зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1518639: Break out the remote server pieces from nsRemoteService and deCOMtaminate. r=jimm
This code is only ever used from c++ so does not need to be an XPCOM component. Broken out a single nsRemoteService that is responsible for choosing the server implementation to use. Differential Revision: https://phabricator.services.mozilla.com/D19067 --HG-- rename : toolkit/components/remote/nsDBusRemoteService.cpp => toolkit/components/remote/nsDBusRemoteServer.cpp rename : toolkit/components/remote/nsDBusRemoteService.h => toolkit/components/remote/nsDBusRemoteServer.h rename : toolkit/components/remote/nsGTKRemoteService.cpp => toolkit/components/remote/nsGTKRemoteServer.cpp rename : toolkit/components/remote/nsGTKRemoteService.h => toolkit/components/remote/nsGTKRemoteServer.h rename : toolkit/components/remote/nsXRemoteService.cpp => toolkit/components/remote/nsXRemoteServer.cpp rename : toolkit/components/remote/nsXRemoteService.h => toolkit/components/remote/nsXRemoteServer.h extra : rebase_source : 631ee45923c64acde92e23c155cbbbbc7a1d9c4d
This commit is contained in:
Родитель
bbb9bd1286
Коммит
5e41c25e13
|
@ -1,14 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Classes = [
|
||||
{
|
||||
'cid': '{c0773e90-5799-4eff-ad03-3ebcd85624ac}',
|
||||
'contract_ids': ['@mozilla.org/toolkit/remote-service;1'],
|
||||
'type': 'nsRemoteService',
|
||||
'headers': ['/toolkit/components/remote/nsRemoteService.h'],
|
||||
},
|
||||
]
|
|
@ -7,31 +7,21 @@
|
|||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Startup and Profile System')
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIRemoteService.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'toolkitremote'
|
||||
|
||||
SOURCES += [
|
||||
'nsXRemoteService.cpp',
|
||||
'nsRemoteService.cpp',
|
||||
]
|
||||
|
||||
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
SOURCES += [
|
||||
'nsGTKRemoteService.cpp',
|
||||
'nsRemoteService.cpp',
|
||||
'nsGTKRemoteServer.cpp',
|
||||
'nsUnixRemoteServer.cpp',
|
||||
'nsXRemoteServer.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_ENABLE_DBUS']:
|
||||
SOURCES += [
|
||||
'nsDBusRemoteService.cpp',
|
||||
'nsDBusRemoteServer.cpp',
|
||||
]
|
||||
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
|
||||
|
||||
XPCOM_MANIFESTS += [
|
||||
'components.conf',
|
||||
]
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsDBusRemoteService.h"
|
||||
#include "nsRemoteService.h"
|
||||
#include "nsDBusRemoteServer.h"
|
||||
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
@ -28,8 +27,6 @@
|
|||
|
||||
#include <dlfcn.h>
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDBusRemoteService, nsIRemoteService)
|
||||
|
||||
const char *introspect_template =
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
|
||||
"1.0//EN\"\n"
|
||||
|
@ -47,7 +44,7 @@ const char *introspect_template =
|
|||
" </interface>\n"
|
||||
"</node>\n";
|
||||
|
||||
DBusHandlerResult nsDBusRemoteService::Introspect(DBusMessage *msg) {
|
||||
DBusHandlerResult nsDBusRemoteServer::Introspect(DBusMessage *msg) {
|
||||
DBusMessage *reply;
|
||||
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
|
@ -66,7 +63,7 @@ DBusHandlerResult nsDBusRemoteService::Introspect(DBusMessage *msg) {
|
|||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
DBusHandlerResult nsDBusRemoteService::OpenURL(DBusMessage *msg) {
|
||||
DBusHandlerResult nsDBusRemoteServer::OpenURL(DBusMessage *msg) {
|
||||
DBusMessage *reply = nullptr;
|
||||
const char *commandLine;
|
||||
int length;
|
||||
|
@ -82,7 +79,7 @@ DBusHandlerResult nsDBusRemoteService::OpenURL(DBusMessage *msg) {
|
|||
if (timestamp == GDK_CURRENT_TIME) {
|
||||
timestamp = guint32(g_get_monotonic_time() / 1000);
|
||||
}
|
||||
nsRemoteService::HandleCommandLine(commandLine, timestamp);
|
||||
HandleCommandLine(commandLine, timestamp);
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
}
|
||||
|
||||
|
@ -92,7 +89,7 @@ DBusHandlerResult nsDBusRemoteService::OpenURL(DBusMessage *msg) {
|
|||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
DBusHandlerResult nsDBusRemoteService::HandleDBusMessage(
|
||||
DBusHandlerResult nsDBusRemoteServer::HandleDBusMessage(
|
||||
DBusConnection *aConnection, DBusMessage *msg) {
|
||||
NS_ASSERTION(mConnection == aConnection, "Wrong D-Bus connection.");
|
||||
|
||||
|
@ -115,19 +112,19 @@ DBusHandlerResult nsDBusRemoteService::HandleDBusMessage(
|
|||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
void nsDBusRemoteService::UnregisterDBusInterface(DBusConnection *aConnection) {
|
||||
void nsDBusRemoteServer::UnregisterDBusInterface(DBusConnection *aConnection) {
|
||||
NS_ASSERTION(mConnection == aConnection, "Wrong D-Bus connection.");
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
static DBusHandlerResult message_handler(DBusConnection *conn, DBusMessage *msg,
|
||||
void *user_data) {
|
||||
auto interface = static_cast<nsDBusRemoteService *>(user_data);
|
||||
auto interface = static_cast<nsDBusRemoteServer *>(user_data);
|
||||
return interface->HandleDBusMessage(conn, msg);
|
||||
}
|
||||
|
||||
static void unregister(DBusConnection *conn, void *user_data) {
|
||||
auto interface = static_cast<nsDBusRemoteService *>(user_data);
|
||||
auto interface = static_cast<nsDBusRemoteServer *>(user_data);
|
||||
interface->UnregisterDBusInterface(conn);
|
||||
}
|
||||
|
||||
|
@ -136,8 +133,8 @@ static DBusObjectPathVTable remoteHandlersTable = {
|
|||
.message_function = message_handler,
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBusRemoteService::Startup(const char *aAppName, const char *aProfileName) {
|
||||
nsresult nsDBusRemoteServer::Startup(const char *aAppName,
|
||||
const char *aProfileName) {
|
||||
if (mConnection && dbus_connection_get_is_connected(mConnection)) {
|
||||
// We're already connected so we don't need to reconnect
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
@ -210,11 +207,13 @@ nsDBusRemoteService::Startup(const char *aAppName, const char *aProfileName) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBusRemoteService::Shutdown() {
|
||||
void nsDBusRemoteServer::Shutdown() {
|
||||
if (!mConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_connection_unregister_object_path(mConnection, mPathName.get());
|
||||
|
||||
// dbus_connection_unref() will be called by RefPtr here.
|
||||
mConnection = nullptr;
|
||||
return NS_OK;
|
||||
}
|
|
@ -5,28 +5,27 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsDBusRemoteService_h__
|
||||
#define __nsDBusRemoteService_h__
|
||||
#ifndef __nsDBusRemoteServer_h__
|
||||
#define __nsDBusRemoteServer_h__
|
||||
|
||||
#include "nsIRemoteService.h"
|
||||
#include "nsRemoteServer.h"
|
||||
#include "nsUnixRemoteServer.h"
|
||||
#include "mozilla/DBusHelpers.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsDBusRemoteService final : public nsIRemoteService {
|
||||
class nsDBusRemoteServer final : public nsRemoteServer,
|
||||
public nsUnixRemoteServer {
|
||||
public:
|
||||
// We will be a static singleton, so don't use the ordinary methods.
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREMOTESERVICE
|
||||
nsDBusRemoteServer() : mConnection(nullptr), mAppName(nullptr) {}
|
||||
~nsDBusRemoteServer() override { Shutdown(); }
|
||||
|
||||
nsDBusRemoteService() : mConnection(nullptr), mAppName(nullptr) {}
|
||||
nsresult Startup(const char *aAppName, const char *aProfileName) override;
|
||||
void Shutdown() override;
|
||||
|
||||
DBusHandlerResult HandleDBusMessage(DBusConnection *aConnection,
|
||||
DBusMessage *msg);
|
||||
void UnregisterDBusInterface(DBusConnection *aConnection);
|
||||
|
||||
private:
|
||||
~nsDBusRemoteService() {}
|
||||
|
||||
DBusHandlerResult OpenURL(DBusMessage *msg);
|
||||
DBusHandlerResult Introspect(DBusMessage *msg);
|
||||
|
||||
|
@ -36,4 +35,4 @@ class nsDBusRemoteService final : public nsIRemoteService {
|
|||
nsCString mPathName;
|
||||
};
|
||||
|
||||
#endif // __nsDBusRemoteService_h__
|
||||
#endif // __nsDBusRemoteServer_h__
|
|
@ -5,7 +5,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsGTKRemoteService.h"
|
||||
#include "nsGTKRemoteServer.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
@ -23,13 +23,13 @@
|
|||
|
||||
#include "nsGTKToolkit.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsGTKRemoteService, nsIRemoteService)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGTKRemoteService::Startup(const char* aAppName, const char* aProfileName) {
|
||||
nsresult nsGTKRemoteServer::Startup(const char* aAppName,
|
||||
const char* aProfileName) {
|
||||
NS_ASSERTION(aAppName, "Don't pass a null appname!");
|
||||
|
||||
if (mServerWindow) return NS_ERROR_ALREADY_INITIALIZED;
|
||||
if (mServerWindow) {
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
XRemoteBaseStartup(aAppName, aProfileName);
|
||||
|
||||
|
@ -40,36 +40,35 @@ nsGTKRemoteService::Startup(const char* aAppName, const char* aProfileName) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGTKRemoteService::Shutdown() {
|
||||
if (!mServerWindow) return NS_ERROR_NOT_INITIALIZED;
|
||||
void nsGTKRemoteServer::Shutdown() {
|
||||
if (!mServerWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(mServerWindow);
|
||||
mServerWindow = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsGTKRemoteService::HandleCommandsFor(GtkWidget* widget) {
|
||||
void nsGTKRemoteServer::HandleCommandsFor(GtkWidget* widget) {
|
||||
g_signal_connect(G_OBJECT(widget), "property_notify_event",
|
||||
G_CALLBACK(HandlePropertyChange), nullptr);
|
||||
G_CALLBACK(HandlePropertyChange), this);
|
||||
|
||||
gtk_widget_add_events(widget, GDK_PROPERTY_CHANGE_MASK);
|
||||
|
||||
Window window = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
|
||||
nsXRemoteService::HandleCommandsFor(window);
|
||||
nsXRemoteServer::HandleCommandsFor(window);
|
||||
}
|
||||
|
||||
gboolean nsGTKRemoteService::HandlePropertyChange(GtkWidget* aWidget,
|
||||
GdkEventProperty* pevent,
|
||||
void* aData) {
|
||||
gboolean nsGTKRemoteServer::HandlePropertyChange(GtkWidget* aWidget,
|
||||
GdkEventProperty* pevent,
|
||||
nsGTKRemoteServer* aThis) {
|
||||
if (pevent->state == GDK_PROPERTY_NEW_VALUE) {
|
||||
Atom changedAtom = gdk_x11_atom_to_xatom(pevent->atom);
|
||||
|
||||
XID window = gdk_x11_window_get_xid(gtk_widget_get_window(aWidget));
|
||||
return HandleNewProperty(window,
|
||||
GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
|
||||
pevent->time, changedAtom);
|
||||
return aThis->HandleNewProperty(
|
||||
window, GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), pevent->time,
|
||||
changedAtom);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
|
@ -5,31 +5,30 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsGTKRemoteService_h__
|
||||
#define __nsGTKRemoteService_h__
|
||||
#ifndef __nsGTKRemoteServer_h__
|
||||
#define __nsGTKRemoteServer_h__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "nsIRemoteService.h"
|
||||
#include "nsXRemoteService.h"
|
||||
#include "nsRemoteServer.h"
|
||||
#include "nsXRemoteServer.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsGTKRemoteService final : public nsIRemoteService,
|
||||
public nsXRemoteService {
|
||||
class nsGTKRemoteServer final : public nsXRemoteServer {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREMOTESERVICE
|
||||
nsGTKRemoteServer() : mServerWindow(nullptr) {}
|
||||
~nsGTKRemoteServer() override { Shutdown(); }
|
||||
|
||||
nsGTKRemoteService() : mServerWindow(nullptr) {}
|
||||
nsresult Startup(const char* aAppName, const char* aProfileName) override;
|
||||
void Shutdown() override;
|
||||
|
||||
static gboolean HandlePropertyChange(GtkWidget* widget,
|
||||
GdkEventProperty* event, void* aData);
|
||||
GdkEventProperty* event,
|
||||
nsGTKRemoteServer* aData);
|
||||
|
||||
private:
|
||||
~nsGTKRemoteService() {}
|
||||
|
||||
void HandleCommandsFor(GtkWidget* aWidget);
|
||||
|
||||
GtkWidget* mServerWindow;
|
|
@ -1,38 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface mozIDOMWindow;
|
||||
|
||||
/**
|
||||
* Start and stop the remote service (xremote/phremote), and register
|
||||
* windows with the service for backwards compatibility with old xremote
|
||||
* clients.
|
||||
*
|
||||
* @status FLUID This interface is not frozen and is not intended for embedders
|
||||
* who want a frozen API. If you are an embedder and need this
|
||||
* functionality, contact Benjamin Smedberg about the possibility
|
||||
* of freezing the functionality you need.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(bf23f1c3-7012-42dd-b0bb-a84060ccc52e)]
|
||||
interface nsIRemoteService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Start the remote service. This should not be done until app startup
|
||||
* appears to have been successful.
|
||||
*
|
||||
* @param appName (Required) Sets a window property identifying the
|
||||
* application.
|
||||
* @param profileName (May be null) Sets a window property identifying the
|
||||
* profile name.
|
||||
*/
|
||||
void startup(in string appName, in string profileName);
|
||||
|
||||
/**
|
||||
* Stop the remote service from accepting additional requests.
|
||||
*/
|
||||
void shutdown();
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsRemoteServer_h__
|
||||
#define __nsRemoteServer_h__
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
class nsRemoteServer {
|
||||
public:
|
||||
virtual ~nsRemoteServer() = default;
|
||||
|
||||
virtual nsresult Startup(const char* aAppName, const char* aProfileName) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
};
|
||||
|
||||
#endif // __nsRemoteServer_h__
|
|
@ -5,48 +5,46 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsGTKRemoteService.h"
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
# include "nsDBusRemoteService.h"
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
# include "nsGTKRemoteServer.h"
|
||||
# ifdef MOZ_ENABLE_DBUS
|
||||
# include "nsDBusRemoteServer.h"
|
||||
# endif
|
||||
#endif
|
||||
#include "nsRemoteService.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIAppShellService.h"
|
||||
#include "nsAppShellCID.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsGTKToolkit.h"
|
||||
#include "nsICommandLineRunner.h"
|
||||
#include "nsCommandLine.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsRemoteService, nsIRemoteService, nsIObserver)
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRemoteService::Startup(const char* aAppName, const char* aProfileName) {
|
||||
NS_IMPL_ISUPPORTS(nsRemoteService, nsIObserver)
|
||||
|
||||
void nsRemoteService::Startup(const char* aAppName, const char* aProfileName) {
|
||||
if (mRemoteServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
bool useX11Remote = GDK_IS_X11_DISPLAY(gdk_display_get_default());
|
||||
|
||||
#if defined(MOZ_ENABLE_DBUS)
|
||||
# if defined(MOZ_ENABLE_DBUS)
|
||||
if (!useX11Remote) {
|
||||
nsresult rv;
|
||||
mDBusRemoteService = new nsDBusRemoteService();
|
||||
rv = mDBusRemoteService->Startup(aAppName, aProfileName);
|
||||
if (NS_FAILED(rv)) {
|
||||
mDBusRemoteService = nullptr;
|
||||
}
|
||||
mRemoteServer = MakeUnique<nsDBusRemoteServer>();
|
||||
}
|
||||
# endif
|
||||
if (useX11Remote) {
|
||||
mRemoteServer = MakeUnique<nsGTKRemoteServer>();
|
||||
}
|
||||
#endif
|
||||
if (useX11Remote) {
|
||||
mGtkRemoteService = new nsGTKRemoteService();
|
||||
mGtkRemoteService->Startup(aAppName, aProfileName);
|
||||
}
|
||||
|
||||
if (!mDBusRemoteService && !mGtkRemoteService) return NS_ERROR_FAILURE;
|
||||
nsresult rv = mRemoteServer->Startup(aAppName, aProfileName);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
mRemoteServer = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs(
|
||||
do_GetService("@mozilla.org/observer-service;1"));
|
||||
|
@ -54,24 +52,9 @@ nsRemoteService::Startup(const char* aAppName, const char* aProfileName) {
|
|||
obs->AddObserver(this, "xpcom-shutdown", false);
|
||||
obs->AddObserver(this, "quit-application", false);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRemoteService::Shutdown() {
|
||||
#if defined(MOZ_ENABLE_DBUS)
|
||||
if (mDBusRemoteService) {
|
||||
mDBusRemoteService->Shutdown();
|
||||
mDBusRemoteService = nullptr;
|
||||
}
|
||||
#endif
|
||||
if (mGtkRemoteService) {
|
||||
mGtkRemoteService->Shutdown();
|
||||
mGtkRemoteService = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
void nsRemoteService::Shutdown() { mRemoteServer = nullptr; }
|
||||
|
||||
nsRemoteService::~nsRemoteService() { Shutdown(); }
|
||||
|
||||
|
@ -83,101 +66,3 @@ nsRemoteService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
Shutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Set desktop startup ID to the passed ID, if there is one, so that any created
|
||||
// windows get created with the right window manager metadata, and any windows
|
||||
// that get new tabs and are activated also get the right WM metadata.
|
||||
// The timestamp will be used if there is no desktop startup ID, or if we're
|
||||
// raising an existing window rather than showing a new window for the first
|
||||
// time.
|
||||
void nsRemoteService::SetDesktopStartupIDOrTimestamp(
|
||||
const nsACString& aDesktopStartupID, uint32_t aTimestamp) {
|
||||
nsGTKToolkit* toolkit = nsGTKToolkit::GetToolkit();
|
||||
if (!toolkit) return;
|
||||
|
||||
if (!aDesktopStartupID.IsEmpty()) {
|
||||
toolkit->SetDesktopStartupID(aDesktopStartupID);
|
||||
}
|
||||
|
||||
toolkit->SetFocusTimestamp(aTimestamp);
|
||||
}
|
||||
|
||||
static bool FindExtensionParameterInCommand(const char* aParameterName,
|
||||
const nsACString& aCommand,
|
||||
char aSeparator,
|
||||
nsACString* aValue) {
|
||||
nsAutoCString searchFor;
|
||||
searchFor.Append(aSeparator);
|
||||
searchFor.Append(aParameterName);
|
||||
searchFor.Append('=');
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
aCommand.BeginReading(start);
|
||||
aCommand.EndReading(end);
|
||||
if (!FindInReadable(searchFor, start, end)) return false;
|
||||
|
||||
nsACString::const_iterator charStart, charEnd;
|
||||
charStart = end;
|
||||
aCommand.EndReading(charEnd);
|
||||
nsACString::const_iterator idStart = charStart, idEnd;
|
||||
if (FindCharInReadable(aSeparator, charStart, charEnd)) {
|
||||
idEnd = charStart;
|
||||
} else {
|
||||
idEnd = charEnd;
|
||||
}
|
||||
*aValue = nsDependentCSubstring(idStart, idEnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* nsRemoteService::HandleCommandLine(const char* aBuffer,
|
||||
uint32_t aTimestamp) {
|
||||
nsCOMPtr<nsICommandLineRunner> cmdline(new nsCommandLine());
|
||||
|
||||
// the commandline property is constructed as an array of int32_t
|
||||
// followed by a series of null-terminated strings:
|
||||
//
|
||||
// [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
|
||||
// (offset is from the beginning of the buffer)
|
||||
|
||||
int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast<const int32_t*>(aBuffer));
|
||||
const char* wd = aBuffer + ((argc + 1) * sizeof(int32_t));
|
||||
|
||||
nsCOMPtr<nsIFile> lf;
|
||||
nsresult rv =
|
||||
NS_NewNativeLocalFile(nsDependentCString(wd), true, getter_AddRefs(lf));
|
||||
if (NS_FAILED(rv)) return "509 internal error";
|
||||
|
||||
nsAutoCString desktopStartupID;
|
||||
|
||||
const char** argv = (const char**)malloc(sizeof(char*) * argc);
|
||||
if (!argv) return "509 internal error";
|
||||
|
||||
const int32_t* offset = reinterpret_cast<const int32_t*>(aBuffer) + 1;
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
argv[i] = aBuffer + TO_LITTLE_ENDIAN32(offset[i]);
|
||||
|
||||
if (i == 0) {
|
||||
nsDependentCString cmd(argv[0]);
|
||||
FindExtensionParameterInCommand("DESKTOP_STARTUP_ID", cmd, ' ',
|
||||
&desktopStartupID);
|
||||
}
|
||||
}
|
||||
|
||||
rv = cmdline->Init(argc, argv, lf, nsICommandLine::STATE_REMOTE_AUTO);
|
||||
|
||||
free(argv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return "509 internal error";
|
||||
}
|
||||
|
||||
SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp);
|
||||
|
||||
rv = cmdline->Run();
|
||||
|
||||
if (NS_ERROR_ABORT == rv) return "500 command not parseable";
|
||||
|
||||
if (NS_FAILED(rv)) return "509 internal error";
|
||||
|
||||
return "200 executed command";
|
||||
}
|
||||
|
|
|
@ -8,31 +8,27 @@
|
|||
#ifndef __nsRemoteService_h__
|
||||
#define __nsRemoteService_h__
|
||||
|
||||
#include "nsIRemoteService.h"
|
||||
#include "nsRemoteServer.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
class nsRemoteService final : public nsIRemoteService, public nsIObserver {
|
||||
class nsRemoteService final : public nsIObserver {
|
||||
public:
|
||||
// We will be a static singleton, so don't use the ordinary methods.
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREMOTESERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static const char* HandleCommandLine(const char* aBuffer,
|
||||
uint32_t aTimestamp);
|
||||
nsRemoteService() = default;
|
||||
|
||||
nsCOMPtr<nsIRemoteService> mDBusRemoteService;
|
||||
nsCOMPtr<nsIRemoteService> mGtkRemoteService;
|
||||
|
||||
nsRemoteService() {}
|
||||
void Startup(const char* aAppName, const char* aProfileName);
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
~nsRemoteService();
|
||||
|
||||
static void SetDesktopStartupIDOrTimestamp(
|
||||
const nsACString& aDesktopStartupID, uint32_t aTimestamp);
|
||||
mozilla::UniquePtr<nsRemoteServer> mRemoteServer;
|
||||
};
|
||||
|
||||
#endif // __nsRemoteService_h__
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsUnixRemoteServer.h"
|
||||
#include "nsGTKToolkit.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsICommandLineRunner.h"
|
||||
#include "nsCommandLine.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
// Set desktop startup ID to the passed ID, if there is one, so that any created
|
||||
// windows get created with the right window manager metadata, and any windows
|
||||
// that get new tabs and are activated also get the right WM metadata.
|
||||
// The timestamp will be used if there is no desktop startup ID, or if we're
|
||||
// raising an existing window rather than showing a new window for the first
|
||||
// time.
|
||||
void nsUnixRemoteServer::SetDesktopStartupIDOrTimestamp(
|
||||
const nsACString& aDesktopStartupID, uint32_t aTimestamp) {
|
||||
nsGTKToolkit* toolkit = nsGTKToolkit::GetToolkit();
|
||||
if (!toolkit) return;
|
||||
|
||||
if (!aDesktopStartupID.IsEmpty()) {
|
||||
toolkit->SetDesktopStartupID(aDesktopStartupID);
|
||||
}
|
||||
|
||||
toolkit->SetFocusTimestamp(aTimestamp);
|
||||
}
|
||||
|
||||
static bool FindExtensionParameterInCommand(const char* aParameterName,
|
||||
const nsACString& aCommand,
|
||||
char aSeparator,
|
||||
nsACString* aValue) {
|
||||
nsAutoCString searchFor;
|
||||
searchFor.Append(aSeparator);
|
||||
searchFor.Append(aParameterName);
|
||||
searchFor.Append('=');
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
aCommand.BeginReading(start);
|
||||
aCommand.EndReading(end);
|
||||
if (!FindInReadable(searchFor, start, end)) return false;
|
||||
|
||||
nsACString::const_iterator charStart, charEnd;
|
||||
charStart = end;
|
||||
aCommand.EndReading(charEnd);
|
||||
nsACString::const_iterator idStart = charStart, idEnd;
|
||||
if (FindCharInReadable(aSeparator, charStart, charEnd)) {
|
||||
idEnd = charStart;
|
||||
} else {
|
||||
idEnd = charEnd;
|
||||
}
|
||||
*aValue = nsDependentCSubstring(idStart, idEnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* nsUnixRemoteServer::HandleCommandLine(const char* aBuffer,
|
||||
uint32_t aTimestamp) {
|
||||
nsCOMPtr<nsICommandLineRunner> cmdline(new nsCommandLine());
|
||||
|
||||
// the commandline property is constructed as an array of int32_t
|
||||
// followed by a series of null-terminated strings:
|
||||
//
|
||||
// [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
|
||||
// (offset is from the beginning of the buffer)
|
||||
|
||||
int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast<const int32_t*>(aBuffer));
|
||||
const char* wd = aBuffer + ((argc + 1) * sizeof(int32_t));
|
||||
|
||||
nsCOMPtr<nsIFile> lf;
|
||||
nsresult rv =
|
||||
NS_NewNativeLocalFile(nsDependentCString(wd), true, getter_AddRefs(lf));
|
||||
if (NS_FAILED(rv)) return "509 internal error";
|
||||
|
||||
nsAutoCString desktopStartupID;
|
||||
|
||||
const char** argv = (const char**)malloc(sizeof(char*) * argc);
|
||||
if (!argv) return "509 internal error";
|
||||
|
||||
const int32_t* offset = reinterpret_cast<const int32_t*>(aBuffer) + 1;
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
argv[i] = aBuffer + TO_LITTLE_ENDIAN32(offset[i]);
|
||||
|
||||
if (i == 0) {
|
||||
nsDependentCString cmd(argv[0]);
|
||||
FindExtensionParameterInCommand("DESKTOP_STARTUP_ID", cmd, ' ',
|
||||
&desktopStartupID);
|
||||
}
|
||||
}
|
||||
|
||||
rv = cmdline->Init(argc, argv, lf, nsICommandLine::STATE_REMOTE_AUTO);
|
||||
|
||||
free(argv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return "509 internal error";
|
||||
}
|
||||
|
||||
SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp);
|
||||
|
||||
rv = cmdline->Run();
|
||||
|
||||
if (NS_ERROR_ABORT == rv) return "500 command not parseable";
|
||||
|
||||
if (NS_FAILED(rv)) return "509 internal error";
|
||||
|
||||
return "200 executed command";
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsUnixRemoteServer_h__
|
||||
#define __nsUnixRemoteServer_h__
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
# define TO_LITTLE_ENDIAN32(x) \
|
||||
((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | \
|
||||
(((x)&0x0000ff00) << 8) | (((x)&0x000000ff) << 24))
|
||||
#else
|
||||
# define TO_LITTLE_ENDIAN32(x) (x)
|
||||
#endif
|
||||
|
||||
class nsUnixRemoteServer {
|
||||
protected:
|
||||
void SetDesktopStartupIDOrTimestamp(const nsACString& aDesktopStartupID,
|
||||
uint32_t aTimestamp);
|
||||
const char* HandleCommandLine(const char* aBuffer, uint32_t aTimestamp);
|
||||
};
|
||||
|
||||
#endif // __nsGTKRemoteService_h__
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "nsXRemoteService.h"
|
||||
#include "nsRemoteService.h"
|
||||
#include "nsXRemoteServer.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
@ -54,18 +53,18 @@ static const char *XAtomNames[] = {
|
|||
MOZILLA_COMMANDLINE_PROP};
|
||||
static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)];
|
||||
|
||||
Atom nsXRemoteService::sMozVersionAtom;
|
||||
Atom nsXRemoteService::sMozLockAtom;
|
||||
Atom nsXRemoteService::sMozResponseAtom;
|
||||
Atom nsXRemoteService::sMozUserAtom;
|
||||
Atom nsXRemoteService::sMozProfileAtom;
|
||||
Atom nsXRemoteService::sMozProgramAtom;
|
||||
Atom nsXRemoteService::sMozCommandLineAtom;
|
||||
Atom nsXRemoteServer::sMozVersionAtom;
|
||||
Atom nsXRemoteServer::sMozLockAtom;
|
||||
Atom nsXRemoteServer::sMozResponseAtom;
|
||||
Atom nsXRemoteServer::sMozUserAtom;
|
||||
Atom nsXRemoteServer::sMozProfileAtom;
|
||||
Atom nsXRemoteServer::sMozProgramAtom;
|
||||
Atom nsXRemoteServer::sMozCommandLineAtom;
|
||||
|
||||
nsXRemoteService::nsXRemoteService() = default;
|
||||
nsXRemoteServer::nsXRemoteServer() = default;
|
||||
|
||||
void nsXRemoteService::XRemoteBaseStartup(const char *aAppName,
|
||||
const char *aProfileName) {
|
||||
void nsXRemoteServer::XRemoteBaseStartup(const char *aAppName,
|
||||
const char *aProfileName) {
|
||||
EnsureAtoms();
|
||||
|
||||
mAppName = aAppName;
|
||||
|
@ -74,7 +73,7 @@ void nsXRemoteService::XRemoteBaseStartup(const char *aAppName,
|
|||
mProfileName = aProfileName;
|
||||
}
|
||||
|
||||
void nsXRemoteService::HandleCommandsFor(Window aWindowId) {
|
||||
void nsXRemoteServer::HandleCommandsFor(Window aWindowId) {
|
||||
// set our version
|
||||
XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozVersionAtom,
|
||||
XA_STRING, 8, PropModeReplace, kRemoteVersion,
|
||||
|
@ -101,8 +100,8 @@ void nsXRemoteService::HandleCommandsFor(Window aWindowId) {
|
|||
}
|
||||
}
|
||||
|
||||
bool nsXRemoteService::HandleNewProperty(XID aWindowId, Display *aDisplay,
|
||||
Time aEventTime, Atom aChangedAtom) {
|
||||
bool nsXRemoteServer::HandleNewProperty(XID aWindowId, Display *aDisplay,
|
||||
Time aEventTime, Atom aChangedAtom) {
|
||||
if (aChangedAtom == sMozCommandLineAtom) {
|
||||
// We got a new command atom.
|
||||
int result;
|
||||
|
@ -132,7 +131,7 @@ bool nsXRemoteService::HandleNewProperty(XID aWindowId, Display *aDisplay,
|
|||
return false;
|
||||
|
||||
// cool, we got the property data.
|
||||
const char *response = nsRemoteService::HandleCommandLine(data, aEventTime);
|
||||
const char *response = HandleCommandLine(data, aEventTime);
|
||||
|
||||
// put the property onto the window as the response
|
||||
XChangeProperty(aDisplay, aWindowId, sMozResponseAtom, XA_STRING, 8,
|
||||
|
@ -155,7 +154,7 @@ bool nsXRemoteService::HandleNewProperty(XID aWindowId, Display *aDisplay,
|
|||
return false;
|
||||
}
|
||||
|
||||
void nsXRemoteService::EnsureAtoms(void) {
|
||||
void nsXRemoteServer::EnsureAtoms(void) {
|
||||
if (sMozVersionAtom) return;
|
||||
|
||||
XInternAtoms(mozilla::DefaultXDisplay(), const_cast<char **>(XAtomNames),
|
|
@ -5,32 +5,24 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef NSXREMOTESERVICE_H
|
||||
#define NSXREMOTESERVICE_H
|
||||
#ifndef NSXREMOTESERVER_H
|
||||
#define NSXREMOTESERVER_H
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsRemoteServer.h"
|
||||
#include "nsUnixRemoteServer.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/X.h>
|
||||
|
||||
class nsIDOMWindow;
|
||||
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
# define TO_LITTLE_ENDIAN32(x) \
|
||||
((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | \
|
||||
(((x)&0x0000ff00) << 8) | (((x)&0x000000ff) << 24))
|
||||
#else
|
||||
# define TO_LITTLE_ENDIAN32(x) (x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
Base class for GTK/Qt remote service
|
||||
*/
|
||||
class nsXRemoteService {
|
||||
class nsXRemoteServer : public nsRemoteServer, public nsUnixRemoteServer {
|
||||
protected:
|
||||
nsXRemoteService();
|
||||
static bool HandleNewProperty(Window aWindowId, Display* aDisplay,
|
||||
Time aEventTime, Atom aChangedAtom);
|
||||
nsXRemoteServer();
|
||||
bool HandleNewProperty(Window aWindowId, Display* aDisplay, Time aEventTime,
|
||||
Atom aChangedAtom);
|
||||
void XRemoteBaseStartup(const char* aAppName, const char* aProfileName);
|
||||
void HandleCommandsFor(Window aWindowId);
|
||||
|
||||
|
@ -49,4 +41,4 @@ class nsXRemoteService {
|
|||
static Atom sMozCommandLineAtom;
|
||||
};
|
||||
|
||||
#endif // NSXREMOTESERVICE_H
|
||||
#endif // NSXREMOTESERVER_H
|
|
@ -91,6 +91,10 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
|||
UNIFIED_SOURCES += [
|
||||
'nsNativeAppSupportUnix.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../components/remote',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'nsNativeAppSupportDefault.cpp',
|
||||
|
|
|
@ -189,7 +189,7 @@
|
|||
// for X remote support
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
# include "XRemoteClient.h"
|
||||
# include "nsIRemoteService.h"
|
||||
# include "nsRemoteService.h"
|
||||
# include "nsProfileLock.h"
|
||||
# include "SpecialSystemDirectory.h"
|
||||
# include <sched.h>
|
||||
|
@ -2925,7 +2925,7 @@ class XREMain {
|
|||
nsCOMPtr<nsIFile> mProfLD;
|
||||
nsCOMPtr<nsIProfileLock> mProfileLock;
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
nsCOMPtr<nsIRemoteService> mRemoteService;
|
||||
RefPtr<nsRemoteService> mRemoteService;
|
||||
nsProfileLock mRemoteLock;
|
||||
nsCOMPtr<nsIFile> mRemoteLockDir;
|
||||
#endif
|
||||
|
@ -4628,10 +4628,12 @@ nsresult XREMain::XRE_mainRun() {
|
|||
#if defined(MOZ_WIDGET_GTK)
|
||||
// if we have X remote support, start listening for requests on the
|
||||
// proxy window.
|
||||
if (!mDisableRemote)
|
||||
mRemoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
|
||||
if (mRemoteService)
|
||||
if (!mDisableRemote) {
|
||||
mRemoteService = new nsRemoteService();
|
||||
}
|
||||
if (mRemoteService) {
|
||||
mRemoteService->Startup(mAppData->remotingName, mProfileName.get());
|
||||
}
|
||||
if (mRemoteLockDir) {
|
||||
mRemoteLock.Unlock();
|
||||
mRemoteLock.Cleanup();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <dbus/dbus.h>
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче