diff --git a/mozilla/Makefile.in b/mozilla/Makefile.in index ddac0df2f27..ba917cd1bfd 100644 --- a/mozilla/Makefile.in +++ b/mozilla/Makefile.in @@ -201,7 +201,6 @@ tier_9_dirs += \ embedding \ editor \ xpfe/appshell \ - xpfe/components/xremote/public \ $(NULL) ifdef MOZ_OJI @@ -243,6 +242,7 @@ endif tier_50_dirs += \ db \ xpfe \ + toolkit/components \ $(NULL) ifndef MOZ_XUL_APP diff --git a/mozilla/allmakefiles.sh b/mozilla/allmakefiles.sh index c15ebae9c4f..ab90819b424 100755 --- a/mozilla/allmakefiles.sh +++ b/mozilla/allmakefiles.sh @@ -640,6 +640,9 @@ xpinstall/wizard/windows/GetShortPathName/Makefile " MAKEFILES_xpfe=" +widget/src/xremoteclient/Makefile +toolkit/components/Makefile +toolkit/components/remote/Makefile xpfe/Makefile xpfe/browser/Makefile xpfe/browser/public/Makefile diff --git a/mozilla/browser/app/mozilla.in b/mozilla/browser/app/mozilla.in index c4316a0d37e..aff036f2a56 100755 --- a/mozilla/browser/app/mozilla.in +++ b/mozilla/browser/app/mozilla.in @@ -36,7 +36,7 @@ # # ***** END LICENSE BLOCK ***** -## $Id: mozilla.in,v 1.11 2005-02-01 17:36:47 gerv%gerv.net Exp $ +## $Id: mozilla.in,v 1.12 2005-04-04 19:08:49 bsmedberg%covad.net Exp $ ## ## Usage: ## @@ -141,76 +141,10 @@ moreargs="" debugging=0 MOZILLA_BIN="${progbase}-bin" -# The following is to check for a currently running instance. -# This is taken almost verbatim from the Mozilla RPM package's launch script. -MOZ_CLIENT_PROGRAM="$dist_bin/mozilla-xremote-client" -check_running() { - "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" 'ping()' 2>/dev/null >/dev/null - RETURN_VAL=$? - if [ $RETURN_VAL -eq 0 ]; then - echo 1 - return 1 - else - echo 0 - return 0 - fi -} - if [ "$OSTYPE" = "beos" ]; then mimeset -F "$MOZILLA_BIN" fi -ALREADY_RUNNING=`check_running` - -################################################################ Parse Arguments -# If there's a command line argument but it doesn't begin with a - -# it's probably a url. Try to send it to a running instance. -_USE_EXIST=0 -_optOne="$1" -case "${_optOne}" in - -*) - ;; - *) - _USE_EXIST=1 - ;; -esac - -_optLast= -for i in "$@"; do - _optLast="${i}" -done #last arg - -if [ `expr "${_optLast}" : '.*:/.*'` -eq 0 -a \( -f "${_optLast}" -o -d "${_optLast}" \) ]; then - # Last argument seems to be a local file/directory - # Check, if it is absolutely specified (ie. /home/foo/file vs. ./file) - # If it is just "relatively" (./file) specified, make it absolutely - [ `expr "${_optLast}" : '/.*'` -eq 0 ] && _optLast="file://`pwd`/${_optLast}" -fi -################################################################ Parse Arguments - -########################################################################### Main -if [ $ALREADY_RUNNING -eq 1 ]; then - # There's an instance already running. Use it. - # Any command line args passed in? - if [ $# -gt 0 ]; then - # There were "some" command line args. - if [ ${_USE_EXIST} -eq 1 ]; then - # We should use an existing instance, as _USE_EXIST=$_USE_EXIST=-1 - _remote_cmd="openURL(${_optLast})" - "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" "${_remote_cmd}" - unset _remote_cmd - exit $? - fi - else - # No command line args. Open new window/tab - #exec "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" "xfeDoCommand(openBrowser)" - "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" "xfeDoCommand(openBrowser)" - exit $? - fi -fi -# Default action - no running instance or _USE_EXIST (${_USE_EXIST}) ! -eq 1 -########################################################################### Main - while [ $# -gt 0 ] do case "$1" in diff --git a/mozilla/browser/components/nsBrowserContentHandler.js b/mozilla/browser/components/nsBrowserContentHandler.js index e77d0ece1c3..a26fa9cbe1c 100644 --- a/mozilla/browser/components/nsBrowserContentHandler.js +++ b/mozilla/browser/components/nsBrowserContentHandler.js @@ -61,6 +61,7 @@ const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo; const NS_BINDING_ABORTED = 0x80020006; const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001; +const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT; function needHomepageOverride(prefb) { var savedmstone; @@ -94,7 +95,7 @@ function openWindow(parent, url, target, features, args) .createInstance(nsISupportsString); argstring.data = args; } - wwatch.openWindow(parent, url, target, features, argstring); + return wwatch.openWindow(parent, url, target, features, argstring); } function getMostRecentWindow(aType) { @@ -168,6 +169,63 @@ var nsBrowserContentHandler = { cmdLine.preventDefault = true; } + try { + var remoteCommand = cmdLine.handleFlagWithParam("remote", true); + } + catch (e) { + throw NS_ERROR_ABORT; + } + + if (remoteCommand != null) { + try { + var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand); + var remoteVerb = a[1].toLowerCase(); + var remoteParams = a[2].split(","); + + switch (remoteVerb) { + case "openurl": + case "openfile": + // openURL() + // openURL(,new-window) + // openURL(,new-tab) + + var uri = cmdLine.resolveURI(remoteParams[0]); + + var location = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW; + if (/new-window/.test(remoteParams[1])) + location = nsIBrowserDOMWindow.OPEN_NEWWINDOW; + else if (/new-tab/.test(remoteParams[1])) + location = nsIBrowserDOMWindow.OPEN_NEWTAB; + + handURIToExistingBrowser(uri, location); + break; + + case "xfedocommand": + // xfeDoCommand(openBrowser) + if (remoteParams[0].toLowerCase() != "openbrowser") + throw NS_ERROR_ABORT; + + openWindow(null, this.chromeURL, "_blank", + "chrome,dialog=no,all" + this.getFeatures(cmdLine), + this.defaultArgs); + break; + + default: + // Somebody sent us a remote command we don't know how to process: + // just abort. + throw NS_ERROR_ABORT; + } + + cmdLine.preventDefault = true; + } + catch (e) { + // If we had a -remote flag but failed to process it, throw + // NS_ERROR_ABORT so that the xremote code knows to return a failure + // back to the handling code. + throw NS_ERROR_ABORT; + } + } + try { var uriparam; while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) { @@ -288,6 +346,28 @@ const bch_contractID = "@mozilla.org/browser/clh;1"; const bch_CID = Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}"); const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type="; +function handURIToExistingBrowser(uri, location) +{ + var navWin = getMostRecentWindow("navigator:browser"); + if (!navWin) { + // if we couldn't load it in an existing window, open a new one + openWindow(null, nsBrowserContentHandler.chromeURL, "_blank", + "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine), + uri.spec); + return; + } + + var navNav = navWin.QueryInterface(nsIInterfaceRequestor) + .getInterface(nsIWebNavigation); + var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem; + var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor) + .getInterface(nsIDOMWindow); + var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow; + bwin.openURI(uri, null, location, + nsIBrowserDOMWindow.OPEN_EXTERNAL); +} + + var nsDefaultCommandLineHandler = { /* nsISupports */ QueryInterface : function dch_QI(iid) { @@ -335,28 +415,15 @@ var nsDefaultCommandLineHandler = { } if (urilist.length) { - existingWindow: if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH && urilist.length == 1) { // Try to find an existing window and load our URI into the // current tab, new tab, or new window as prefs determine. - try { - var navWin = getMostRecentWindow("navigator:browser"); - if (!navWin) - break existingWindow; - var navNav = navWin.QueryInterface(nsIInterfaceRequestor) - .getInterface(nsIWebNavigation); - var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem; - var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor) - .getInterface(nsIDOMWindow); - var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow; - bwin.openURI(urilist[0], null, nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, - nsIBrowserDOMWindow.OPEN_EXTERNAL); + handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW); return; } catch (e) { - dump("Failed to hand off external URL to extant window: " + e + "\n"); } } diff --git a/mozilla/mail/app/mozilla.in b/mozilla/mail/app/mozilla.in index a94b36d0f9f..164ced3d93d 100644 --- a/mozilla/mail/app/mozilla.in +++ b/mozilla/mail/app/mozilla.in @@ -36,7 +36,7 @@ # # ***** END LICENSE BLOCK ***** -## $Id: mozilla.in,v 1.4 2005-02-01 18:04:15 gerv%gerv.net Exp $ +## $Id: mozilla.in,v 1.5 2005-04-04 19:08:49 bsmedberg%covad.net Exp $ ## ## Usage: ## @@ -140,88 +140,10 @@ moreargs="" debugging=0 MOZILLA_BIN="${progbase}-bin" -# The following is to check for a currently running instance. -# This is taken almost verbatim from the Mozilla RPM package's launch script. -MOZ_CLIENT_PROGRAM="$dist_bin/mozilla-xremote-client" -check_running() { - "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" 'ping()' 2>/dev/null >/dev/null - RETURN_VAL=$? - if [ $RETURN_VAL -eq 0 ]; then - echo 1 - return 1 - else - echo 0 - return 0 - fi -} - if [ "$OSTYPE" = "beos" ]; then mimeset -F "$MOZILLA_BIN" fi -ALREADY_RUNNING=`check_running` - -################################################################ Parse Arguments -# If there's a command line argument but it doesn't begin with a - -# it's probably a url. Try to send it to a running instance. -_USE_EXIST=0 -_NEW_WINDOW= -_optOne="$1" -case "${_optOne}" in - -*) - ;; - *) - _USE_EXIST=1 - ;; -esac - -_optOthers= -_optLast= -for i in "$@"; do - _optLast="${i}" -done #last arg - -for i in "$@"; do - [ $i = ${_optLast} ] && break - _optOthers="${_optOthers} ${i}" -done #others arg - -#???: needs check if othersopt begin with -* ? -if [ `expr "${_optLast}" : '.*:/.*'` -eq 0 -a \( -f "${_optLast}" -o -d "${_optLast}" \) ]; then - # Last argument seems to be a local file/directory - # Check, if it is absolutely specified (ie. /home/foo/file vs. ./file) - # If it is just "relatively" (./file) specified, make it absolutely - [ `expr "${_optLast}" : '/.*'` -eq 0 ] && _optLast="file://`pwd`/${_optLast}" -elif [ `expr "${_optLast}" : '.*:/.*'` -gt 0 -o -n "${_optOthers}" ]; then #???? like before... - _NEW_WINDOW=1 -fi -################################################################ Parse Arguments - -########################################################################### Main -if [ $ALREADY_RUNNING -eq 1 ]; then - # There's an instance already running. Use it. - # Any command line args passed in? - if [ $# -gt 0 ]; then - # There were "some" command line args. - if [ ${_USE_EXIST} -eq 1 ]; then - # We should use an existing instance, as _USE_EXIST=$_USE_EXIST=-1 - _open_type="window" - #_open_type="tab" - _remote_cmd="openURL(${_optLast} , new-${_open_type})" - "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" "${_remote_cmd}" - unset _remote_cmd _open_type - exit $? - fi - else - # No command line args. Open new window/tab - #exec "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" "xfeDoCommand(openBrowser)" - "${run_moz}" "$MOZ_CLIENT_PROGRAM" -a "${progbase}" "xfeDoCommand(openInbox)" - exit $? - fi -fi -# Default action - no running instance or _USE_EXIST (${_USE_EXIST}) ! -eq 1 -########################################################################### Main - while [ $# -gt 0 ] do case "$1" in diff --git a/mozilla/mail/components/nsMailDefaultHandler.js b/mozilla/mail/components/nsMailDefaultHandler.js index 15bce4404f4..257b294f3fd 100644 --- a/mozilla/mail/components/nsMailDefaultHandler.js +++ b/mozilla/mail/components/nsMailDefaultHandler.js @@ -45,6 +45,43 @@ const nsISupportsString = Components.interfaces.nsISupportsString; const nsIWindowMediator = Components.interfaces.nsIWindowMediator; const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher; +const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT; + +function mayOpenURI(uri) +{ + var ext = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"] + .getService(Components.interfaces.nsIExternalProtocolService); + + return ext.isExposedProtocol(uri.scheme); +} + +function openURI(uri) +{ + if (!mayOpenURI()) + throw Components.results.NS_ERROR_FAILURE; + + var io = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + var channel = io.newChannelFromURI(uri); + var loader = Components.classes["@mozilla.org/uriloader;1"] + .getService(Components.interfaces.nsIURILoader); + var listener = { + onStartURIOpen: function(uri) { return false; }, + doContent: function(ctype, preferred, request, handler) { return false; }, + isPreferred: function(ctype, desired) { return false; }, + canHandleContent: function(ctype, preferred, desired) { return false; }, + loadCookie: null, + parentContentListener: null, + getInterface: function(iid) { + if (iid.equals(Components.interfaces.nsIURIContentListener)) + return this; + + throw Components.results.NS_ERROR_NO_INTERFACE; + } + }; + loader.openURI(channel, true, listener); +} + var nsMailDefaultHandler = { /* nsISupports */ @@ -62,6 +99,84 @@ var nsMailDefaultHandler = { handle : function mdh_handle(cmdLine) { var uri; + try { + var remoteCommand = cmdLine.handleFlagWithParam("remote", true); + } + catch (e) { + throw NS_ERROR_ABORT; + } + + if (remoteCommand != null) { + try { + var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand); + var remoteVerb = a[1].toLowerCase(); + var remoteParams = a[2].split(","); + + switch (remoteVerb) { + case "openurl": + var xuri = cmdLine.resolveURI(remoteParams[0]); + openURI(xuri); + break; + + case "mailto": + var xuri = cmdLine.resolveURI("mailto:" + remoteParams[0]); + openURI(xuri); + break; + + case "xfedocommand": + // xfeDoCommand(openBrowser) + switch (remoteParams[0].toLowerCase()) { + case "openinbox": + var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Components.classes.nsIWindowMediator); + var win = wm.getMostRecentWindow("mail:3pane"); + if (win) { + win.focus(); + } + else { + var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] + .getService(nsIWindowWatcher); + + // Bug 277798 - we have to pass an argument to openWindow(), or + // else it won't honor the dialog=no instruction. + var argstring = Components.classes["@mozilla.org/supports-string;1"] + .createInstance(nsISupportsString); + wwatch.openWindow(null, "chrome://messenger/content/", "_blank", + "chrome,dialog=no,all", argstring); + } + break; + + case "composemessage": + var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] + .getService(nsIWindowWatcher); + var argstring = Components.classes["@mozilla.org/supports-string;1"] + .createInstance(nsISupportsString); + wwatch.openWindow(null, "chrome://messenger/content/messengercompose/messengercompose.xul", "_blank", + "chrome,dialog=no,all", argstring); + break; + + default: + throw Components.results.NS_ERROR_ABORT; + } + break; + + default: + // Somebody sent us a remote command we don't know how to process: + // just abort. + throw Components.results.NS_ERROR_ABORT; + } + + cmdLine.preventDefault = true; + } + catch (e) { + // If we had a -remote flag but failed to process it, throw + // NS_ERROR_ABORT so that the xremote code knows to return a failure + // back to the handling code. + dump(e); + throw Components.results.NS_ERROR_ABORT; + } + } + var count = cmdLine.length; if (count) { var i = 0; diff --git a/mozilla/toolkit/Makefile.in b/mozilla/toolkit/Makefile.in index 5aeb234ea6b..a16b2bc526c 100644 --- a/mozilla/toolkit/Makefile.in +++ b/mozilla/toolkit/Makefile.in @@ -49,7 +49,6 @@ DIRS = \ obsolete \ profile \ xre \ - components \ mozapps \ themes \ $(NULL) diff --git a/mozilla/toolkit/components/Makefile.in b/mozilla/toolkit/components/Makefile.in index f4752db177a..6ba382c0a25 100644 --- a/mozilla/toolkit/components/Makefile.in +++ b/mozilla/toolkit/components/Makefile.in @@ -43,7 +43,16 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -DIRS = \ +# These component dirs are built for all apps (including seamonkey) + +ifdef MOZ_ENABLE_XREMOTE +DIRS += remote +endif + +# These component dirs are built only for XUL apps + +ifdef MOZ_XUL_APP +DIRS += \ console \ filepicker \ printing \ @@ -62,7 +71,7 @@ DIRS += \ typeaheadfind \ downloads \ $(NULL) -endif +endif # MOZ_THUNDERBIRD ifeq ($(OS_ARCH),WINNT) DIRS += alerts @@ -76,4 +85,6 @@ DIRS += \ EXTRA_PP_COMPONENTS = nsDefaultCLH.js +endif # MOZ_XUL_APP + include $(topsrcdir)/config/rules.mk diff --git a/mozilla/toolkit/components/commandlines/public/nsICommandLine.idl b/mozilla/toolkit/components/commandlines/public/nsICommandLine.idl index 5e3bfe923fd..26e97b8daa4 100644 --- a/mozilla/toolkit/components/commandlines/public/nsICommandLine.idl +++ b/mozilla/toolkit/components/commandlines/public/nsICommandLine.idl @@ -39,6 +39,7 @@ interface nsIFile; interface nsIURI; +interface nsIDOMWindow; /** * Represents the command line used to invoke a XUL application. This may be the @@ -54,7 +55,7 @@ interface nsIURI; * yet. Please use with care. */ -[scriptable, uuid(d2368f41-b2ed-424e-891e-f7aedd92d5d3)] +[scriptable, uuid(bc3173bd-aa46-46a0-9d25-d9867a9659b6)] interface nsICommandLine : nsISupports { /** @@ -149,6 +150,12 @@ interface nsICommandLine : nsISupports */ readonly attribute nsIFile workingDirectory; + /** + * A window to be targeted by this command line. In most cases, this will + * be null (xremote will sometimes set this attribute). + */ + readonly attribute nsIDOMWindow windowContext; + /** * Resolve a file-path argument into an nsIFile. This method gracefully * handles relative or absolute file paths, according to the working diff --git a/mozilla/toolkit/components/commandlines/public/nsICommandLineRunner.idl b/mozilla/toolkit/components/commandlines/public/nsICommandLineRunner.idl index 2a458c9e11e..e1fc9f68057 100644 --- a/mozilla/toolkit/components/commandlines/public/nsICommandLineRunner.idl +++ b/mozilla/toolkit/components/commandlines/public/nsICommandLineRunner.idl @@ -50,7 +50,7 @@ * Smedberg . */ -[uuid(8089187e-2f73-48dc-a8e1-baa2633618e3)] +[uuid(c1f4cfbf-a41f-4628-aa6c-9fb914478af8)] interface nsICommandLineRunner : nsICommandLine { /** @@ -65,6 +65,11 @@ interface nsICommandLineRunner : nsICommandLine void init(in long argc, in nsCharPtrArray argv, in nsIFile workingDir, in unsigned long state); + /** + * Set the windowContext parameter. + */ + void setWindowContext(in nsIDOMWindow aWindow); + /** * Process the command-line handlers in the proper order, calling "handle()" on * each. diff --git a/mozilla/toolkit/components/commandlines/src/Makefile.in b/mozilla/toolkit/components/commandlines/src/Makefile.in index 4c809294074..1e3bdbc075e 100644 --- a/mozilla/toolkit/components/commandlines/src/Makefile.in +++ b/mozilla/toolkit/components/commandlines/src/Makefile.in @@ -58,6 +58,7 @@ REQUIRES = \ string \ necko \ unicharutil \ + dom \ $(NULL) CPPSRCS = \ diff --git a/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp b/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp index c7cbb4d2ce0..54612e13df4 100644 --- a/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp +++ b/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp @@ -39,6 +39,7 @@ #include "nsICategoryManager.h" #include "nsICommandLineHandler.h" +#include "nsIDOMWindow.h" #include "nsIFile.h" #include "nsISimpleEnumerator.h" #include "nsIStringEnumerator.h" @@ -90,6 +91,7 @@ protected: nsStringArray mArgs; PRUint32 mState; nsCOMPtr mWorkingDir; + nsCOMPtr mWindowContext; PRBool mPreventDefault; }; @@ -245,6 +247,20 @@ nsCommandLine::GetWorkingDirectory(nsIFile* *aResult) return NS_OK; } +NS_IMETHODIMP +nsCommandLine::GetWindowContext(nsIDOMWindow* *aResult) +{ + NS_IF_ADDREF(*aResult = mWindowContext); + return NS_OK; +} + +NS_IMETHODIMP +nsCommandLine::SetWindowContext(nsIDOMWindow* aValue) +{ + mWindowContext = aValue; + return NS_OK; +} + NS_IMETHODIMP nsCommandLine::ResolveFile(const nsAString& aArgument, nsIFile* *aResult) { diff --git a/mozilla/toolkit/components/remote/Makefile.in b/mozilla/toolkit/components/remote/Makefile.in new file mode 100644 index 00000000000..6257b56b8dd --- /dev/null +++ b/mozilla/toolkit/components/remote/Makefile.in @@ -0,0 +1,82 @@ +# +# ***** 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. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Christopher Blizzard . +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of 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 ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = toolkitcomps +LIBRARY_NAME = remoteservice +EXPORT_LIBRARY = 1 +IS_COMPONENT = 1 +MODULE_NAME = RemoteServiceModule + +REQUIRES = \ + xpcom \ + string \ + appcomps \ + toolkitcomps \ + appcomps \ + xulapp \ + widget \ + gfx \ + dom \ + docshell \ + $(NULL) + +XPIDLSRCS = nsIRemoteService.idl + +ifneq (,$(filter gtk gtk2,$(MOZ_WIDGET_TOOLKIT))) +CPPSRCS += nsGTKRemoteService.cpp +endif + +ifeq (photon,$(MOZ_WIDGET_TOOLKIT)) +CPPSRCS += nsPhMozRemoteHelper.cpp +endif + +include $(topsrcdir)/config/rules.mk + +ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT)) +CXXFLAGS += $(MOZ_GTK2_CFLAGS) +endif + +ifeq (gtk,$(MOZ_WIDGET_TOOLKIT)) +CXXFLAGS += $(MOZ_GTK_CFLAGS) +endif diff --git a/mozilla/toolkit/components/remote/nsGTKRemoteService.cpp b/mozilla/toolkit/components/remote/nsGTKRemoteService.cpp new file mode 100644 index 00000000000..46c1f1d5862 --- /dev/null +++ b/mozilla/toolkit/components/remote/nsGTKRemoteService.cpp @@ -0,0 +1,576 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=8: + */ +/* ***** 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. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard + * Benjamin Smedberg + * + * 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 "nsGTKRemoteService.h" + +#include // for XA_STRING +#include +#include // For some reason GTK+ doesn't include this file + // automatically from gtk.h +#include +#include + +#include "nsIBaseWindow.h" +#include "nsIDocShell.h" +#include "nsIDOMWindow.h" +#include "nsIGenericFactory.h" +#include "nsILocalFile.h" +#include "nsIObserverService.h" +#include "nsIScriptGlobalObject.h" +#include "nsIServiceManager.h" +#include "nsIWeakReference.h" +#include "nsIWidget.h" + +#include "nsCOMPtr.h" +#include "nsString.h" +#include "prprf.h" +#include "prenv.h" +#include "nsCRT.h" + +#ifdef MOZ_XUL_APP +#include "nsICommandLineRunner.h" +#include "nsXULAppAPI.h" +#else +#include "nsISuiteRemoteService.h" +#endif + +#define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" +#define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" +#define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND" +#define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" +#define MOZILLA_USER_PROP "_MOZILLA_USER" +#define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE" +#define MOZILLA_PROGRAM_PROP "_MOZILLA_PROGRAM" +#define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE" + +#ifdef MOZ_XUL_APP +const unsigned char kRemoteVersion[] = "5.1"; +#else +const unsigned char kRemoteVersion[] = "5.0"; +#endif + +NS_IMPL_QUERY_INTERFACE2(nsGTKRemoteService, + nsIRemoteService, + nsIObserver); + +NS_IMETHODIMP_(nsrefcnt) +nsGTKRemoteService::AddRef() +{ + return 1; +} + +NS_IMETHODIMP_(nsrefcnt) +nsGTKRemoteService::Release() +{ + return 1; +} + +NS_IMETHODIMP +nsGTKRemoteService::Startup(const char* aAppName, const char* aProfileName) +{ + NS_ASSERTION(aAppName, "Don't pass a null appname!"); + + EnsureAtoms(); + if (mServerWindow) return NS_ERROR_ALREADY_INITIALIZED; + + mAppName = aAppName; + ToLowerCase(mAppName); + + mProfileName = aProfileName; + + mServerWindow = gtk_invisible_new(); + gtk_widget_realize(mServerWindow); + HandleCommandsFor(mServerWindow, nsnull); + + if (!mWindows.IsInitialized()) + mWindows.Init(); + + mWindows.EnumerateRead(StartupHandler, this); + + nsCOMPtr obs + (do_GetService("@mozilla.org/observer-service;1")); + if (obs) { + obs->AddObserver(this, "xpcom-shutdown", PR_FALSE); + obs->AddObserver(this, "quit-application", PR_FALSE); + } + + return NS_OK; +} + +PLDHashOperator +nsGTKRemoteService::StartupHandler(const void* aKey, + nsIWeakReference* aData, + void* aClosure) +{ + GtkWidget* widget = (GtkWidget*) aKey; + nsGTKRemoteService* aThis = (nsGTKRemoteService*) aClosure; + + aThis->HandleCommandsFor(widget, aData); + return PL_DHASH_NEXT; +} + +NS_IMETHODIMP +nsGTKRemoteService::RegisterWindow(nsIDOMWindow* aWindow) +{ + // get the native window for this instance + nsCOMPtr scriptObject + (do_QueryInterface(aWindow)); + NS_ENSURE_TRUE(scriptObject, NS_ERROR_FAILURE); + + nsCOMPtr baseWindow + (do_QueryInterface(scriptObject->GetDocShell())); + NS_ENSURE_TRUE(baseWindow, NS_ERROR_FAILURE); + + nsCOMPtr mainWidget; + baseWindow->GetMainWidget(getter_AddRefs(mainWidget)); + NS_ENSURE_TRUE(mainWidget, NS_ERROR_FAILURE); + + // walk up the widget tree and find the toplevel window in the + // hierarchy + + nsCOMPtr tempWidget (dont_AddRef(mainWidget->GetParent())); + + while (tempWidget) { + tempWidget = dont_AddRef(tempWidget->GetParent()); + if (tempWidget) + mainWidget = tempWidget; + } + + GtkWidget* widget = + (GtkWidget*) mainWidget->GetNativeData(NS_NATIVE_SHELLWIDGET); + NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE); + + nsCOMPtr weak = do_GetWeakReference(aWindow); + NS_ENSURE_TRUE(weak, NS_ERROR_FAILURE); + + if (!mWindows.IsInitialized()) + mWindows.Init(); + + mWindows.Put(widget, weak); + + // If Startup() has already been called, immediately register this window. + if (mServerWindow) { + HandleCommandsFor(widget, weak); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsGTKRemoteService::Shutdown() +{ + if (!mServerWindow) + return NS_ERROR_NOT_INITIALIZED; + + gtk_widget_destroy(mServerWindow); + mServerWindow = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsGTKRemoteService::Observe(nsISupports* aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + // This can be xpcom-shutdown or quit-application, but it's the same either + // way. + Shutdown(); + return NS_OK; +} + +#define ARRAY_LENGTH(array_) (sizeof(array_)/sizeof(array_[0])) + +// Minimize the roundtrips to the X server by getting all the atoms at once +static char *XAtomNames[] = { + MOZILLA_VERSION_PROP, + MOZILLA_LOCK_PROP, + MOZILLA_COMMAND_PROP, + MOZILLA_RESPONSE_PROP, + MOZILLA_USER_PROP, + MOZILLA_PROFILE_PROP, + MOZILLA_PROGRAM_PROP, + MOZILLA_COMMANDLINE_PROP +}; +static Atom XAtoms[ARRAY_LENGTH(XAtomNames)]; + +void +nsGTKRemoteService::EnsureAtoms(void) +{ + if (sMozVersionAtom) + return; + + XInternAtoms(GDK_DISPLAY(), XAtomNames, ARRAY_LENGTH(XAtomNames), + False, XAtoms); + int i = 0; + sMozVersionAtom = XAtoms[i++]; + sMozLockAtom = XAtoms[i++]; + sMozCommandAtom = XAtoms[i++]; + sMozResponseAtom = XAtoms[i++]; + sMozUserAtom = XAtoms[i++]; + sMozProfileAtom = XAtoms[i++]; + sMozProgramAtom = XAtoms[i++]; + sMozCommandLineAtom = XAtoms[i++]; +} + +#ifndef MOZ_XUL_APP +const char* +nsGTKRemoteService::HandleCommand(char* aCommand, nsIDOMWindow* aWindow) +{ + nsresult rv; + + nsCOMPtr remote + (do_GetService("@mozilla.org/browser/xremoteservice;2")); + if (!remote) + return "509 internal error"; + + rv = remote->ParseCommand(aCommand, aWindow); + if (NS_SUCCEEDED(rv)) + return "200 executed command"; + + if (NS_ERROR_INVALID_ARG == rv) + return "500 command not parseable"; + + if (NS_ERROR_NOT_IMPLEMENTED == rv) + return "501 unrecognized command"; + + return "509 internal error"; +} + +#else //MOZ_XUL_APP +const char* +nsGTKRemoteService::HandleCommand(char* aCommand, nsIDOMWindow* aWindow) +{ + nsresult rv; + + nsCOMPtr cmdline + (do_CreateInstance("@mozilla.org/toolkit/command-line;1", &rv)); + if (NS_FAILED(rv)) + return "509 internal error"; + + // 1) Make sure that it looks remotely valid with parens + // 2) Treat ping() immediately and specially + + nsCAutoString command(aCommand); + PRInt32 p1, p2; + p1 = command.FindChar('('); + p2 = command.FindChar(')'); + + if (p1 == kNotFound || p2 == kNotFound || p1 == 0 || p2 < p1) { + return "500 command not parseable"; + } + + command.Truncate(p1); + command.Trim(" ", PR_TRUE, PR_TRUE); + ToLowerCase(command); + +#ifdef DEBUG_bsmedberg + printf("Processing xremote command: %s\n", command.get()); +#endif + + if (!command.EqualsLiteral("ping")) { + char* argv[3] = {"dummyappname", "-remote", aCommand}; + rv = cmdline->Init(3, argv, nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT); + if (NS_FAILED(rv)) + return "509 internal error"; + + if (aWindow) + cmdline->SetWindowContext(aWindow); + + 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"; +} + +const char* +nsGTKRemoteService::HandleCommandLine(char* aBuffer, nsIDOMWindow* aWindow) +{ + nsresult rv; + + nsCOMPtr cmdline + (do_CreateInstance("@mozilla.org/toolkit/command-line;1", &rv)); + if (NS_FAILED(rv)) + return "509 internal error"; + + // the commandline property is constructed as an array of PRInt32 + // followed by a series of null-terminated strings: + // + // [argc][offsetargv0][offsetargv1...]\0\0argv[1]...\0 + // (offset is from the beginning of the buffer) + + PRInt32 argc = *NS_REINTERPRET_CAST(PRInt32*, aBuffer); + char *wd = aBuffer + ((argc + 1) * sizeof(PRInt32)); + +#ifdef DEBUG_bsmedberg + printf("Receiving command line:\n" + " wd:\t%s\n" + " argc:\t%i\n", + wd, argc); +#endif + + nsCOMPtr lf; + rv = NS_NewNativeLocalFile(nsDependentCString(wd), PR_TRUE, + getter_AddRefs(lf)); + if (NS_FAILED(rv)) + return "509 internal error"; + + char **argv = (char**) malloc(sizeof(char*) * argc); + if (!argv) return "509 internal error"; + + PRInt32 *offset = NS_REINTERPRET_CAST(PRInt32*, aBuffer) + 1; + + for (int i = 0; i < argc; ++i) { + argv[i] = aBuffer + offset[i]; + +#ifdef DEBUG_bsmedberg + printf(" argv[%i]:\t%s\n", i, argv[i]); +#endif + } + + rv = cmdline->Init(argc, argv, lf, nsICommandLine::STATE_REMOTE_AUTO); + free (argv); + if (NS_FAILED(rv)) { + return "509 internal error"; + } + + if (aWindow) + cmdline->SetWindowContext(aWindow); + + 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"; +} +#endif // MOZ_XUL_APP + +void +nsGTKRemoteService::HandleCommandsFor(GtkWidget* widget, + nsIWeakReference* aWindow) +{ +#ifdef MOZ_WIDGET_GTK2 + g_signal_connect(G_OBJECT(widget), "property_notify_event", + G_CALLBACK(HandlePropertyChange), aWindow); +#else // GTK+ + gtk_signal_connect(GTK_OBJECT(widget), "property_notify_event", + GTK_SIGNAL_FUNC(HandlePropertyChange), aWindow); +#endif + + gtk_widget_add_events(widget, GDK_PROPERTY_CHANGE_MASK); + + Window window = GDK_WINDOW_XWINDOW(widget->window); + + // set our version + XChangeProperty(GDK_DISPLAY(), window, sMozVersionAtom, XA_STRING, + 8, PropModeReplace, kRemoteVersion, sizeof(kRemoteVersion) - 1); + + // get our username + unsigned char *logname; + logname = (unsigned char*) PR_GetEnv("LOGNAME"); + if (logname) { + // set the property on the window if it's available + XChangeProperty(GDK_DISPLAY(), window, sMozUserAtom, XA_STRING, + 8, PropModeReplace, logname, strlen((char*) logname)); + } + + XChangeProperty(GDK_DISPLAY(), window, sMozProgramAtom, XA_STRING, + 8, PropModeReplace, (unsigned char*) mAppName.get(), mAppName.Length()); + + if (!mProfileName.IsEmpty()) { + XChangeProperty(GDK_DISPLAY(), window, sMozProfileAtom, XA_STRING, + 8, PropModeReplace, (unsigned char*) mProfileName.get(), mProfileName.Length()); + } +} + +#ifdef MOZ_WIDGET_GTK2 +#define CMP_GATOM_XATOM(gatom,xatom) (gatom == gdk_x11_xatom_to_atom(xatom)) +#else +#define CMP_GATOM_XATOM(gatom,xatom) (gatom == xatom) +#endif + +gboolean +nsGTKRemoteService::HandlePropertyChange(GtkWidget *aWidget, + GdkEventProperty *pevent, + nsIWeakReference* aThis) +{ + nsCOMPtr window (do_QueryReferent(aThis)); + + if (pevent->state == GDK_PROPERTY_NEW_VALUE && + CMP_GATOM_XATOM(pevent->atom, sMozCommandAtom)) { + + // We got a new command atom. + int result; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + char *data = 0; + + result = XGetWindowProperty (GDK_DISPLAY(), + GDK_WINDOW_XWINDOW(pevent->window), + sMozCommandAtom, + 0, /* long_offset */ + (65536 / sizeof (long)), /* long_length */ + True, /* atomic delete after */ + XA_STRING, /* req_type */ + &actual_type, /* actual_type return */ + &actual_format, /* actual_format_return */ + &nitems, /* nitems_return */ + &bytes_after, /* bytes_after_return */ + (unsigned char **)&data); /* prop_return + (we only care + about the first ) */ + +#ifdef DEBUG_bsmedberg + printf("Handling command: %s\n", data); +#endif + + // Failed to get property off the window? + if (result != Success) + return FALSE; + + // Failed to get the data off the window or it was the wrong type? + if (!data || !*data) + return FALSE; + + // cool, we got the property data. + const char *response = HandleCommand(data, window); + + // put the property onto the window as the response + XChangeProperty (GDK_DISPLAY(), GDK_WINDOW_XWINDOW(pevent->window), + sMozResponseAtom, XA_STRING, + 8, PropModeReplace, (const unsigned char *)response, strlen (response)); + XFree(data); + return TRUE; + } + +#ifdef MOZ_XUL_APP + if (pevent->state == GDK_PROPERTY_NEW_VALUE && + CMP_GATOM_XATOM(pevent->atom, sMozCommandLineAtom)) { + + // We got a new commandline atom. + int result; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + char *data = 0; + + result = XGetWindowProperty (GDK_DISPLAY(), + GDK_WINDOW_XWINDOW(pevent->window), + sMozCommandLineAtom, + 0, /* long_offset */ + (65536 / sizeof (long)), /* long_length */ + True, /* atomic delete after */ + XA_STRING, /* req_type */ + &actual_type, /* actual_type return */ + &actual_format, /* actual_format_return */ + &nitems, /* nitems_return */ + &bytes_after, /* bytes_after_return */ + (unsigned char **)&data); /* prop_return + (we only care + about the first ) */ + + // Failed to get property off the window? + if (result != Success) + return FALSE; + + // Failed to get the data off the window or it was the wrong type? + if (!data || !*data) + return FALSE; + + // cool, we got the property data. + const char *response = HandleCommandLine(data, window); + + // put the property onto the window as the response + XChangeProperty (GDK_DISPLAY(), GDK_WINDOW_XWINDOW(pevent->window), + sMozResponseAtom, XA_STRING, + 8, PropModeReplace, (const unsigned char *)response, strlen (response)); + XFree(data); + return TRUE; + } +#endif //MOZ_XUL_APP + + if (pevent->state == GDK_PROPERTY_NEW_VALUE && + CMP_GATOM_XATOM(pevent->atom, sMozResponseAtom)) { + // client accepted the response. party on wayne. + return TRUE; + } + + if (pevent->state == GDK_PROPERTY_NEW_VALUE && + CMP_GATOM_XATOM(pevent->atom, sMozLockAtom)) { + // someone locked the window + return TRUE; + } + + return FALSE; +} + +Atom nsGTKRemoteService::sMozVersionAtom; +Atom nsGTKRemoteService::sMozLockAtom; +Atom nsGTKRemoteService::sMozCommandAtom; +Atom nsGTKRemoteService::sMozResponseAtom; +Atom nsGTKRemoteService::sMozUserAtom; +Atom nsGTKRemoteService::sMozProfileAtom; +Atom nsGTKRemoteService::sMozProgramAtom; +Atom nsGTKRemoteService::sMozCommandLineAtom; + +// {C0773E90-5799-4eff-AD03-3EBCD85624AC} +#define NS_REMOTESERVICE_CID \ + { 0xc0773e90, 0x5799, 0x4eff, { 0xad, 0x3, 0x3e, 0xbc, 0xd8, 0x56, 0x24, 0xac } } + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsGTKRemoteService) + +static const nsModuleComponentInfo components[] = +{ + { "Remote Service", + NS_REMOTESERVICE_CID, + "@mozilla.org/toolkit/remote-service;1", + nsGTKRemoteServiceConstructor + } +}; + +NS_IMPL_NSGETMODULE(RemoteServiceModule, components) diff --git a/mozilla/toolkit/components/remote/nsGTKRemoteService.h b/mozilla/toolkit/components/remote/nsGTKRemoteService.h new file mode 100644 index 00000000000..b40558c0bc6 --- /dev/null +++ b/mozilla/toolkit/components/remote/nsGTKRemoteService.h @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: + */ +/* ***** 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. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard + * Benjamin Smedberg + * + * 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 __nsGTKRemoteService_h__ +#define __nsGTKRemoteService_h__ + +#include "nsIRemoteService.h" + +#include "nsIObserver.h" + +#include +#include +#include + +#include "nsString.h" +#include "nsInterfaceHashtable.h" + +class nsIDOMWindow; +class nsIWeakReference; +class nsIWidget; + +class nsGTKRemoteService : public nsIRemoteService, + 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 + + nsGTKRemoteService() : + mServerWindow(NULL) { } + +private: + ~nsGTKRemoteService() { } + + void HandleCommandsFor(GtkWidget* aWidget, + nsIWeakReference* aWindow); + + static void EnsureAtoms(); + static PLDHashOperator StartupHandler(const void* aKey, + nsIWeakReference* aData, + void* aData); + + static const char* HandleCommand(char* aCommand, nsIDOMWindow* aWindow); + +#ifdef MOZ_XUL_APP + static const char* HandleCommandLine(char* aBuffer, nsIDOMWindow* aWindow); +#endif + + static gboolean HandlePropertyChange(GtkWidget *widget, + GdkEventProperty *event, + nsIWeakReference* aThis); + + GtkWidget* mServerWindow; + nsCString mAppName; + nsCString mProfileName; + nsInterfaceHashtable mWindows; + + static Atom sMozVersionAtom; + static Atom sMozLockAtom; + static Atom sMozCommandAtom; + static Atom sMozResponseAtom; + static Atom sMozUserAtom; + static Atom sMozProfileAtom; + static Atom sMozProgramAtom; + static Atom sMozCommandLineAtom; +}; + +#endif // __nsGTKRemoteService_h__ diff --git a/mozilla/xpfe/components/xremote/public/nsIXRemoteService.idl b/mozilla/toolkit/components/remote/nsIRemoteService.idl similarity index 56% rename from mozilla/xpfe/components/xremote/public/nsIXRemoteService.idl rename to mozilla/toolkit/components/remote/nsIRemoteService.idl index 1558703b114..c92b5ad97b7 100644 --- a/mozilla/xpfe/components/xremote/public/nsIXRemoteService.idl +++ b/mozilla/toolkit/components/remote/nsIRemoteService.idl @@ -19,6 +19,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Benjamin Smedberg * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -36,41 +37,42 @@ #include "nsISupports.idl" -/* This interface provides the clue that allows you set up a specific - * browser instance so that it will respond to X remote requests. */ +interface nsIDOMWindow; -interface nsIDOMWindowInternal; -interface nsIWidget; +/** + * 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(510c0946-1dd2-11b2-b210-f5031abff3f0)] -interface nsIXRemoteService : nsISupports { +[scriptable, uuid(a2240f6a-f1e4-4548-9e1a-6f3bc9b2426c)] +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); - // this is called once the browser starts up so that we can create a - // dummy window to respond to requests on. - // - // @param aProgram This is the name of the program that will be - // advertised to clients. This is so we can seperate the various - // Mozilla products. - [noscript] void startup (in string aProgram); - - // this is called right before shutdown so we can destroy the window - // that we are receving requests on - [noscript] void shutdown (); - - // parse the command given and generate a response - [noscript] void parseCommand (in nsIWidget aWidget, - in string aCommand, out string aResponse); - - // add a new browser instance to listen for remote requests on - void addBrowserInstance (in nsIDOMWindowInternal aBrowser); - - // remove a browser instance from the list to listen for requests on - void removeBrowserInstance (in nsIDOMWindowInternal aBrowser); + /** + * Register a XUL window with the xremote service. The window will be + * configured to accept incoming remote requests. If this method is called + * before startup(), the registration will happen once startup() is called. + */ + void registerWindow(in nsIDOMWindow aWindow); + /** + * Stop the remote service from accepting additional requests. + */ + void shutdown(); }; - -%{C++ -#define NS_IXREMOTESERVICE_CONTRACTID "@mozilla.org/browser/xremoteservice;1" -#define NS_IXREMOTESERVICE_CLASSNAME "Mozilla XRemote Service" -%} - diff --git a/mozilla/toolkit/library/Makefile.in b/mozilla/toolkit/library/Makefile.in index 1e3e6a79f15..1d2761a2ffc 100644 --- a/mozilla/toolkit/library/Makefile.in +++ b/mozilla/toolkit/library/Makefile.in @@ -221,9 +221,6 @@ endif ifdef MOZ_ENABLE_PHOTON COMPONENT_LIBS += widget_photon endif -ifdef MOZ_ENABLE_XREMOTE -COMPONENT_LIBS += xremote_client -endif ifdef MOZ_OJI STATIC_LIBS += jsj diff --git a/mozilla/toolkit/library/nsStaticXULComponents.cpp b/mozilla/toolkit/library/nsStaticXULComponents.cpp index 685d5ce4b8a..8d9310b17f7 100644 --- a/mozilla/toolkit/library/nsStaticXULComponents.cpp +++ b/mozilla/toolkit/library/nsStaticXULComponents.cpp @@ -131,12 +131,6 @@ #define XPRINT_MODULES #endif -#ifdef MOZ_ENABLE_XREMOTE -#define XREMOTE_MODULES MODULE(XRemoteClientModule) -#else -#define XREMOTE_MODULES -#endif - #ifdef OJI #define OJI_MODULES MODULE(nsCJVMManagerModule) #else @@ -167,7 +161,6 @@ POSTSCRIPT_MODULES \ GFX_MODULES \ WIDGET_MODULES \ - XREMOTE_MODULES \ MODULE(nsImageLib2Module) \ ICON_MODULE \ MODULE(nsPluginModule) \ diff --git a/mozilla/toolkit/xre/Makefile.in b/mozilla/toolkit/xre/Makefile.in index 8b6840edd31..8a738d4fa4c 100644 --- a/mozilla/toolkit/xre/Makefile.in +++ b/mozilla/toolkit/xre/Makefile.in @@ -153,6 +153,11 @@ endif SHARED_LIBRARY_LIBS += ../profile/src/$(LIB_PREFIX)profile_s.$(LIB_SUFFIX) +ifdef MOZ_ENABLE_XREMOTE +SHARED_LIBRARY_LIBS += $(DEPTH)/widget/src/xremoteclient/$(LIB_PREFIX)xremote_client_s.$(LIB_SUFFIX) +LOCAL_INCLUDES += -I$(topsrcdir)/widget/src/xremoteclient +endif + include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES += -I$(topsrcdir)/xpfe/bootstrap -I$(srcdir)/../profile/src diff --git a/mozilla/toolkit/xre/nsAppRunner.cpp b/mozilla/toolkit/xre/nsAppRunner.cpp index f4e3fc11bf7..c4375bb2980 100644 --- a/mozilla/toolkit/xre/nsAppRunner.cpp +++ b/mozilla/toolkit/xre/nsAppRunner.cpp @@ -102,6 +102,7 @@ #include "nsAppDirectoryServiceDefs.h" #include "nsXULAppAPI.h" #include "nsXREDirProvider.h" +#include "nsToolkitCompsCID.h" #include "nsINIParser.h" @@ -130,9 +131,12 @@ // for X remote support #ifdef MOZ_ENABLE_XREMOTE -#include "nsXRemoteClientCID.h" -#include "nsIXRemoteClient.h" -#include "nsIXRemoteService.h" +#ifdef MOZ_WIDGET_PHOTON +#include "PhRemoteClient.h" +#else +#include "XRemoteClient.h" +#endif +#include "nsIRemoteService.h" #endif #ifdef NS_TRACE_MALLOC @@ -906,44 +910,73 @@ HandleRemoteArgument(const char* remote) return 1; } - // start XPCOM - ScopedXPCOMStartup xpcom; - rv = xpcom.Initialize(); - NS_ENSURE_SUCCESS(rv, 1); + XRemoteClient client; + rv = client.Init(); + if (NS_FAILED(rv)) { + PR_fprintf(PR_STDERR, "Error: Failed to connect to X server.\n"); + return 1; + } - { // scope the comptr so we don't hold on to XPCOM objects beyond shutdown - // try to get the X remote client - nsCOMPtr client (do_CreateInstance(NS_XREMOTECLIENT_CONTRACTID)); - NS_ENSURE_TRUE(client, 1); + nsXPIDLCString response; + PRBool success = PR_FALSE; + rv = client.SendCommand(program.get(), username, profile, remote, + getter_Copies(response), &success); + // did the command fail? + if (NS_FAILED(rv)) { + PR_fprintf(PR_STDERR, "Error: Failed to send command: %s\n", + response ? response.get() : "No response included"); + return 1; + } - // try to init - connects to the X server and stuff - rv = client->Init(); - if (NS_FAILED(rv)) { - PR_fprintf(PR_STDERR, "Error: Failed to connect to X server.\n"); - return 1; - } - - nsXPIDLCString response; - PRBool success = PR_FALSE; - rv = client->SendCommand(program.get(), username, profile, remote, - getter_Copies(response), &success); - // did the command fail? - if (NS_FAILED(rv)) { - PR_fprintf(PR_STDERR, "Error: Failed to send command: %s\n", - response ? response.get() : "No response included"); - return 1; - } - - if (!success) { - PR_fprintf(PR_STDERR, "Error: No running window found\n"); - return 2; - } - - client->Shutdown(); + if (!success) { + PR_fprintf(PR_STDERR, "Error: No running window found\n"); + return 2; } return 0; } + +static PRBool +RemoteCommandLine() +{ + nsresult rv; + ArgResult ar; + + nsCAutoString program(gAppData->appName); + ToLowerCase(program); + const char *username = getenv("LOGNAME"); + + const char *temp = nsnull; + ar = CheckArg("a", &temp); + if (ar == ARG_BAD) { + PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n"); + return PR_FALSE; + } else if (ar == ARG_FOUND) { + program.Assign(temp); + } + + ar = CheckArg("u", &username); + if (ar == ARG_BAD) { + PR_fprintf(PR_STDERR, "Error: argument -u requires a username\n"); + return PR_FALSE; + } + + XRemoteClient client; + rv = client.Init(); + if (NS_FAILED(rv)) + return PR_FALSE; + + nsXPIDLCString response; + PRBool success = PR_FALSE; + rv = client.SendCommandLine(program.get(), username, nsnull, + gArgc, gArgv, + getter_Copies(response), &success); + // did the command fail? + if (NS_FAILED(rv) || !success) + return PR_FALSE; + + return PR_TRUE; +} #endif // MOZ_ENABLE_XREMOTE #if defined(XP_UNIX) && !defined(XP_MACOSX) @@ -1768,6 +1801,10 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) if (ar) { return HandleRemoteArgument(xremotearg); } + + // Try to remote the entire command line. If this fails, start up normally. + if (RemoteCommandLine()) + return 0; #endif nsCOMPtr profileLock; @@ -1990,10 +2027,10 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) #ifdef MOZ_ENABLE_XREMOTE // if we have X remote support and we have our one window up and // running start listening for requests on the proxy window. - nsCOMPtr remoteService; - remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID); + nsCOMPtr remoteService; + remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1"); if (remoteService) - remoteService->Startup(aAppData->appName); + remoteService->Startup(gAppData->appName, nsnull); #endif /* MOZ_ENABLE_XREMOTE */ // enable win32 DDE responses and Mac appleevents responses diff --git a/mozilla/widget/public/Makefile.in b/mozilla/widget/public/Makefile.in index 30a54427457..243cf1e9d8d 100644 --- a/mozilla/widget/public/Makefile.in +++ b/mozilla/widget/public/Makefile.in @@ -69,7 +69,6 @@ EXPORTS = \ nsIDragSessionXlib.h \ nsIDragSessionMac.h \ nsIDragSessionOS2.h \ - nsIXRemoteWidgetHelper.h \ nsIPluginWidget.h \ nsINativeKeyBindings.h \ $(NULL) @@ -101,7 +100,6 @@ XPIDLSRCS = \ nsIMenuRollup.idl \ nsIBaseWindow.idl \ nsIBidiKeyboard.idl \ - nsIXRemoteClient.idl \ nsIFullScreen.idl \ nsINativeScrollbar.idl \ $(NULL) diff --git a/mozilla/widget/public/nsIWidget.h b/mozilla/widget/public/nsIWidget.h index f909aed47c1..9d9ac041c08 100644 --- a/mozilla/widget/public/nsIWidget.h +++ b/mozilla/widget/public/nsIWidget.h @@ -90,6 +90,7 @@ typedef nsEventStatus (*PR_CALLBACK EVENT_CALLBACK)(nsGUIEvent *event); #define NS_NATIVE_OFFSETY 7 #define NS_NATIVE_PLUGIN_PORT 8 #define NS_NATIVE_SCREEN 9 +#define NS_NATIVE_SHELLWIDGET 10 // Get the shell GtkWidget // {18032AD5-B265-11d1-AA2A-000000000000} #define NS_IWIDGET_IID \ diff --git a/mozilla/widget/public/nsIXRemoteWidgetHelper.h b/mozilla/widget/public/nsIXRemoteWidgetHelper.h deleted file mode 100644 index f5300b5a697..00000000000 --- a/mozilla/widget/public/nsIXRemoteWidgetHelper.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** 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. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Christopher Blizzard - * - * 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 ***** */ - -class nsIWidget; - -// {9fe661fa-1dd1-11b2-bd72-ff439d2e8557} - -#define NS_IXREMOTEWIDGETHELPER_IID \ - { 0x9fe661fa, 0x1dd1, 0x11b2, \ - { 0xbd, 0x72, 0xff, 0x43, 0x9d, 0x2e, 0x85, 0x57 } } - -class nsIXRemoteWidgetHelper : public nsISupports { - - public: - NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXREMOTEWIDGETHELPER_IID) - - NS_IMETHOD EnableXRemoteCommands(nsIWidget *aWidget, - const char *aProfile, - const char *aProgram) = 0; - -}; - -#define NS_IXREMOTEWIDGETHELPER_CONTRACTID "@mozilla.org/widgets/xremotehelper;1" -#define NS_IXREMOTEWIDGETHELPER_CLASSNAME "Mozilla XRemote Widget Helper Service" diff --git a/mozilla/widget/src/Makefile.in b/mozilla/widget/src/Makefile.in index bd9b3b5488c..729245b70e4 100644 --- a/mozilla/widget/src/Makefile.in +++ b/mozilla/widget/src/Makefile.in @@ -94,9 +94,5 @@ ifdef MOZ_ENABLE_PHOTON DIRS += photon endif -ifdef MOZ_ENABLE_XREMOTE -DIRS += xremoteclient -endif - include $(topsrcdir)/config/rules.mk diff --git a/mozilla/widget/src/gtk/Makefile.in b/mozilla/widget/src/gtk/Makefile.in index 506a98bb886..fc970551da6 100644 --- a/mozilla/widget/src/gtk/Makefile.in +++ b/mozilla/widget/src/gtk/Makefile.in @@ -60,7 +60,6 @@ REQUIRES = xpcom \ dom \ uconv \ necko \ - xremoteservice \ view \ util \ unicharutil \ @@ -92,7 +91,6 @@ CPPSRCS = \ nsWidgetFactory.cpp \ nsWindow.cpp \ nsGtkIMEHelper.cpp \ - nsGtkMozRemoteHelper.cpp \ $(NULL) SHARED_LIBRARY_LIBS = $(DIST)/lib/libxpwidgets_s.a diff --git a/mozilla/widget/src/gtk/nsGtkMozRemoteHelper.cpp b/mozilla/widget/src/gtk/nsGtkMozRemoteHelper.cpp deleted file mode 100644 index 986b0b5b865..00000000000 --- a/mozilla/widget/src/gtk/nsGtkMozRemoteHelper.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* ***** 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. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Christopher Blizzard - * - * 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 // for XA_STRING -#include -#include -#include -#include -#include -#include -#include -#include "nsGtkMozRemoteHelper.h" -#include "nsCRT.h" - -#define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" -#define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" -#define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND" -#define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" -#define MOZILLA_USER_PROP "_MOZILLA_USER" -#define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE" -#define MOZILLA_PROGRAM_PROP "_MOZILLA_PROGRAM" - -Atom nsGtkMozRemoteHelper::sMozVersionAtom = 0; -Atom nsGtkMozRemoteHelper::sMozLockAtom = 0; -Atom nsGtkMozRemoteHelper::sMozCommandAtom = 0; -Atom nsGtkMozRemoteHelper::sMozResponseAtom = 0; -Atom nsGtkMozRemoteHelper::sMozUserAtom = 0; -Atom nsGtkMozRemoteHelper::sMozProfileAtom = 0; -Atom nsGtkMozRemoteHelper::sMozProgramAtom = 0; - -#define ARRAY_LENGTH(array_) (sizeof(array_)/sizeof(array_[0])) - -// Minimize the roundtrips to the X-server -static char *XAtomNames[] = { - MOZILLA_VERSION_PROP, - MOZILLA_LOCK_PROP, - MOZILLA_COMMAND_PROP, - MOZILLA_RESPONSE_PROP, - MOZILLA_USER_PROP, - MOZILLA_PROFILE_PROP, - MOZILLA_PROGRAM_PROP -}; -static Atom XAtoms[ARRAY_LENGTH(XAtomNames)]; - -// XXX get this dynamically -static const char sRemoteVersion[] = "5.0"; - -void -nsGtkMozRemoteHelper::SetupVersion(GdkWindow *aWindow, const char *aProfile, - const char *aProgram) -{ - Window window; - unsigned char *data = (unsigned char *)sRemoteVersion; - EnsureAtoms(); - window = GDK_WINDOW_XWINDOW(aWindow); - - // set our version - XChangeProperty(GDK_DISPLAY(), window, sMozVersionAtom, XA_STRING, - 8, PropModeReplace, data, strlen(sRemoteVersion)); - - // get our username - char *logname; - logname = PR_GetEnv("LOGNAME"); - if (logname) { - data = (unsigned char *)logname; - - // set the property on the window if it's available - XChangeProperty(GDK_DISPLAY(), window, sMozUserAtom, XA_STRING, - 8, PropModeReplace, data, strlen(logname)); - } - - // set our profile name and program name, if available. - if (aProfile) { - data = (unsigned char *)aProfile; - - XChangeProperty(GDK_DISPLAY(), window, sMozProfileAtom, XA_STRING, - 8, PropModeReplace, data, strlen(aProfile)); - } - - if (aProgram) { - data = (unsigned char *)aProgram; - - XChangeProperty(GDK_DISPLAY(), window, sMozProgramAtom, XA_STRING, - 8, PropModeReplace, data, strlen(aProgram)); - } -} - -gboolean -nsGtkMozRemoteHelper::HandlePropertyChange(GtkWidget *aWidget, - GdkEventProperty *aEvent, - nsIWidget *ansIWidget) -{ - - EnsureAtoms(); - - // see if this is the command atom and it's new - if (aEvent->state == GDK_PROPERTY_NEW_VALUE && - aEvent->window == aWidget->window && - aEvent->atom == sMozCommandAtom) - { - int result; - Atom actual_type; - int actual_format; - unsigned long nitems, bytes_after; - char *data = 0; - - result = XGetWindowProperty (GDK_DISPLAY(), - GDK_WINDOW_XWINDOW(aWidget->window), - sMozCommandAtom, - 0, /* long_offset */ - (65536 / sizeof (long)), /* long_length */ - True, /* atomic delete after */ - XA_STRING, /* req_type */ - &actual_type, /* actual_type return */ - &actual_format, /* actual_format_return */ - &nitems, /* nitems_return */ - &bytes_after, /* bytes_after_return */ - (unsigned char **)&data); /* prop_return - ( we only care about - the first ) */ - if (result != Success) - { - // failed to get property off the window - return FALSE; - } - else if (!data || !*data) - { - // failed to get the data off the window or it was the wrong - // type - return FALSE; - } - // cool, we got the property data. - char *response = NULL; - // The reason that we are using a conditional free here is that if - // ParseCommand() fails below it's probably because of failed - // memory allocations. If that's the case we want to make sure - // that we try to get something back to the client instead of just - // giving up since a lot of clients will just hang forever. Hence - // using a static string. - PRBool freeResponse = PR_TRUE; - - // parse the command - nsCOMPtr remoteService; - remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID); - - if (remoteService) - remoteService->ParseCommand(ansIWidget, data, &response); - - if (!response) - { - response = "500 error parsing command"; - freeResponse = PR_FALSE; - } - // put the property onto the window as the response - XChangeProperty (GDK_DISPLAY(), GDK_WINDOW_XWINDOW(aWidget->window), - sMozResponseAtom, XA_STRING, - 8, PropModeReplace, (const unsigned char *)response, strlen (response)); - if (freeResponse) - nsCRT::free(response); - XFree(data); - return TRUE; - } - else if (aEvent->state == GDK_PROPERTY_NEW_VALUE && - aEvent->window == aWidget->window && - aEvent->atom == sMozResponseAtom) - { - // client accepted the response. party on wayne. - return TRUE; - } - else if (aEvent->state == GDK_PROPERTY_NEW_VALUE && - aEvent->window == aWidget->window && - aEvent->atom == sMozLockAtom) - { - // someone locked the window - return TRUE; - } - return FALSE; -} - -void -nsGtkMozRemoteHelper::EnsureAtoms(void) -{ - // init our atoms if we need to - static PRBool initialized; - if (!initialized) { - XInternAtoms(GDK_DISPLAY(), XAtomNames, ARRAY_LENGTH(XAtomNames), False, XAtoms); - - int i = 0; - sMozVersionAtom = XAtoms[i++]; - sMozLockAtom = XAtoms[i++]; - sMozCommandAtom = XAtoms[i++]; - sMozResponseAtom = XAtoms[i++]; - sMozUserAtom = XAtoms[i++]; - sMozProfileAtom = XAtoms[i++]; - sMozProgramAtom = XAtoms[i++]; - - initialized = PR_TRUE; - } -} - - -nsGtkMozRemoteHelper::~nsGtkMozRemoteHelper() -{ -} - -nsGtkXRemoteWidgetHelper::nsGtkXRemoteWidgetHelper() -{ -} - -nsGtkXRemoteWidgetHelper::~nsGtkXRemoteWidgetHelper() -{ -} - -NS_IMPL_ISUPPORTS1(nsGtkXRemoteWidgetHelper, nsIXRemoteWidgetHelper) - -NS_IMETHODIMP -nsGtkXRemoteWidgetHelper::EnableXRemoteCommands(nsIWidget *aWidget, - const char *aProfile, - const char *aProgram) -{ - // find the native gdk window - GdkWindow *window = NS_STATIC_CAST(GdkWindow *, - aWidget->GetNativeData(NS_NATIVE_WINDOW)); - if (!window) - return NS_ERROR_FAILURE; - - // find the toplevel gdk window - GdkWindow *temp = window; - - while (temp) { - temp = gdk_window_get_parent(window); - if (!temp || temp == GDK_ROOT_PARENT()) - break; - window = temp; - } - - // ok, found the toplevel window - set up the version information - nsGtkMozRemoteHelper::SetupVersion(window, aProfile, aProgram); - - return NS_OK; -} - diff --git a/mozilla/widget/src/gtk/nsGtkMozRemoteHelper.h b/mozilla/widget/src/gtk/nsGtkMozRemoteHelper.h deleted file mode 100644 index 53b28ae6399..00000000000 --- a/mozilla/widget/src/gtk/nsGtkMozRemoteHelper.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** 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. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Christopher Blizzard - * - * 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 -#include -#include -#include -#include - -#ifndef __nsGtkMozRemoteHelper_h__ -#define __nsGtkMozRemoteHelper_h__ - -class nsGtkMozRemoteHelper -{ -public: - nsGtkMozRemoteHelper(); - virtual ~nsGtkMozRemoteHelper(); - - // interaction from the outside world - static void SetupVersion (GdkWindow *aWindow, - const char *aProfile, - const char *aProgram); - static gboolean HandlePropertyChange (GtkWidget *aWidget, - GdkEventProperty *aEvent, - nsIWidget *ansIWidget); - - private: - - // internal methods - static void EnsureAtoms (void); - - static Atom sMozVersionAtom; - static Atom sMozLockAtom; - static Atom sMozCommandAtom; - static Atom sMozResponseAtom; - static Atom sMozUserAtom; - static Atom sMozProfileAtom; - static Atom sMozProgramAtom; - -}; - -// {84f94aac-1dd2-11b2-a05f-9b338fea662c} - -#define NS_GTKXREMOTEWIDGETHELPER_CID \ - { 0x84f94aac, 0x1dd2, 0x11b2, \ - { 0xa0, 0x5f, 0x9b, 0x33, 0x8f, 0xea, 0x66, 0x2c } } - -class nsGtkXRemoteWidgetHelper : public nsIXRemoteWidgetHelper { - public: - nsGtkXRemoteWidgetHelper(); - virtual ~nsGtkXRemoteWidgetHelper(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD EnableXRemoteCommands(nsIWidget *aWidget, - const char *aProfile, - const char *aProgram); -}; - -#endif /* __nsGtkMozRemoteHelper_h__ */ diff --git a/mozilla/widget/src/gtk/nsWidgetFactory.cpp b/mozilla/widget/src/gtk/nsWidgetFactory.cpp index 620e1dbb512..7cde6f5b29e 100644 --- a/mozilla/widget/src/gtk/nsWidgetFactory.cpp +++ b/mozilla/widget/src/gtk/nsWidgetFactory.cpp @@ -57,7 +57,6 @@ #include "nsHTMLFormatConverter.h" #include "nsDragService.h" #include "nsSound.h" -#include "nsGtkMozRemoteHelper.h" #include "nsBidiKeyboard.h" #include "nsGtkIMEHelper.h" @@ -77,7 +76,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsGtkXRemoteWidgetHelper) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard) static const nsModuleComponentInfo components[] = @@ -146,10 +144,6 @@ static const nsModuleComponentInfo components[] = // "@mozilla.org/widget/dragservice/gtk;1", "@mozilla.org/widget/dragservice;1", nsDragServiceConstructor }, - { NS_IXREMOTEWIDGETHELPER_CLASSNAME, - NS_GTKXREMOTEWIDGETHELPER_CID, - NS_IXREMOTEWIDGETHELPER_CONTRACTID, - nsGtkXRemoteWidgetHelperConstructor }, { "Gtk Bidi Keyboard", NS_BIDIKEYBOARD_CID, "@mozilla.org/widget/bidikeyboard;1", diff --git a/mozilla/widget/src/gtk/nsWindow.cpp b/mozilla/widget/src/gtk/nsWindow.cpp index d116b0afc5a..b8d689e164e 100644 --- a/mozilla/widget/src/gtk/nsWindow.cpp +++ b/mozilla/widget/src/gtk/nsWindow.cpp @@ -79,8 +79,6 @@ #include "nsGtkUtils.h" // for nsGtkUtils::gdk_window_flash() -#include "nsGtkMozRemoteHelper.h" - #include "nsIDragService.h" #include "nsIDragSessionGTK.h" @@ -159,11 +157,6 @@ void handle_toplevel_configure ( GtkMozArea * aArea, nsWindow * aWindow); -gboolean handle_toplevel_property_change ( - GtkWidget *aGtkWidget, - GdkEventProperty *event, - nsWindow *aWindow); - // are we grabbing? PRBool nsWindow::sIsGrabbing = PR_FALSE; nsWindow *nsWindow::sGrabWindow = NULL; @@ -1984,12 +1977,7 @@ NS_METHOD nsWindow::CreateNative(GtkObject *parentWidget) // set up all the focus handling if (mShell) { - gtk_signal_connect(GTK_OBJECT(mShell), - "property_notify_event", - GTK_SIGNAL_FUNC(handle_toplevel_property_change), - this); - mask = (GdkEventMask) (GDK_PROPERTY_CHANGE_MASK | - GDK_KEY_PRESS_MASK | + mask = (GdkEventMask) (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK ); gdk_window_set_events(mShell->window, @@ -2203,6 +2191,9 @@ void * nsWindow::GetNativeData(PRUint32 aDataType) } return NULL; } + else if (aDataType == NS_NATIVE_SHELLWIDGET) { + return (void *) mShell; + } return nsWidget::GetNativeData(aDataType); } @@ -2897,17 +2888,6 @@ void handle_toplevel_configure ( aWindow->OnMove(x, y); } - -gboolean handle_toplevel_property_change ( - GtkWidget *aGtkWidget, - GdkEventProperty *event, - nsWindow *aWindow) -{ - nsIWidget *widget = NS_STATIC_CAST(nsIWidget *, aWindow); - return nsGtkMozRemoteHelper::HandlePropertyChange(aGtkWidget, event, - widget); -} - void nsWindow::HandleXlibConfigureNotifyEvent(XEvent *event) { diff --git a/mozilla/widget/src/gtk2/Makefile.in b/mozilla/widget/src/gtk2/Makefile.in index b0e9427f2eb..59bce2b4b9a 100644 --- a/mozilla/widget/src/gtk2/Makefile.in +++ b/mozilla/widget/src/gtk2/Makefile.in @@ -61,7 +61,6 @@ REQUIRES = xpcom \ uconv \ intl \ gtkxtbin \ - xremoteservice \ imglib2 \ $(NULL) @@ -80,7 +79,6 @@ CPPSRCS = \ nsCommonWidget.cpp \ nsLookAndFeel.cpp \ nsGtkKeyUtils.cpp \ - nsGtkMozRemoteHelper.cpp \ nsClipboard.cpp \ nsDragService.cpp \ nsFilePicker.cpp \ diff --git a/mozilla/widget/src/gtk2/nsGtkMozRemoteHelper.cpp b/mozilla/widget/src/gtk2/nsGtkMozRemoteHelper.cpp deleted file mode 100644 index b27374c90da..00000000000 --- a/mozilla/widget/src/gtk2/nsGtkMozRemoteHelper.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** 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. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Christopher Blizzard - * - * 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 // for XA_STRING -#include -#include -#include -#include -#include -#include -#include -#include -#include "nsGtkMozRemoteHelper.h" - -#define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" -#define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" -#define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND" -#define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" -#define MOZILLA_USER_PROP "_MOZILLA_USER" -#define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE" -#define MOZILLA_PROGRAM_PROP "_MOZILLA_PROGRAM" - -Atom nsGtkMozRemoteHelper::sMozVersionAtom = 0; -Atom nsGtkMozRemoteHelper::sMozLockAtom = 0; -Atom nsGtkMozRemoteHelper::sMozCommandAtom = 0; -Atom nsGtkMozRemoteHelper::sMozResponseAtom = 0; -Atom nsGtkMozRemoteHelper::sMozUserAtom = 0; -Atom nsGtkMozRemoteHelper::sMozProfileAtom = 0; -Atom nsGtkMozRemoteHelper::sMozProgramAtom = 0; - -#define ARRAY_LENGTH(array_) (sizeof(array_)/sizeof(array_[0])) - -// Minimize the roundtrips to the X-server -static char *XAtomNames[] = { - MOZILLA_VERSION_PROP, - MOZILLA_LOCK_PROP, - MOZILLA_COMMAND_PROP, - MOZILLA_RESPONSE_PROP, - MOZILLA_USER_PROP, - MOZILLA_PROFILE_PROP, - MOZILLA_PROGRAM_PROP -}; -static Atom XAtoms[ARRAY_LENGTH(XAtomNames)]; - -// XXX get this dynamically -static const char sRemoteVersion[] = "5.0"; - -void -nsGtkMozRemoteHelper::SetupVersion(GdkWindow *aWindow, const char *aProfile, - const char *aProgram) -{ - Window window; - unsigned char *data = (unsigned char *)sRemoteVersion; - EnsureAtoms(); - window = GDK_WINDOW_XWINDOW(aWindow); - - // set our version - XChangeProperty(GDK_DISPLAY(), window, sMozVersionAtom, XA_STRING, - 8, PropModeReplace, data, strlen(sRemoteVersion)); - - // get our username - char *logname; - logname = PR_GetEnv("LOGNAME"); - if (logname) { - data = (unsigned char *)logname; - - // set the property on the window if it's available - XChangeProperty(GDK_DISPLAY(), window, sMozUserAtom, XA_STRING, - 8, PropModeReplace, data, strlen(logname)); - } - - // set our profile name and program name, if available. - if (aProfile) { - data = (unsigned char *)aProfile; - - XChangeProperty(GDK_DISPLAY(), window, sMozProfileAtom, XA_STRING, - 8, PropModeReplace, data, strlen(aProfile)); - } - - if (aProgram) { - data = (unsigned char *)aProgram; - - XChangeProperty(GDK_DISPLAY(), window, sMozProgramAtom, XA_STRING, - 8, PropModeReplace, data, strlen(aProgram)); - } -} - -gboolean -nsGtkMozRemoteHelper::HandlePropertyChange(GtkWidget *aWidget, - GdkEventProperty *aEvent, - nsIWidget *ansIWidget) -{ - - EnsureAtoms(); - - // see if this is the command atom and it's new - if (aEvent->state == GDK_PROPERTY_NEW_VALUE && - aEvent->window == aWidget->window && - aEvent->atom == gdk_x11_xatom_to_atom(sMozCommandAtom)) - { - int result; - Atom actual_type; - int actual_format; - unsigned long nitems, bytes_after; - char *data = 0; - - result = XGetWindowProperty (GDK_DISPLAY(), - GDK_WINDOW_XWINDOW(aWidget->window), - sMozCommandAtom, - 0, /* long_offset */ - (65536 / sizeof (long)), /* long_length */ - True, /* atomic delete after */ - XA_STRING, /* req_type */ - &actual_type, /* actual_type return */ - &actual_format, /* actual_format_return */ - &nitems, /* nitems_return */ - &bytes_after, /* bytes_after_return */ - (unsigned char **)&data); /* prop_return - ( we only care about - the first ) */ - if (result != Success) - { - // failed to get property off the window - return FALSE; - } - else if (!data || !*data) - { - // failed to get the data off the window or it was the wrong - // type - return FALSE; - } - // cool, we got the property data. - char *response = NULL; - // The reason that we are using a conditional free here is that if - // ParseCommand() fails below it's probably because of failed - // memory allocations. If that's the case we want to make sure - // that we try to get something back to the client instead of just - // giving up since a lot of clients will just hang forever. Hence - // using a static string. - PRBool freeResponse = PR_TRUE; - - // parse the command - nsCOMPtr remoteService; - remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID); - - if (remoteService) - remoteService->ParseCommand(ansIWidget, data, &response); - - if (!response) - { - response = "500 error parsing command"; - freeResponse = PR_FALSE; - } - // put the property onto the window as the response - XChangeProperty (GDK_DISPLAY(), GDK_WINDOW_XWINDOW(aWidget->window), - sMozResponseAtom, XA_STRING, - 8, PropModeReplace, (const unsigned char *)response, strlen (response)); - if (freeResponse) - nsCRT::free(response); - XFree(data); - return TRUE; - } - else if (aEvent->state == GDK_PROPERTY_NEW_VALUE && - aEvent->window == aWidget->window && - aEvent->atom == gdk_x11_xatom_to_atom(sMozResponseAtom)) - { - // client accepted the response. party on wayne. - return TRUE; - } - else if (aEvent->state == GDK_PROPERTY_NEW_VALUE && - aEvent->window == aWidget->window && - aEvent->atom == gdk_x11_xatom_to_atom(sMozLockAtom)) - { - // someone locked the window - return TRUE; - } - return FALSE; -} - -void -nsGtkMozRemoteHelper::EnsureAtoms(void) -{ - // init our atoms if we need to - static PRBool initialized; - if (!initialized) { - XInternAtoms(GDK_DISPLAY(), XAtomNames, ARRAY_LENGTH(XAtomNames), False, XAtoms); - - int i = 0; - sMozVersionAtom = XAtoms[i++]; - sMozLockAtom = XAtoms[i++]; - sMozCommandAtom = XAtoms[i++]; - sMozResponseAtom = XAtoms[i++]; - sMozUserAtom = XAtoms[i++]; - sMozProfileAtom = XAtoms[i++]; - sMozProgramAtom = XAtoms[i++]; - - initialized = PR_TRUE; - } -} - - -nsGtkMozRemoteHelper::~nsGtkMozRemoteHelper() -{ -} - -nsGtkXRemoteWidgetHelper::nsGtkXRemoteWidgetHelper() -{ -} - -nsGtkXRemoteWidgetHelper::~nsGtkXRemoteWidgetHelper() -{ -} - -NS_IMPL_ISUPPORTS1(nsGtkXRemoteWidgetHelper, nsIXRemoteWidgetHelper) - -NS_IMETHODIMP -nsGtkXRemoteWidgetHelper::EnableXRemoteCommands(nsIWidget *aWidget, - const char *aProfile, - const char *aProgram) -{ - // find the native gdk window - GdkWindow *window = NS_STATIC_CAST(GdkWindow *, - aWidget->GetNativeData(NS_NATIVE_WINDOW)); - if (!window) - return NS_ERROR_FAILURE; - - // find the toplevel gdk window - this will stop at the window that - // is the direct child of the root window - notice the break - GdkWindow *temp = window; - - while (temp) { - temp = gdk_window_get_parent(window); - if (!temp || temp == GDK_ROOT_PARENT()) - break; - window = temp; - } - - // ok, found the toplevel window - set up the version information - nsGtkMozRemoteHelper::SetupVersion(window, aProfile, aProgram); - - return NS_OK; -} - diff --git a/mozilla/widget/src/gtk2/nsGtkMozRemoteHelper.h b/mozilla/widget/src/gtk2/nsGtkMozRemoteHelper.h deleted file mode 100644 index 53b28ae6399..00000000000 --- a/mozilla/widget/src/gtk2/nsGtkMozRemoteHelper.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** 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. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Christopher Blizzard - * - * 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 -#include -#include -#include -#include - -#ifndef __nsGtkMozRemoteHelper_h__ -#define __nsGtkMozRemoteHelper_h__ - -class nsGtkMozRemoteHelper -{ -public: - nsGtkMozRemoteHelper(); - virtual ~nsGtkMozRemoteHelper(); - - // interaction from the outside world - static void SetupVersion (GdkWindow *aWindow, - const char *aProfile, - const char *aProgram); - static gboolean HandlePropertyChange (GtkWidget *aWidget, - GdkEventProperty *aEvent, - nsIWidget *ansIWidget); - - private: - - // internal methods - static void EnsureAtoms (void); - - static Atom sMozVersionAtom; - static Atom sMozLockAtom; - static Atom sMozCommandAtom; - static Atom sMozResponseAtom; - static Atom sMozUserAtom; - static Atom sMozProfileAtom; - static Atom sMozProgramAtom; - -}; - -// {84f94aac-1dd2-11b2-a05f-9b338fea662c} - -#define NS_GTKXREMOTEWIDGETHELPER_CID \ - { 0x84f94aac, 0x1dd2, 0x11b2, \ - { 0xa0, 0x5f, 0x9b, 0x33, 0x8f, 0xea, 0x66, 0x2c } } - -class nsGtkXRemoteWidgetHelper : public nsIXRemoteWidgetHelper { - public: - nsGtkXRemoteWidgetHelper(); - virtual ~nsGtkXRemoteWidgetHelper(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD EnableXRemoteCommands(nsIWidget *aWidget, - const char *aProfile, - const char *aProgram); -}; - -#endif /* __nsGtkMozRemoteHelper_h__ */ diff --git a/mozilla/widget/src/gtk2/nsWidgetFactory.cpp b/mozilla/widget/src/gtk2/nsWidgetFactory.cpp index ccf65b8d204..d9cf292b35e 100644 --- a/mozilla/widget/src/gtk2/nsWidgetFactory.cpp +++ b/mozilla/widget/src/gtk2/nsWidgetFactory.cpp @@ -42,7 +42,6 @@ #include "nsBaseWidget.h" #include "nsLookAndFeel.h" #include "nsWindow.h" -#include "nsGtkMozRemoteHelper.h" #include "nsTransferable.h" #include "nsClipboardHelper.h" #include "nsHTMLFormatConverter.h" @@ -71,7 +70,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAppShell) NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel) NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsGtkXRemoteWidgetHelper) NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsClipboard, Init) @@ -171,10 +169,6 @@ static const nsModuleComponentInfo components[] = NS_SOUND_CID, "@mozilla.org/sound;1", nsSoundConstructor }, - { NS_IXREMOTEWIDGETHELPER_CLASSNAME, - NS_GTKXREMOTEWIDGETHELPER_CID, - NS_IXREMOTEWIDGETHELPER_CONTRACTID, - nsGtkXRemoteWidgetHelperConstructor }, { "Transferable", NS_TRANSFERABLE_CID, "@mozilla.org/widget/transferable;1", diff --git a/mozilla/widget/src/gtk2/nsWindow.cpp b/mozilla/widget/src/gtk2/nsWindow.cpp index c05525380d7..83e0a604578 100644 --- a/mozilla/widget/src/gtk2/nsWindow.cpp +++ b/mozilla/widget/src/gtk2/nsWindow.cpp @@ -52,7 +52,6 @@ #include "nsGtkKeyUtils.h" #include "nsGtkCursors.h" -#include "nsGtkMozRemoteHelper.h" #include #include @@ -150,8 +149,6 @@ static gboolean visibility_notify_event_cb(GtkWidget *widget, GdkEventVisibility *event); static gboolean window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event); -static gboolean property_notify_event_cb (GtkWidget *widget, - GdkEventProperty *event); static void style_set_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer data); @@ -1053,6 +1050,9 @@ nsWindow::GetNativeData(PRUint32 aDataType) break; } + case NS_NATIVE_SHELLWIDGET: + return (void *) mShell; + default: NS_WARNING("nsWindow::GetNativeData called with bad value"); return nsnull; @@ -2412,14 +2412,8 @@ nsWindow::NativeCreate(nsIWidget *aParent, G_CALLBACK(configure_event_cb), NULL); g_signal_connect(G_OBJECT(mShell), "delete_event", G_CALLBACK(delete_event_cb), NULL); - // we need to add this to the shell since versions of gtk - // before 2.0.3 forgot to set property_notify events on the - // shell window - gtk_widget_add_events(mShell, GDK_PROPERTY_CHANGE_MASK); g_signal_connect(G_OBJECT(mShell), "window_state_event", G_CALLBACK(window_state_event_cb), NULL); - g_signal_connect(G_OBJECT(mShell), "property_notify_event", - G_CALLBACK(property_notify_event_cb), NULL); g_signal_connect(G_OBJECT(mShell), "style_set", G_CALLBACK(style_set_cb), NULL); } @@ -3892,19 +3886,6 @@ window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event) return FALSE; } -/* static */ -gboolean -property_notify_event_cb (GtkWidget *widget, GdkEventProperty *event) -{ - nsIWidget *nswidget = (nsIWidget *)get_window_for_gtk_widget(widget); - if (!nswidget) - return FALSE; - - nsGtkMozRemoteHelper::HandlePropertyChange(widget, event, nswidget); - - return FALSE; -} - /* static */ void style_set_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer data) diff --git a/mozilla/widget/src/photon/nsPhMozRemoteHelper.cpp b/mozilla/widget/src/photon/nsPhMozRemoteHelper.cpp deleted file mode 100644 index f224b7fee74..00000000000 --- a/mozilla/widget/src/photon/nsPhMozRemoteHelper.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* ***** 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. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adrian Mardare - * - * 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 -#include -#include -#include -#include "nsPhMozRemoteHelper.h" -#include "nsIServiceManager.h" -#include "nsCRT.h" - -#include - - -//------------------------------------------------------------------------- -// -// A client has connected and probably will want to xremote control us -// -//------------------------------------------------------------------------- - -#define MOZ_REMOTE_MSG_TYPE 100 - -static void const * RemoteMsgHandler( PtConnectionServer_t *connection, void *user_data, - unsigned long type, void const *msg, unsigned len, unsigned *reply_len ) -{ - if( type != MOZ_REMOTE_MSG_TYPE ) return NULL; - - /* we are given strings and we reply with strings */ - char *command = ( char * ) msg, *response = NULL; - - // parse the command - nsCOMPtr remoteService; - remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID); - - if( remoteService ) { - command[len] = 0; - /* it seems we can pass any non-null value as the first argument - if this changes, pass a valid nsWidget* and move this code to nsWidget.cpp */ - remoteService->ParseCommand( (nsIWidget*)0x1, command, &response ); - } - - PtConnectionReply( connection, response ? strlen( response ) : 0, response ); - - if( response ) nsCRT::free( response ); - - return ( void * ) 1; /* return any non NULL value to indicate we handled the message */ -} - -static void client_connect( PtConnector_t *cntr, PtConnectionServer_t *csrvr, void *data ) -{ - static PtConnectionMsgHandler_t handlers[] = { { 0, RemoteMsgHandler } }; - PtConnectionAddMsgHandlers( csrvr, handlers, sizeof(handlers)/sizeof(handlers[0]) ); -} - - - -nsPhXRemoteWidgetHelper::nsPhXRemoteWidgetHelper() -{ -} - -nsPhXRemoteWidgetHelper::~nsPhXRemoteWidgetHelper() -{ -} - -NS_IMPL_ISUPPORTS1(nsPhXRemoteWidgetHelper, nsIXRemoteWidgetHelper) - -NS_IMETHODIMP -nsPhXRemoteWidgetHelper::EnableXRemoteCommands( nsIWidget *aWidget, const char *aProfile, const char *aProgram ) -{ - static PRBool ConnectorCreated = PR_FALSE; - -///* ATENTIE */ printf( "aProgram=%s aProfile=%s aWidget=%p\n", aProgram?aProgram:"NULL", aProfile?aProfile:"NULL", aWidget ); - - if( !ConnectorCreated ) { - char RemoteServerName[128]; - sprintf( RemoteServerName, "%s_RemoteServer", aProgram ? aProgram : "mozilla" ); - /* create a connector for the xremote control */ - PtConnectorCreate( RemoteServerName, client_connect, NULL ); - ConnectorCreated = PR_TRUE; - } - - return NS_OK; -} diff --git a/mozilla/widget/src/xremoteclient/Makefile.in b/mozilla/widget/src/xremoteclient/Makefile.in index 21b5fbe328e..536e6707e56 100644 --- a/mozilla/widget/src/xremoteclient/Makefile.in +++ b/mozilla/widget/src/xremoteclient/Makefile.in @@ -35,6 +35,10 @@ # # ***** END LICENSE BLOCK ***** +# NOTE: This directory is part of tier 50, and is linked directly into +# the application binaries. The fact that it's under mozilla/widget is a fluke +# of tree history. + DEPTH = ../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ @@ -42,21 +46,13 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -MODULE = widget -LIBRARY_NAME = xremote_client -EXPORT_LIBRARY = 1 -IS_COMPONENT = 1 -MODULE_NAME = XRemoteClientModule -LIBXUL_LIBRARY = 1 +MODULE = xremoteclient +LIBRARY_NAME = xremote_client_s +FORCE_STATIC_LIB = 1 -PACKAGE_FILE = xremoteclient.pkg - -REQUIRES = xpcom \ - $(NULL) - -CPPSRCS = \ - XRemoteClientFactory.cpp \ - $(NULL) +REQUIRES = \ + xpcom \ + $(NULL) ifdef MOZ_ENABLE_PHOTON CPPSRCS += PhRemoteClient.cpp @@ -73,9 +69,6 @@ ifdef MOZ_ENABLE_PHOTON EXTRA_DSO_LDOPTS += -lph endif -EXPORTS = \ - nsXRemoteClientCID.h - PROGRAM = mozilla-xremote-client$(BIN_SUFFIX) PROGOBJS = mozilla-xremote-client.$(OBJ_SUFFIX) \ @@ -101,8 +94,8 @@ endif ifndef MOZ_ENABLE_PHOTON XRemoteClient_standalone.$(OBJ_SUFFIX): XRemoteClient.cpp - $(CXX) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) -DXREMOTE_STANDALONE $< + $(CXX) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $< else XRemoteClient_standalone.$(OBJ_SUFFIX): PhRemoteClient.cpp - $(CXX) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) -DXREMOTE_STANDALONE $< + $(CXX) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $< endif diff --git a/mozilla/widget/src/xremoteclient/XRemoteClient.cpp b/mozilla/widget/src/xremoteclient/XRemoteClient.cpp index b2e97e7e45a..4469560ae88 100644 --- a/mozilla/widget/src/xremoteclient/XRemoteClient.cpp +++ b/mozilla/widget/src/xremoteclient/XRemoteClient.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:expandtab:shiftwidth=4:tabstop=4: */ /* vim:set ts=8 sw=2 et cindent: */ @@ -45,8 +45,10 @@ #include "prsystem.h" #include "prlog.h" #include "prenv.h" +#include "prdtoa.h" #include #include +#include #include #include #include @@ -59,11 +61,16 @@ #define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" #define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" #define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND" +#define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE" #define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" #define MOZILLA_USER_PROP "_MOZILLA_USER" #define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE" #define MOZILLA_PROGRAM_PROP "_MOZILLA_PROGRAM" +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + #define ARRAY_LENGTH(array_) (sizeof(array_)/sizeof(array_[0])) static PRLogModuleInfo *sRemoteLm = NULL; @@ -91,10 +98,6 @@ XRemoteClient::~XRemoteClient() Shutdown(); } -#ifndef XREMOTE_STANDALONE -NS_IMPL_ISUPPORTS1(XRemoteClient, nsIXRemoteClient) -#endif - // Minimize the roundtrips to the X-server static char *XAtomNames[] = { MOZILLA_VERSION_PROP, @@ -104,17 +107,19 @@ static char *XAtomNames[] = { "WM_STATE", MOZILLA_USER_PROP, MOZILLA_PROFILE_PROP, - MOZILLA_PROGRAM_PROP + MOZILLA_PROGRAM_PROP, + MOZILLA_COMMANDLINE_PROP }; static Atom XAtoms[ARRAY_LENGTH(XAtomNames)]; -NS_IMETHODIMP -XRemoteClient::Init (void) +nsresult +XRemoteClient::Init() { PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::Init")); if (mInitialized) return NS_OK; + // try to open the display mDisplay = XOpenDisplay(0); if (!mDisplay) @@ -132,19 +137,21 @@ XRemoteClient::Init (void) mMozUserAtom = XAtoms[i++]; mMozProfileAtom = XAtoms[i++]; mMozProgramAtom = XAtoms[i++]; + mMozCommandLineAtom = XAtoms[i++]; mInitialized = PR_TRUE; return NS_OK; } -NS_IMETHODIMP +void XRemoteClient::Shutdown (void) { PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::Shutdown")); if (!mInitialized) - return NS_OK; + return; + // shut everything down XCloseDisplay(mDisplay); mDisplay = 0; @@ -153,10 +160,9 @@ XRemoteClient::Shutdown (void) free(mLockData); mLockData = 0; } - return NS_OK; } -NS_IMETHODIMP +nsresult XRemoteClient::SendCommand (const char *aProgram, const char *aUsername, const char *aProfile, const char *aCommand, char **aResponse, PRBool *aWindowFound) @@ -165,7 +171,7 @@ XRemoteClient::SendCommand (const char *aProgram, const char *aUsername, *aWindowFound = PR_FALSE; - Window w = FindBestWindow(aProgram, aUsername, aProfile); + Window w = FindBestWindow(aProgram, aUsername, aProfile, PR_FALSE); nsresult rv = NS_OK; @@ -199,6 +205,50 @@ XRemoteClient::SendCommand (const char *aProgram, const char *aUsername, return rv; } +nsresult +XRemoteClient::SendCommandLine (const char *aProgram, const char *aUsername, + const char *aProfile, + PRInt32 argc, char **argv, + char **aResponse, PRBool *aWindowFound) +{ + PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::SendCommandLine")); + + *aWindowFound = PR_FALSE; + + Window w = FindBestWindow(aProgram, aUsername, aProfile, PR_TRUE); + + nsresult rv = NS_OK; + + if (w) { + // ok, let the caller know that we at least found a window. + *aWindowFound = PR_TRUE; + + // make sure we get the right events on that window + XSelectInput(mDisplay, w, + (PropertyChangeMask|StructureNotifyMask)); + + PRBool destroyed = PR_FALSE; + + // get the lock on the window + rv = GetLock(w, &destroyed); + + if (NS_SUCCEEDED(rv)) { + // send our command + rv = DoSendCommandLine(w, argc, argv, aResponse, &destroyed); + + // if the window was destroyed, don't bother trying to free the + // lock. + if (!destroyed) + FreeLock(w); // doesn't really matter what this returns + + } + } + + PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("SendCommandLine returning 0x%x\n", rv)); + + return rv; +} + Window XRemoteClient::CheckWindow(Window aWindow) { @@ -389,7 +439,8 @@ XRemoteClient::GetLock(Window aWindow, PRBool *aDestroyed) Window XRemoteClient::FindBestWindow(const char *aProgram, const char *aUsername, - const char *aProfile) + const char *aProfile, + PRBool aSupportsCommandLine) { Window root = RootWindowOfScreen(DefaultScreenOfDisplay(mDisplay)); Window bestWindow = 0; @@ -432,7 +483,12 @@ XRemoteClient::FindBestWindow(const char *aProgram, const char *aUsername, if (!data_return) continue; + PRFloat64 version = PR_strtod((char*) data_return, nsnull); XFree(data_return); + + if (aSupportsCommandLine && !(version >= 5.1 && version < 6)) + continue; + data_return = 0; if (status != Success || type == None) @@ -518,6 +574,9 @@ XRemoteClient::FindBestWindow(const char *aProgram, const char *aUsername, } } + // Check to see if the window supports the new command-line passing + // protocol, if that is requested. + // If we got this far, this is the best window so far. It passed // all the tests. bestWindow = w; @@ -571,129 +630,208 @@ nsresult XRemoteClient::DoSendCommand(Window aWindow, const char *aCommand, char **aResponse, PRBool *aDestroyed) { - PRBool done = PR_FALSE; - PRBool accepted = PR_FALSE; *aDestroyed = PR_FALSE; PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("(writing " MOZILLA_COMMAND_PROP " \"%s\" to 0x%x)\n", - aCommand, (unsigned int) aWindow)); + ("(writing " MOZILLA_COMMAND_PROP " \"%s\" to 0x%x)\n", + aCommand, (unsigned int) aWindow)); XChangeProperty (mDisplay, aWindow, mMozCommandAtom, XA_STRING, 8, - PropModeReplace, (unsigned char *)aCommand, - strlen(aCommand)); + PropModeReplace, (unsigned char *)aCommand, + strlen(aCommand)); + + if (!WaitForResponse(aWindow, aResponse, aDestroyed, mMozCommandAtom)) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +/* like strcpy, but return the char after the final null */ +static char* +estrcpy(char* s, char* d) +{ + while (*s) + *d++ = *s++; + + *d++ = '\0'; + return d; +} + +nsresult +XRemoteClient::DoSendCommandLine(Window aWindow, PRInt32 argc, char **argv, + char **aResponse, PRBool *aDestroyed) +{ + int i; + + *aDestroyed = PR_FALSE; + + char cwdbuf[MAX_PATH]; + if (!getcwd(cwdbuf, MAX_PATH)) + return NS_ERROR_UNEXPECTED; + + // the commandline property is constructed as an array of PRInt32 + // followed by a series of null-terminated strings: + // + // [argc][offsetargv0][offsetargv1...]\0\0argv[1]...\0 + // (offset is from the beginning of the buffer) + + PRInt32 argvlen = strlen(cwdbuf); + for (i = 0; i < argc; ++i) + argvlen += strlen(argv[i]); + + PRInt32* buffer = (PRInt32*) malloc(argvlen + argc + 1 + + sizeof(PRInt32) * (argc + 1)); + if (!buffer) + return NS_ERROR_OUT_OF_MEMORY; + + buffer[0] = argc; + + char *bufend = (char*) (buffer + argc + 1); + + bufend = estrcpy(cwdbuf, bufend); + + for (int i = 0; i < argc; ++i) { + buffer[i + 1] = bufend - ((char*) buffer); + bufend = estrcpy(argv[i], bufend); + } + +#ifdef DEBUG_bsmedberg + PRInt32 debug_argc = *buffer; + char *debug_workingdir = (char*) (buffer + argc + 1); + + printf("Sending command line:\n" + " working dir: %s\n" + " argc:\t%i", + debug_workingdir, + debug_argc); + + PRInt32 *debug_offset = buffer + 1; + for (int debug_i = 0; debug_i < debug_argc; ++debug_i) + printf(" argv[%i]:\t%s\n", debug_i, + ((char*) buffer) + debug_offset[debug_i]); +#endif + + XChangeProperty (mDisplay, aWindow, mMozCommandLineAtom, XA_STRING, 8, + PropModeReplace, (unsigned char *) buffer, + bufend - ((char*) buffer)); + + if (!WaitForResponse(aWindow, aResponse, aDestroyed, mMozCommandLineAtom)) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +PRBool +XRemoteClient::WaitForResponse(Window aWindow, char **aResponse, + PRBool *aDestroyed, Atom aCommandAtom) +{ + PRBool done = PR_FALSE; + PRBool accepted = PR_FALSE; while (!done) { XEvent event; XNextEvent (mDisplay, &event); if (event.xany.type == DestroyNotify && - event.xdestroywindow.window == aWindow) { + event.xdestroywindow.window == aWindow) { /* Print to warn user...*/ PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("window 0x%x was destroyed.\n", - (unsigned int) aWindow)); + ("window 0x%x was destroyed.\n", + (unsigned int) aWindow)); *aResponse = strdup("Window was destroyed while reading response."); *aDestroyed = PR_TRUE; - goto DONE; + return PR_FALSE; } else if (event.xany.type == PropertyNotify && - event.xproperty.state == PropertyNewValue && - event.xproperty.window == aWindow && - event.xproperty.atom == mMozResponseAtom) { + event.xproperty.state == PropertyNewValue && + event.xproperty.window == aWindow && + event.xproperty.atom == mMozResponseAtom) { Atom actual_type; int actual_format; unsigned long nitems, bytes_after; unsigned char *data = 0; Bool result; result = XGetWindowProperty (mDisplay, aWindow, mMozResponseAtom, - 0, (65536 / sizeof (long)), - True, /* atomic delete after */ - XA_STRING, - &actual_type, &actual_format, - &nitems, &bytes_after, - &data); + 0, (65536 / sizeof (long)), + True, /* atomic delete after */ + XA_STRING, + &actual_type, &actual_format, + &nitems, &bytes_after, + &data); if (result != Success) { - PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("failed reading " MOZILLA_RESPONSE_PROP - " from window 0x%0x.\n", - (unsigned int) aWindow)); - *aResponse = strdup("Internal error reading response from window."); - done = PR_TRUE; + PR_LOG(sRemoteLm, PR_LOG_DEBUG, + ("failed reading " MOZILLA_RESPONSE_PROP + " from window 0x%0x.\n", + (unsigned int) aWindow)); + *aResponse = strdup("Internal error reading response from window."); + done = PR_TRUE; } else if (!data || strlen((char *) data) < 5) { - PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("invalid data on " MOZILLA_RESPONSE_PROP - " property of window 0x%0x.\n", - (unsigned int) aWindow)); - *aResponse = strdup("Server returned invalid data in response."); - done = PR_TRUE; + PR_LOG(sRemoteLm, PR_LOG_DEBUG, + ("invalid data on " MOZILLA_RESPONSE_PROP + " property of window 0x%0x.\n", + (unsigned int) aWindow)); + *aResponse = strdup("Server returned invalid data in response."); + done = PR_TRUE; } - else if (*data == '1') { /* positive preliminary reply */ - PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("%s\n", data + 4)); - /* keep going */ - done = PR_FALSE; + else if (*data == '1') { /* positive preliminary reply */ + PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("%s\n", data + 4)); + /* keep going */ + done = PR_FALSE; } else if (!strncmp ((char *)data, "200", 3)) { /* positive completion */ - *aResponse = strdup((char *)data); - accepted = PR_TRUE; - done = PR_TRUE; + *aResponse = strdup((char *)data); + accepted = PR_TRUE; + done = PR_TRUE; } - else if (*data == '2') { /* positive completion */ - PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("%s\n", data + 4)); - *aResponse = strdup((char *)data); - accepted = PR_TRUE; - done = PR_TRUE; + else if (*data == '2') { /* positive completion */ + PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("%s\n", data + 4)); + *aResponse = strdup((char *)data); + accepted = PR_TRUE; + done = PR_TRUE; } - else if (*data == '3') { /* positive intermediate reply */ - PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("internal error: " - "server wants more information? (%s)\n", - data)); - *aResponse = strdup((char *)data); - done = PR_TRUE; + else if (*data == '3') { /* positive intermediate reply */ + PR_LOG(sRemoteLm, PR_LOG_DEBUG, + ("internal error: " + "server wants more information? (%s)\n", + data)); + *aResponse = strdup((char *)data); + done = PR_TRUE; } - else if (*data == '4' || /* transient negative completion */ - *data == '5') { /* permanent negative completion */ - PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("%s\n", data + 4)); - *aResponse = strdup((char *)data); - done = PR_TRUE; + else if (*data == '4' || /* transient negative completion */ + *data == '5') { /* permanent negative completion */ + PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("%s\n", data + 4)); + *aResponse = strdup((char *)data); + done = PR_TRUE; } else { - PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("unrecognised " MOZILLA_RESPONSE_PROP - " from window 0x%x: %s\n", - (unsigned int) aWindow, data)); - *aResponse = strdup((char *)data); - done = PR_TRUE; + PR_LOG(sRemoteLm, PR_LOG_DEBUG, + ("unrecognised " MOZILLA_RESPONSE_PROP + " from window 0x%x: %s\n", + (unsigned int) aWindow, data)); + *aResponse = strdup((char *)data); + done = PR_TRUE; } if (data) - XFree(data); + XFree(data); } else if (event.xany.type == PropertyNotify && - event.xproperty.window == aWindow && - event.xproperty.state == PropertyDelete && - event.xproperty.atom == mMozCommandAtom) { + event.xproperty.window == aWindow && + event.xproperty.state == PropertyDelete && + event.xproperty.atom == aCommandAtom) { PR_LOG(sRemoteLm, PR_LOG_DEBUG, - ("(server 0x%x has accepted " - MOZILLA_COMMAND_PROP ".)\n", - (unsigned int) aWindow)); + ("(server 0x%x has accepted " + MOZILLA_COMMAND_PROP ".)\n", + (unsigned int) aWindow)); } } - DONE: - - if (!accepted) - return NS_ERROR_FAILURE; - - return NS_OK; + return accepted; } - - diff --git a/mozilla/widget/src/xremoteclient/XRemoteClient.h b/mozilla/widget/src/xremoteclient/XRemoteClient.h index 787a39d108f..2def6414f8d 100644 --- a/mozilla/widget/src/xremoteclient/XRemoteClient.h +++ b/mozilla/widget/src/xremoteclient/XRemoteClient.h @@ -37,24 +37,23 @@ #include #include -#include "nsIXRemoteClient.h" +#include "nsRemoteClient.h" -class XRemoteClient -#ifndef XREMOTE_STANDALONE -: public nsIXRemoteClient -#endif +class XRemoteClient : public nsRemoteClient { - public: +public: XRemoteClient(); - virtual ~XRemoteClient(); + ~XRemoteClient(); -#ifndef XREMOTE_STANDALONE - // nsISupports - NS_DECL_ISUPPORTS -#endif - - // nsIXRemoteClient - NS_DECL_NSIXREMOTECLIENT + virtual nsresult Init(); + virtual nsresult SendCommand(const char *aProgram, const char *aUsername, + const char *aProfile, const char *aCommand, + char **aResponse, PRBool *aSucceeded); + virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername, + const char *aProfile, + PRInt32 argc, char **argv, + char **aResponse, PRBool *aSucceeded); + void Shutdown(); private: @@ -62,23 +61,33 @@ private: Window CheckChildren (Window aWindow); nsresult GetLock (Window aWindow, PRBool *aDestroyed); nsresult FreeLock (Window aWindow); - Window FindBestWindow (const char *aProgram, const char *aUsername, - const char *aProfile); + Window FindBestWindow (const char *aProgram, + const char *aUsername, + const char *aProfile, + PRBool aSupportsCommandLine); nsresult DoSendCommand (Window aWindow, - const char *aCommand, - char **aResponse, - PRBool *aDestroyed); + const char *aCommand, + char **aResponse, + PRBool *aDestroyed); + nsresult DoSendCommandLine(Window aWindow, + PRInt32 argc, char **argv, + char **aResponse, + PRBool *aDestroyed); + PRBool WaitForResponse (Window aWindow, char **aResponse, + PRBool *aDestroyed, Atom aCommandAtom); Display *mDisplay; Atom mMozVersionAtom; Atom mMozLockAtom; Atom mMozCommandAtom; + Atom mMozCommandLineAtom; Atom mMozResponseAtom; Atom mMozWMStateAtom; Atom mMozUserAtom; Atom mMozProfileAtom; Atom mMozProgramAtom; + Atom mMozSupportsCLAtom; char *mLockData; diff --git a/mozilla/widget/src/xremoteclient/mozilla-xremote-client.cpp b/mozilla/widget/src/xremoteclient/mozilla-xremote-client.cpp index 218c4916abf..011eabf6679 100644 --- a/mozilla/widget/src/xremoteclient/mozilla-xremote-client.cpp +++ b/mozilla/widget/src/xremoteclient/mozilla-xremote-client.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #ifdef MOZ_WIDGET_PHOTON #include "PhRemoteClient.h" diff --git a/mozilla/widget/public/nsIXRemoteClient.idl b/mozilla/widget/src/xremoteclient/nsRemoteClient.h similarity index 71% rename from mozilla/widget/public/nsIXRemoteClient.idl rename to mozilla/widget/src/xremoteclient/nsRemoteClient.h index 6d35f19cbba..4a453051d17 100644 --- a/mozilla/widget/public/nsIXRemoteClient.idl +++ b/mozilla/widget/src/xremoteclient/nsRemoteClient.h @@ -1,4 +1,4 @@ -/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:expandtab:shiftwidth=4:tabstop=4: */ /* ***** BEGIN LICENSE BLOCK ***** @@ -16,12 +16,12 @@ * * The Original Code is mozilla.org code. * - * The Initial Developer of the Original Code is - * Christopher Blizzard. Portions created Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved. + * The Initial Developer of the Original Code is Christopher Blizzard. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Benjamin Smedberg * * 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 @@ -37,19 +37,25 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsISupports.idl" +#ifndef nsRemoteClient_h__ +#define nsRemoteClient_h__ -[scriptable, uuid(0bafc924-1dd2-11b2-8345-b59762ae0df7)] -interface nsIXRemoteClient : nsISupports +#include "nscore.h" + +/** + * Pure-virtual common base class for remoting implementations. + */ + +class nsRemoteClient { +public: /** * Initializes the client */ - void init(); + virtual nsresult Init() = 0; /** - * Sends a command to a running instance. If it returns false then - * there is no running instance. + * Sends a command to a running instance. * * @param aProgram This is the preferred program that we want to use * for this particular command. @@ -62,11 +68,11 @@ interface nsIXRemoteClient : nsISupports * of the server that's running under a particular username. If * this isn't specified here it's pulled from the LOGNAME * environmental variable if it's set. - + * * @param aProfile This allows you to specify a particular server * running under a named profile. If it is not specified the * profile is not checked. - + * * @param aCommand This is the command that is passed to the server. * Please see the additional information located at: * http://www.mozilla.org/unix/remote.html @@ -74,14 +80,24 @@ interface nsIXRemoteClient : nsISupports * @param aResponse If there is a response, it will be here. This * includes error messages. The string is allocated using stdlib * string functions, so free it with free(). - */ - boolean sendCommand(in string aProgram, in string aUsername, - in string aProfile, in string aCommand, - out string aResponse); + * + * @retun true if succeeded, false if no running instance was found. + */ + virtual nsresult SendCommand(const char *aProgram, const char *aUsername, + const char *aProfile, const char *aCommand, + char **aResponse, PRBool *aSucceeded) = 0; /** - * Shuts down the client + * Send a complete command line to a running instance. + * + * @see sendCommand + * @param argc The number of command-line arguments. + * */ - void shutdown(); - + virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername, + const char *aProfile, + PRInt32 argc, char **argv, + char **aResponse, PRBool *aSucceeded) = 0; }; + +#endif // nsRemoteClient_h__ diff --git a/mozilla/xpfe/bootstrap/Makefile.in b/mozilla/xpfe/bootstrap/Makefile.in index 925190b3fa9..80321aa2270 100644 --- a/mozilla/xpfe/bootstrap/Makefile.in +++ b/mozilla/xpfe/bootstrap/Makefile.in @@ -82,6 +82,7 @@ REQUIRES = xpcom \ content \ pref \ appshell \ + toolkitcomps \ appcomps \ gfx \ xpinstall \ @@ -92,6 +93,7 @@ REQUIRES = xpcom \ locale \ profile \ chrome \ + xremoteclient \ $(NULL) # for jprof REQUIRES += jprof @@ -344,6 +346,11 @@ ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH))) GARBAGE += $(STACKWALK_SRC_LCSRCS) $(wildcard *.$(OBJ_SUFFIX)) endif +ifdef MOZ_ENABLE_XREMOTE +LIBS += $(DEPTH)/widget/src/xremoteclient/$(LIB_PREFIX)xremote_client_s.$(LIB_SUFFIX) +LOCAL_INCLUDES += -I$(topsrcdir)/widget/src/xremoteclient +endif + include $(topsrcdir)/config/rules.mk ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH))) @@ -384,7 +391,7 @@ endif CXXFLAGS += $(MOZ_TOOLKIT_REGISTRY_CFLAGS) -LOCAL_INCLUDES = -I$(srcdir) -I. +LOCAL_INCLUDES += -I$(srcdir) -I. ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH))) $(MOZ_APP_NAME).1: mozilla.man.in Makefile.in Makefile $(DEPTH)/config/autoconf.mk diff --git a/mozilla/xpfe/bootstrap/nsAppRunner.cpp b/mozilla/xpfe/bootstrap/nsAppRunner.cpp index d1ed0de8e9c..913fbdc4f7e 100644 --- a/mozilla/xpfe/bootstrap/nsAppRunner.cpp +++ b/mozilla/xpfe/bootstrap/nsAppRunner.cpp @@ -103,9 +103,12 @@ // for X remote support #ifdef MOZ_ENABLE_XREMOTE -#include "nsXRemoteClientCID.h" -#include "nsIXRemoteClient.h" -#include "nsIXRemoteService.h" +#ifdef MOZ_WIDGET_PHOTON +#include "PhRemoteClient.h" +#else +#include "XRemoteClient.h" +#endif +#include "nsIRemoteService.h" #endif // see DoOnShutdown() @@ -1297,10 +1300,23 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp ) // if we have X remote support and we have our one window up and // running start listening for requests on the proxy window. // It will shut itself down before the event queue stops processing events. - nsCOMPtr remoteService; - remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID); - if (remoteService) - remoteService->Startup(MOZ_APP_NAME); + nsCOMPtr remoteService + (do_GetService("@mozilla.org/toolkit/remote-service;1")); + NS_ASSERTION(remoteService, "Couldn't create remote service?"); + if (remoteService) { + nsCAutoString pname; + + nsCOMPtr pm (do_GetService(NS_PROFILE_CONTRACTID)); + if (pm) { + nsXPIDLString name; + pm->GetCurrentProfile(getter_Copies(name)); + if (name) { + CopyUTF16toUTF8(name, pname); + } + } + + remoteService->Startup(MOZ_APP_NAME, pname.IsEmpty() ? nsnull : pname.get()); + } #endif /* MOZ_ENABLE_XREMOTE */ // remove the nativeApp as an XPCOM autoreg observer @@ -1493,13 +1509,11 @@ static int HandleRemoteArguments(int argc, char* argv[], PRBool *aArgUsed) return 0; // No remote argument == success // try to get the X remote client - nsCOMPtr client (do_CreateInstance(NS_XREMOTECLIENT_CONTRACTID)); - if (!client) - return 1; + XRemoteClient client; nsresult rv; // try to init - connects to the X server and stuff - rv = client->Init(); + rv = client.Init(); if (NS_FAILED(rv)) { PR_fprintf(PR_STDERR, "Error: Failed to connect to X server.\n"); return 1; @@ -1517,8 +1531,8 @@ static int HandleRemoteArguments(int argc, char* argv[], PRBool *aArgUsed) char *response = NULL; PRBool success = PR_FALSE; - rv = client->SendCommand(program, username, profile, remote, - &response, &success); + rv = client.SendCommand(program, username, profile, remote, + &response, &success); // did the command fail? if (NS_FAILED(rv)) { @@ -1540,7 +1554,6 @@ static int HandleRemoteArguments(int argc, char* argv[], PRBool *aArgUsed) return 2; } - client->Shutdown(); // success return 0; } diff --git a/mozilla/xpfe/bootstrap/nsStringSupport.h b/mozilla/xpfe/bootstrap/nsStringSupport.h index da9697bc622..e6e77b77481 100644 --- a/mozilla/xpfe/bootstrap/nsStringSupport.h +++ b/mozilla/xpfe/bootstrap/nsStringSupport.h @@ -95,6 +95,12 @@ NS_CopyUnicodeToNative(const nsAString &input, nsACString &output) NS_UTF16ToCString(input, NS_CSTRING_ENCODING_NATIVE_FILESYSTEM, output); } +inline void +CopyUTF16toUTF8(const nsAString &input, nsACString &output) +{ + NS_UTF16ToCString(input, NS_CSTRING_ENCODING_UTF8, output); +} + typedef nsCString nsCAutoString; typedef nsString nsAutoString; typedef nsCString nsXPIDLCString; @@ -104,6 +110,7 @@ typedef nsString nsXPIDLString; #include "nsString.h" #include "nsNativeCharsetUtils.h" +#include "nsReadableUtils.h" inline void AppendIntToString(nsCString &str, PRInt32 value) diff --git a/mozilla/xpfe/browser/resources/content/navigator.js b/mozilla/xpfe/browser/resources/content/navigator.js index f1354c1d5aa..56786edaed0 100644 --- a/mozilla/xpfe/browser/resources/content/navigator.js +++ b/mozilla/xpfe/browser/resources/content/navigator.js @@ -38,7 +38,7 @@ * * ***** END LICENSE BLOCK ***** */ -const XREMOTESERVICE_CONTRACTID = "@mozilla.org/browser/xremoteservice;1"; +const REMOTESERVICE_CONTRACTID = "@mozilla.org/toolkit/remote-service;1"; const XUL_NAMESPACE = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var gURLBar = null; var gProxyButton = null; @@ -695,11 +695,11 @@ function Startup() window.browserDOMWindow = new nsBrowserAccess(); // hook up remote support - if (XREMOTESERVICE_CONTRACTID in Components.classes) { - var remoteService; - remoteService = Components.classes[XREMOTESERVICE_CONTRACTID] - .getService(Components.interfaces.nsIXRemoteService); - remoteService.addBrowserInstance(window); + if (REMOTESERVICE_CONTRACTID in Components.classes) { + var remoteService = + Components.classes[REMOTESERVICE_CONTRACTID] + .getService(Components.interfaces.nsIRemoteService); + remoteService.registerWindow(window); var observerService = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); diff --git a/mozilla/xpfe/components/Makefile.in b/mozilla/xpfe/components/Makefile.in index 55776be9e37..e4766a71ae6 100644 --- a/mozilla/xpfe/components/Makefile.in +++ b/mozilla/xpfe/components/Makefile.in @@ -138,9 +138,11 @@ endif endif +ifndef MOZ_XUL_APP ifdef MOZ_ENABLE_XREMOTE TOOL_DIRS += xremote endif +endif ifdef MOZ_HAVE_BROWSER DIRS += build diff --git a/mozilla/xpfe/components/xremote/Makefile.in b/mozilla/xpfe/components/xremote/Makefile.in index 8c222a15404..5826c5f9f4e 100644 --- a/mozilla/xpfe/components/xremote/Makefile.in +++ b/mozilla/xpfe/components/xremote/Makefile.in @@ -43,6 +43,6 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = xremoteservice -DIRS = src +DIRS = public src include $(topsrcdir)/config/rules.mk diff --git a/mozilla/xpfe/components/xremote/public/Makefile.in b/mozilla/xpfe/components/xremote/public/Makefile.in index 6e8fa97e25d..c5f74501173 100644 --- a/mozilla/xpfe/components/xremote/public/Makefile.in +++ b/mozilla/xpfe/components/xremote/public/Makefile.in @@ -42,11 +42,11 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -MODULE = xremoteservice +MODULE = appcomps XPIDL_MODULE = xremoteservice XPIDLSRCS = \ - nsIXRemoteService.idl \ + nsISuiteRemoteService.idl \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/mozilla/widget/src/xremoteclient/nsXRemoteClientCID.h b/mozilla/xpfe/components/xremote/public/nsISuiteRemoteService.idl similarity index 60% rename from mozilla/widget/src/xremoteclient/nsXRemoteClientCID.h rename to mozilla/xpfe/components/xremote/public/nsISuiteRemoteService.idl index 05d86c10eb3..7f5cfdc2720 100644 --- a/mozilla/widget/src/xremoteclient/nsXRemoteClientCID.h +++ b/mozilla/xpfe/components/xremote/public/nsISuiteRemoteService.idl @@ -14,15 +14,16 @@ * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is - * Christopher Blizzard and Jamie Zawinski. Portions created Christopher Blizzard are Copyright (C) 2000 Christopher Blizzard. - * Portions created by the Initial Developer are Copyright (C) 1994 + * Christopher Blizzard . + * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Benjamin Smedberg * * 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"), + * either of 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 @@ -34,5 +35,27 @@ * * ***** END LICENSE BLOCK ***** */ -#define NS_XREMOTECLIENT_CONTRACTID \ - "@mozilla.org/xremote_client;1" +#include "nsISupports.idl" + +interface nsIDOMWindow; + +/** + * Responds to incoming xremote requests for the mozilla suite. + */ + +[scriptable, uuid(52add212-2067-4575-8d26-edd5165179b1)] +interface nsISuiteRemoteService : nsISupports +{ + /** + * Parse the command given. + * + * @param aCommand The command string, e.g. "openURL(http://www.foo.com/)" + * @param aContext The domwindow to target the command at. May be null, and + * may be ignored. + */ + void parseCommand (in string aCommand, in nsIDOMWindow aContext); +}; + +%{C++ +#define NS_SUITEREMOTESERVICE_CONTRACTID "@mozilla.org/browser/xremoteservice;2" +%} diff --git a/mozilla/xpfe/components/xremote/src/Makefile.in b/mozilla/xpfe/components/xremote/src/Makefile.in index 3f67d25fec8..4023ad9cc5c 100644 --- a/mozilla/xpfe/components/xremote/src/Makefile.in +++ b/mozilla/xpfe/components/xremote/src/Makefile.in @@ -42,7 +42,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -MODULE = xremoteservice +MODULE = appcomps LIBRARY_NAME = xremoteservice EXPORT_LIBRARY = 1 IS_COMPONENT = 1 @@ -54,7 +54,6 @@ REQUIRES = xpcom \ string \ dom \ widget \ - gfx \ uriloader \ docshell \ pref \ @@ -74,5 +73,6 @@ CPPSRCS = \ include $(topsrcdir)/config/rules.mk -EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) - +EXTRA_DSO_LDOPTS += \ + $(MOZ_COMPONENT_LIBS) \ + $(NULL) diff --git a/mozilla/xpfe/components/xremote/src/XRemoteService.cpp b/mozilla/xpfe/components/xremote/src/XRemoteService.cpp index e4f75b1039d..9aef9e7ded3 100644 --- a/mozilla/xpfe/components/xremote/src/XRemoteService.cpp +++ b/mozilla/xpfe/components/xremote/src/XRemoteService.cpp @@ -48,11 +48,7 @@ #include #include #include -#include -#include #include -#include -#include #include #include #include @@ -74,117 +70,41 @@ #include #include -#ifdef MOZ_XUL_APP -#include "nsICommandLineRunner.h" -#else #include "nsICmdLineHandler.h" -#endif - -NS_DEFINE_CID(kWindowCID, NS_WINDOW_CID); - -// protocol strings -static const char s200ExecutedCommand[] = "200 executed command:"; -static const char s500ParseCommand[] = "500 command not parsable:"; -static const char s501UnrecognizedCommand[] = "501 unrecognized command:"; -// not used -//static const char s502NoWindow[] = "502 no appropriate window for:"; -static const char s509InternalError[] = "509 internal error"; XRemoteService::XRemoteService() { - mNumWindows = 0; - mRunning = PR_FALSE; } XRemoteService::~XRemoteService() { - Shutdown(); } -NS_IMPL_ISUPPORTS2(XRemoteService, nsIXRemoteService, nsIObserver) +NS_IMPL_ISUPPORTS1(XRemoteService, nsISuiteRemoteService) NS_IMETHODIMP -XRemoteService::Startup(const char *aProgram) +XRemoteService::ParseCommand(const char *aCommand, nsIDOMWindow* aWindow) { - // We have to destroy the proxy window before the event loop stops running. - nsCOMPtr obsServ = - do_GetService("@mozilla.org/observer-service;1"); - obsServ->AddObserver(this, "quit-application", PR_FALSE); - obsServ->AddObserver(this, "profile-after-change", PR_FALSE); - - mProgram.Assign(aProgram); - - // Normalize program names to lowercase. - ToLowerCase(mProgram); - - mRunning = PR_TRUE; - if (mNumWindows == 0) - CreateProxyWindow(); - return NS_OK; -} - -NS_IMETHODIMP -XRemoteService::Shutdown(void) -{ - DestroyProxyWindow(); - mRunning = PR_FALSE; - return NS_OK; -} - -NS_IMETHODIMP -XRemoteService::Observe(nsISupports *aSubject, const char *aTopic, - const PRUnichar *aData) -{ - if (!strcmp(aTopic, "quit-application")) { - Shutdown(); - } else { - NS_NOTREACHED("unexpected topic"); - return NS_ERROR_UNEXPECTED; - } - - return NS_OK; -} - -NS_IMETHODIMP -XRemoteService::ParseCommand(nsIWidget *aWidget, - const char *aCommand, char **aResponse) -{ - if (!aCommand || !aResponse) - return NS_ERROR_INVALID_ARG; - - // is there no command? - if (aCommand[0] == '\0') { - *aResponse = nsCRT::strdup(s509InternalError); - return NS_OK; - } - - *aResponse = nsnull; + NS_ASSERTION(aCommand, "Tell me what to do, or shut up!"); // begin our parse - nsCString tempString; - PRInt32 begin_arg = 0; - PRInt32 end_arg = 0; + nsCString tempString(aCommand); - tempString.Append(aCommand); - // find the () in the command - begin_arg = tempString.FindChar('('); - end_arg = tempString.RFindChar(')'); + PRInt32 begin_arg = tempString.FindChar('('); + PRInt32 end_arg = tempString.RFindChar(')'); // make sure that both were found, the string doesn't start with '(' // and that the ')' follows the '(' if (begin_arg == kNotFound || end_arg == kNotFound || - begin_arg == 0 || end_arg < begin_arg) { - *aResponse = BuildResponse(s500ParseCommand, aCommand); - return NS_OK; - } + begin_arg == 0 || end_arg < begin_arg) + return NS_ERROR_INVALID_ARG; // truncate the closing paren and anything following it tempString.Truncate(end_arg); // save the argument and trim whitespace off of it - nsCString argument; - argument.Append(tempString); + nsCString argument(tempString); argument.Cut(0, begin_arg + 1); argument.Trim(" ", PR_TRUE, PR_TRUE); @@ -192,8 +112,7 @@ XRemoteService::ParseCommand(nsIWidget *aWidget, tempString.Truncate(begin_arg); // get the action, strip off whitespace and convert to lower case - nsCString action; - action.Append(tempString); + nsCString action(tempString); action.Trim(" ", PR_TRUE, PR_TRUE); ToLowerCase(action); @@ -210,17 +129,6 @@ XRemoteService::ParseCommand(nsIWidget *aWidget, nsresult rv = NS_OK; - // find the DOM window for the passed in parameter - nsVoidKey *key; - key = new nsVoidKey(aWidget); - if (!key) - return NS_ERROR_FAILURE; - // If this fails it's OK since it just means that we got a request - // on an unknown window. We can handle that case. - nsIDOMWindowInternal *domWindow = NS_STATIC_CAST(nsIDOMWindowInternal *, - mWindowList.Get(key)); - delete key; - /* openURL ( ) Prompts for a URL with a dialog box. @@ -240,9 +148,9 @@ XRemoteService::ParseCommand(nsIWidget *aWidget, if (action.Equals("openurl") || action.Equals("openfile")) { if (argument.IsEmpty()) - rv = OpenURLDialog(domWindow); + rv = OpenURLDialog(aWindow); else - rv = OpenURL(argument, domWindow, PR_TRUE); + rv = OpenURL(argument, aWindow, PR_TRUE); } /* @@ -296,7 +204,7 @@ XRemoteService::ParseCommand(nsIWidget *aWidget, // and openurl should work fine. nsCString tempArg("mailto:"); tempArg.Append(argument); - rv = OpenURL(tempArg, domWindow, PR_FALSE); + rv = OpenURL(tempArg, aWindow, PR_FALSE); } /* @@ -310,21 +218,7 @@ XRemoteService::ParseCommand(nsIWidget *aWidget, */ else if (action.Equals("addbookmark")) { - if (argument.IsEmpty()) { - rv = NS_ERROR_NOT_IMPLEMENTED; - } - else { - index = 0; - FindLastInList(argument, lastArgument, &index); - if (!lastArgument.IsEmpty()) { - nsCString title(lastArgument); - argument.Truncate(index); - rv = NS_ERROR_NOT_IMPLEMENTED; - } - else { - rv = NS_ERROR_NOT_IMPLEMENTED; - } - } + rv = NS_ERROR_NOT_IMPLEMENTED; } /* some extensions! */ @@ -346,227 +240,17 @@ XRemoteService::ParseCommand(nsIWidget *aWidget, */ else if (action.Equals("xfedocommand")) { - rv = XfeDoCommand(argument, domWindow); + rv = XfeDoCommand(argument, aWindow); } // bad command else { rv = NS_ERROR_FAILURE; - *aResponse = BuildResponse(s501UnrecognizedCommand, aCommand); } - // if we failed and *aResponse isn't already filled in, fill it in - // with a generic internal error message. - if (NS_FAILED(rv)) { - if (!*aResponse) { - if (rv == NS_ERROR_NOT_IMPLEMENTED) - *aResponse = BuildResponse(s501UnrecognizedCommand, aCommand); - else - *aResponse = nsCRT::strdup(s509InternalError); - } - } - - // if we got this far then everything worked. - if (!*aResponse) - *aResponse = BuildResponse(s200ExecutedCommand, aCommand); - return rv; } -NS_IMETHODIMP -XRemoteService::AddBrowserInstance(nsIDOMWindowInternal *aBrowser) -{ - - // get the native window for this instance - nsCOMPtr scriptObject; - scriptObject = do_QueryInterface(aBrowser); - if (!scriptObject) { - NS_WARNING("Failed to get script object for browser instance"); - return NS_ERROR_FAILURE; - } - - nsCOMPtr baseWindow; - baseWindow = do_QueryInterface(scriptObject->GetDocShell()); - if (!baseWindow) { - NS_WARNING("Failed to get base window for browser instance"); - return NS_ERROR_FAILURE; - } - - nsCOMPtr mainWidget; - baseWindow->GetMainWidget(getter_AddRefs(mainWidget)); - if (!mainWidget) { - NS_WARNING("Failed to get main widget for browser instance"); - return NS_ERROR_FAILURE; - } - - // walk up the widget tree and find the toplevel window in the - // hierarchy - - nsCOMPtr tempWidget; - - tempWidget = getter_AddRefs(mainWidget->GetParent()); - - while (tempWidget) { - tempWidget = getter_AddRefs(tempWidget->GetParent()); - if (tempWidget) - mainWidget = tempWidget; - } - - // Tell the widget code to set up X remote for this window - nsCOMPtr widgetHelper = - do_GetService(NS_IXREMOTEWIDGETHELPER_CONTRACTID); - if (!widgetHelper) { - NS_WARNING("couldn't get widget helper service"); - return NS_ERROR_FAILURE; - } - - - nsCAutoString profile; - GetProfileName(profile); - - // Make sure that the profile is actually set to something. - const char *profileTmp = NULL; - if (profile.Length()) - profileTmp = profile.get(); - - // Make sure we actually have a name. - const char *programTmp = NULL; - if (!mProgram.IsEmpty()) - programTmp = mProgram.get(); - - nsresult rv; - rv = widgetHelper->EnableXRemoteCommands(mainWidget, profileTmp, - programTmp); - if (NS_FAILED(rv)) { - NS_WARNING("failed to enable x remote commands for widget"); - return rv; - } - - // It's assumed that someone will call RemoveBrowserInstance before - // this DOM window is destroyed so we don't addref or release or - // keep a weak ptr or anything. - nsVoidKey *key; - key = new nsVoidKey (mainWidget.get()); - if (!key) - return NS_ERROR_FAILURE; - mWindowList.Put(key, aBrowser); - delete key; - - // ...and the reverse lookup - key = new nsVoidKey (aBrowser); - if (!key) - return NS_ERROR_FAILURE; - mBrowserList.Put(key, mainWidget.get()); - delete key; - - // now that we have a real browser window listening to requests - // destroy the proxy window. - DestroyProxyWindow(); - mNumWindows++; - - return NS_OK; -} - -NS_IMETHODIMP -XRemoteService::RemoveBrowserInstance(nsIDOMWindowInternal *aBrowser) -{ - mNumWindows--; - if (mNumWindows == 0 && mRunning) - CreateProxyWindow(); - - // remove our keys - nsVoidKey *key; - key = new nsVoidKey(aBrowser); - if (!key) - return NS_ERROR_FAILURE; - nsIWidget *widget = NS_STATIC_CAST(nsIWidget *, - mBrowserList.Remove(key)); - delete key; - - key = new nsVoidKey(widget); - if (!key) - return NS_ERROR_FAILURE; - mWindowList.Remove(key); - delete key; - - return NS_OK; -} - -void -XRemoteService::CreateProxyWindow(void) -{ - if (mProxyWindow) - return; - - mProxyWindow = do_CreateInstance(kWindowCID); - if (!mProxyWindow) - return; - - nsWidgetInitData initData; - initData.mWindowType = eWindowType_toplevel; - initData.mContentType = eContentTypeUI; - - // create the window as a new toplevel - nsRect rect(0,0,100,100); - nsresult rv; - rv = mProxyWindow->Create(NS_STATIC_CAST(nsIWidget *, nsnull), - rect, - nsnull, nsnull, nsnull, nsnull, - &initData); - if (NS_FAILED(rv)) { - NS_WARNING("Failed to create proxy window"); - return; - } - - // Tell the widget code to set up X remote for this window - nsCOMPtr widgetHelper = - do_GetService(NS_IXREMOTEWIDGETHELPER_CONTRACTID); - if (!widgetHelper) { - NS_WARNING("couldn't get widget helper service"); - return; - } - - nsCAutoString profile; - GetProfileName(profile); - - rv = widgetHelper->EnableXRemoteCommands(mProxyWindow, profile.get(), - mProgram.get()); - if (NS_FAILED(rv)) { - NS_WARNING("failed to enable x remote commands for proxy window"); - return; - } - -} - -void -XRemoteService::DestroyProxyWindow(void) -{ - if (!mProxyWindow) - return; - - mProxyWindow->Destroy(); - mProxyWindow = nsnull; -} - -char * -XRemoteService::BuildResponse(const char *aError, const char *aMessage) -{ - nsCString retvalString; - char *retval; - - // check to make sure that we have the minimum for allocating this - // buffer - if (!aError || !aMessage) - return nsnull; - - retvalString.Append(aError); - retvalString.Append(" "); - retvalString.Append(aMessage); - - retval = ToNewCString(retvalString); - return retval; -} - void XRemoteService::FindRestInList(nsCString &aString, nsCString &retString, PRUint32 *aIndexRet) @@ -760,11 +444,11 @@ XRemoteService::MayOpenURL(const nsCString &aURL) nsresult XRemoteService::OpenURL(nsCString &aArgument, - nsIDOMWindowInternal *aParent, + nsIDOMWindow *aParent, PRBool aOpenBrowser) { // the eventual toplevel target of the load - nsCOMPtr finalWindow = aParent; + nsCOMPtr finalWindow = do_QueryInterface(aParent); // see if there's a new-window or new-tab argument on the end nsCString lastArgument; @@ -794,10 +478,6 @@ XRemoteService::OpenURL(nsCString &aArgument, // If we're trying to open a new tab, we'll fall back to opening // a new window if there's no browser window open, so look for it // here. -#ifdef MOZ_THUNDERBIRD - newWindow = PR_FALSE; - finalWindow = nsnull; // always use the URILoader code below -#else if (aOpenBrowser && (!newWindow || newTab)) { nsCOMPtr lastUsedWindow; FindWindow(NS_LITERAL_STRING("navigator:browser").get(), @@ -819,7 +499,6 @@ XRemoteService::OpenURL(nsCString &aArgument, if (!finalWindow || !bwin) newWindow = PR_TRUE; } -#endif // check if we can handle this type of URL if (!MayOpenURL(aArgument)) @@ -966,7 +645,7 @@ XRemoteService::OpenURL(nsCString &aArgument, } nsresult -XRemoteService::OpenURLDialog(nsIDOMWindowInternal *aParent) +XRemoteService::OpenURLDialog(nsIDOMWindow *aParent) { nsresult rv; @@ -1002,7 +681,7 @@ XRemoteService::OpenURLDialog(nsIDOMWindowInternal *aParent) nsresult XRemoteService::XfeDoCommand(nsCString &aArgument, - nsIDOMWindowInternal *aParent) + nsIDOMWindow *aParent) { nsresult rv = NS_OK; @@ -1029,7 +708,7 @@ XRemoteService::XfeDoCommand(nsCString &aArgument, nsCOMPtr domWindow; rv = FindWindow(NS_LITERAL_STRING("mail:3pane").get(), - getter_AddRefs(domWindow)); + getter_AddRefs(domWindow)); if (NS_FAILED(rv)) return rv; @@ -1055,19 +734,6 @@ XRemoteService::XfeDoCommand(nsCString &aArgument, // open a new browser window else if (aArgument.LowerCaseEqualsLiteral("openbrowser")) { -#ifdef MOZ_XUL_APP - char* argc = "-browser"; - - nsCOMPtr cmdLine - (do_GetService("@mozilla.org/toolkit/command-line;1")); - NS_ENSURE_TRUE(cmdLine, NS_ERROR_FAILURE); - - rv = cmdLine->Init(1, &argc, nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT); - NS_ENSURE_SUCCESS(rv, rv); - - rv = cmdLine->Run(); - -#else // Get the browser URL and the default start page URL. nsCOMPtr browserHandler = do_GetService("@mozilla.org/commandlinehandler/general-startup;1?type=browser"); @@ -1086,7 +752,6 @@ XRemoteService::XfeDoCommand(nsCString &aArgument, nsCOMPtr newWindow; rv = OpenChromeWindow(0, browserLocation, "chrome,all,dialog=no", arg, getter_AddRefs(newWindow)); -#endif } // open a new compose window @@ -1109,17 +774,17 @@ XRemoteService::XfeDoCommand(nsCString &aArgument, else if (aArgument.LowerCaseEqualsLiteral("opencalendar")) { // check to see if it's already running - nsCOMPtr domWindow; + nsCOMPtr aWindow; rv = FindWindow(NS_LITERAL_STRING("calendarMainWindow").get(), - getter_AddRefs(domWindow)); + getter_AddRefs(aWindow)); if (NS_FAILED(rv)) return rv; // focus the window if it was found - if (domWindow) { - domWindow->Focus(); + if (aWindow) { + aWindow->Focus(); } // otherwise open a new calendar window @@ -1151,28 +816,12 @@ XRemoteService::FindWindow(const PRUnichar *aType, return mediator->GetMostRecentWindow(aType, _retval); } -void -XRemoteService::GetProfileName(nsACString &aProfile) -{ - // Get the current profile name and save it. - nsresult rv; - nsCOMPtr profileMgr; - profileMgr = do_GetService(NS_PROFILE_CONTRACTID, &rv); - if (!profileMgr) - return; - - nsXPIDLString name; - rv = profileMgr->GetCurrentProfile(getter_Copies(name)); - if (NS_SUCCEEDED(rv)) - LossyCopyUTF16toASCII(name, aProfile); -} - NS_GENERIC_FACTORY_CONSTRUCTOR(XRemoteService) static const nsModuleComponentInfo components[] = { - { NS_IXREMOTESERVICE_CLASSNAME, + { "XRemoteService", NS_XREMOTESERVICE_CID, - NS_IXREMOTESERVICE_CONTRACTID, + "@mozilla.org/browser/xremoteservice;2", XRemoteServiceConstructor } }; diff --git a/mozilla/xpfe/components/xremote/src/XRemoteService.h b/mozilla/xpfe/components/xremote/src/XRemoteService.h index 13223b2aa6e..4f034903688 100644 --- a/mozilla/xpfe/components/xremote/src/XRemoteService.h +++ b/mozilla/xpfe/components/xremote/src/XRemoteService.h @@ -19,6 +19,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Benjamin Smedberg * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -34,12 +35,12 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsIXRemoteService.h" -#include "nsHashtable.h" -#include "nsIDOMWindow.h" -#include "nsIWidget.h" +#include "nsISuiteRemoteService.h" + #include "nsCOMPtr.h" -#include "nsIObserver.h" +#include "nsString.h" + +class nsIDOMWindowInternal; // {3dfe7324-1dd2-11b2-9ff2-8853f91e8a20} @@ -47,7 +48,8 @@ { 0x3dfe7324, 0x1dd2, 0x11b2, \ { 0x9f, 0xf2, 0x88, 0x53, 0xf9, 0x1e, 0x8a, 0x20 } } -class XRemoteService : public nsIXRemoteService, public nsIObserver { +class XRemoteService : public nsISuiteRemoteService +{ public: XRemoteService(); virtual ~XRemoteService(); @@ -56,18 +58,9 @@ class XRemoteService : public nsIXRemoteService, public nsIObserver { NS_DECL_ISUPPORTS - NS_DECL_NSIXREMOTESERVICE - NS_DECL_NSIOBSERVER + NS_DECL_NSISUITEREMOTESERVICE private: - - // create and destroy the proxy window - void CreateProxyWindow(); - void DestroyProxyWindow(); - - // this builds a response for any parsing - char *BuildResponse(const char *aError, const char *aMessage); - // find the last argument in an argument string void FindLastInList(nsCString &aString, nsCString &retString, PRUint32 *aIndexRet); @@ -94,36 +87,16 @@ class XRemoteService : public nsIXRemoteService, public nsIObserver { // remote command handlers nsresult OpenURL(nsCString &aArgument, - nsIDOMWindowInternal *aParent, - PRBool aOpenBrowser); + nsIDOMWindow* aParent, + PRBool aOpenBrowser); - nsresult OpenURLDialog(nsIDOMWindowInternal *aParent); + nsresult OpenURLDialog(nsIDOMWindow* aParent); // handle xfe commands nsresult XfeDoCommand(nsCString &aArgument, - nsIDOMWindowInternal *aParent); + nsIDOMWindow* aParent); // find the most recent window of a certain type nsresult FindWindow(const PRUnichar *aType, - nsIDOMWindowInternal **_retval); - - // Save the profile name - void GetProfileName(nsACString &aProfile); - - // hidden window for proxy requests - nsCOMPtr mProxyWindow; - - // native window to internal dom window map - nsHashtable mWindowList; - // internal dom window to native window map - nsHashtable mBrowserList; - - // the number of non-proxy windows that are set up for X Remote - PRUint32 mNumWindows; - - // have we been started up from the main loop yet? - PRBool mRunning; - - // Name of our program - nsCString mProgram; + nsIDOMWindowInternal **_retval); };