Bug 280725 - use generic/automatic remoting for xremote r=caillon sr=bryner
This commit is contained in:
Родитель
985bf5fe92
Коммит
2d9f9646a3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(<url>)
|
||||
// openURL(<url>,new-window)
|
||||
// openURL(<url>,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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -49,7 +49,6 @@ DIRS = \
|
|||
obsolete \
|
||||
profile \
|
||||
xre \
|
||||
components \
|
||||
mozapps \
|
||||
themes \
|
||||
$(NULL)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
* Smedberg <benjamin@smedbergs.us>.
|
||||
*/
|
||||
|
||||
[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.
|
||||
|
|
|
@ -58,6 +58,7 @@ REQUIRES = \
|
|||
string \
|
||||
necko \
|
||||
unicharutil \
|
||||
dom \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -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<nsIFile> mWorkingDir;
|
||||
nsCOMPtr<nsIDOMWindow> 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)
|
||||
{
|
||||
|
|
|
@ -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 <blizzard@mozilla.org>.
|
||||
# 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
|
|
@ -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 <blizzard@mozilla.org>
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 <X11/Xatom.h> // for XA_STRING
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtkinvisible.h> // For some reason GTK+ doesn't include this file
|
||||
// automatically from gtk.h
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#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<nsIObserverService> 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<nsIScriptGlobalObject> scriptObject
|
||||
(do_QueryInterface(aWindow));
|
||||
NS_ENSURE_TRUE(scriptObject, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow
|
||||
(do_QueryInterface(scriptObject->GetDocShell()));
|
||||
NS_ENSURE_TRUE(baseWindow, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIWidget> 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<nsIWidget> 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<nsIWeakReference> 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<nsISuiteRemoteService> 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<nsICommandLineRunner> 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<nsICommandLineRunner> 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...]<workingdir>\0<argv[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<nsILocalFile> 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<nsIDOMWindow> 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)
|
|
@ -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 <blizzard@mozilla.org>
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#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<nsVoidPtrHashKey, nsIWeakReference> 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__
|
|
@ -0,0 +1,78 @@
|
|||
/* ***** 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 <blizzard@mozilla.org>. 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):
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
/**
|
||||
* 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(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);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<nsIXRemoteClient> 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<nsIProfileLock> 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<nsIXRemoteService> remoteService;
|
||||
remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID);
|
||||
nsCOMPtr<nsIRemoteService> 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -94,9 +94,5 @@ ifdef MOZ_ENABLE_PHOTON
|
|||
DIRS += photon
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_XREMOTE
|
||||
DIRS += xremoteclient
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
#include "nsGtkKeyUtils.h"
|
||||
#include "nsGtkCursors.h"
|
||||
#include "nsGtkMozRemoteHelper.h"
|
||||
|
||||
#include <gtk/gtkwindow.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -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...]<workingdir>\0<argv[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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,24 +37,23 @@
|
|||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <plgetopt.h>
|
||||
#ifdef MOZ_WIDGET_PHOTON
|
||||
#include "PhRemoteClient.h"
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 nsRemoteClient_h__
|
||||
#define nsRemoteClient_h__
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
/**
|
||||
* Pure-virtual common base class for remoting implementations.
|
||||
*/
|
||||
|
||||
class nsRemoteClient
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes the client
|
||||
*/
|
||||
virtual nsresult Init() = 0;
|
||||
|
||||
/**
|
||||
* Sends a command to a running instance.
|
||||
*
|
||||
* @param aProgram This is the preferred program that we want to use
|
||||
* for this particular command.
|
||||
*
|
||||
* @param aNoProgramFallback This boolean attribute tells the client
|
||||
* code that if the preferred program isn't found that it should
|
||||
* fail not send the command to another server.
|
||||
*
|
||||
* @param aUsername This allows someone to only talk to an instance
|
||||
* 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
|
||||
*
|
||||
* @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().
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Send a complete command line to a running instance.
|
||||
*
|
||||
* @see sendCommand
|
||||
* @param argc The number of command-line arguments.
|
||||
*
|
||||
*/
|
||||
virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername,
|
||||
const char *aProfile,
|
||||
PRInt32 argc, char **argv,
|
||||
char **aResponse, PRBool *aSucceeded) = 0;
|
||||
};
|
||||
|
||||
#endif // nsRemoteClient_h__
|
|
@ -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
|
||||
|
|
|
@ -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<nsIXRemoteService> remoteService;
|
||||
remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID);
|
||||
if (remoteService)
|
||||
remoteService->Startup(MOZ_APP_NAME);
|
||||
nsCOMPtr<nsIRemoteService> remoteService
|
||||
(do_GetService("@mozilla.org/toolkit/remote-service;1"));
|
||||
NS_ASSERTION(remoteService, "Couldn't create remote service?");
|
||||
if (remoteService) {
|
||||
nsCAutoString pname;
|
||||
|
||||
nsCOMPtr<nsIProfile> 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<nsIXRemoteClient> 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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -43,6 +43,6 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xremoteservice
|
||||
DIRS = src
|
||||
DIRS = public src
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* ***** 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 <blizzard@mozilla.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#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"
|
||||
%}
|
|
@ -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)
|
||||
|
|
|
@ -48,11 +48,7 @@
|
|||
#include <nsIDocShell.h>
|
||||
#include <nsIScriptGlobalObject.h>
|
||||
#include <nsIBaseWindow.h>
|
||||
#include <nsWidgetsCID.h>
|
||||
#include <nsIXRemoteWidgetHelper.h>
|
||||
#include <nsIServiceManager.h>
|
||||
#include <nsIObserverService.h>
|
||||
#include <nsRect.h>
|
||||
#include <nsString.h>
|
||||
#include <nsCRT.h>
|
||||
#include <nsIPref.h>
|
||||
|
@ -74,117 +70,41 @@
|
|||
#include <nsIExternalProtocolService.h>
|
||||
#include <nsIProfile.h>
|
||||
|
||||
#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<nsIObserverService> 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<nsIScriptGlobalObject> scriptObject;
|
||||
scriptObject = do_QueryInterface(aBrowser);
|
||||
if (!scriptObject) {
|
||||
NS_WARNING("Failed to get script object for browser instance");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow;
|
||||
baseWindow = do_QueryInterface(scriptObject->GetDocShell());
|
||||
if (!baseWindow) {
|
||||
NS_WARNING("Failed to get base window for browser instance");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> 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<nsIWidget> 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<nsIXRemoteWidgetHelper> 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<nsIXRemoteWidgetHelper> 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<nsIDOMWindowInternal> finalWindow = aParent;
|
||||
nsCOMPtr<nsIDOMWindowInternal> 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<nsIDOMWindowInternal> 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<nsIDOMWindowInternal> 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<nsICommandLineRunner> 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<nsICmdLineHandler> browserHandler =
|
||||
do_GetService("@mozilla.org/commandlinehandler/general-startup;1?type=browser");
|
||||
|
@ -1086,7 +752,6 @@ XRemoteService::XfeDoCommand(nsCString &aArgument,
|
|||
nsCOMPtr<nsIDOMWindow> 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<nsIDOMWindowInternal> domWindow;
|
||||
nsCOMPtr<nsIDOMWindowInternal> 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<nsIProfile> 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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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<nsIWidget> 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);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче