From a87bed13429b22508503737c0f47c3ac9973210e Mon Sep 17 00:00:00 2001 From: "svn%xmlterm.org" Date: Mon, 6 Dec 1999 06:32:12 +0000 Subject: [PATCH] Initial import of XMLterm extension; not part of default SeaMonkey build git-svn-id: svn://10.0.0.236/trunk@55405 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/extensions/xmlterm/INSTALL | 170 ++ mozilla/extensions/xmlterm/Makefile.in | 78 + mozilla/extensions/xmlterm/README | 63 + mozilla/extensions/xmlterm/UUID.txt | 28 + mozilla/extensions/xmlterm/base/Makefile.in | 120 + mozilla/extensions/xmlterm/base/README | 127 + mozilla/extensions/xmlterm/base/lineterm.h | 387 +++ mozilla/extensions/xmlterm/base/ltermEscape.c | 1029 +++++++ mozilla/extensions/xmlterm/base/ltermIO.c | 1113 ++++++++ mozilla/extensions/xmlterm/base/ltermInput.c | 829 ++++++ .../extensions/xmlterm/base/ltermManager.c | 1190 ++++++++ mozilla/extensions/xmlterm/base/ltermOutput.c | 895 ++++++ .../extensions/xmlterm/base/ltermPrivate.h | 560 ++++ .../extensions/xmlterm/base/mozILineTerm.idl | 88 + .../extensions/xmlterm/base/mozILineTermAux.h | 122 + .../xmlterm/base/mozIXMLTermShell.idl | 86 + .../xmlterm/base/mozIXMLTermStream.h | 78 + .../extensions/xmlterm/base/mozIXMLTerminal.h | 127 + .../extensions/xmlterm/base/mozLineTerm.cpp | 681 +++++ mozilla/extensions/xmlterm/base/mozLineTerm.h | 139 + mozilla/extensions/xmlterm/base/mozXMLT.h | 67 + .../xmlterm/base/mozXMLTermFactory.cpp | 298 ++ .../xmlterm/base/mozXMLTermListeners.cpp | 604 ++++ .../xmlterm/base/mozXMLTermListeners.h | 172 ++ .../xmlterm/base/mozXMLTermSession.cpp | 2515 +++++++++++++++++ .../xmlterm/base/mozXMLTermSession.h | 537 ++++ .../xmlterm/base/mozXMLTermShell.cpp | 326 +++ .../extensions/xmlterm/base/mozXMLTermShell.h | 81 + .../xmlterm/base/mozXMLTermStream.cpp | 568 ++++ .../xmlterm/base/mozXMLTermStream.h | 96 + .../xmlterm/base/mozXMLTermUtils.cpp | 454 +++ .../extensions/xmlterm/base/mozXMLTermUtils.h | 145 + .../xmlterm/base/mozXMLTerminal.cpp | 770 +++++ .../extensions/xmlterm/base/mozXMLTerminal.h | 153 + mozilla/extensions/xmlterm/base/ptystream.c | 512 ++++ mozilla/extensions/xmlterm/base/ptystream.h | 92 + mozilla/extensions/xmlterm/base/tracelog.c | 205 ++ mozilla/extensions/xmlterm/base/tracelog.h | 154 + mozilla/extensions/xmlterm/base/unistring.c | 186 ++ mozilla/extensions/xmlterm/base/unistring.h | 277 ++ mozilla/extensions/xmlterm/config/README | 1 + mozilla/extensions/xmlterm/config/autoconf.mk | 47 + mozilla/extensions/xmlterm/config/config.mk | 93 + mozilla/extensions/xmlterm/config/rules.mk | 157 + .../xmlterm/config/xmlterm_config.mk | 102 + mozilla/extensions/xmlterm/dist/README | 1 + mozilla/extensions/xmlterm/doc/BUGS | 9 + mozilla/extensions/xmlterm/doc/FinalizeXPCOM | 31 + .../extensions/xmlterm/doc/INSTALL.xmlterm | 60 + mozilla/extensions/xmlterm/doc/Implementation | 28 + mozilla/extensions/xmlterm/doc/MPL | 602 ++++ mozilla/extensions/xmlterm/doc/Portability | 36 + mozilla/extensions/xmlterm/doc/README | 12 + mozilla/extensions/xmlterm/doc/SlowDOMBug | 22 + .../extensions/xmlterm/doc/XMLterm_LICENSE | 19 + .../extensions/xmlterm/doc/lineterm_LICENSE | 31 + .../extensions/xmlterm/geckoterm/Makefile.in | 109 + mozilla/extensions/xmlterm/geckoterm/README | 24 + .../xmlterm/geckoterm/default_prefs.js | 3 + .../xmlterm/geckoterm/default_prefs.js.sav | 5 + .../xmlterm/geckoterm/mozGeckoTerm.cpp | 337 +++ .../xmlterm/geckoterm/mozGeckoTerm.cpp.sav | 318 +++ .../xmlterm/geckoterm/mozISimpleContainer.h | 134 + .../xmlterm/geckoterm/mozSimpleContainer.cpp | 396 +++ .../xmlterm/geckoterm/mozSimpleContainer.h | 100 + .../xmlterm/geckoterm/nsSetupRegistry.cpp | 23 + .../extensions/xmlterm/geckoterm/nsTimer.cpp | 198 ++ mozilla/extensions/xmlterm/geckoterm/remake | 8 + .../extensions/xmlterm/linetest/Makefile.in | 65 + mozilla/extensions/xmlterm/linetest/README | 1 + mozilla/extensions/xmlterm/linetest/lterm.c | 557 ++++ mozilla/extensions/xmlterm/linetest/ptytest.c | 366 +++ mozilla/extensions/xmlterm/linetest/remake | 7 + .../extensions/xmlterm/linetest/temncurses.c | 32 + .../extensions/xmlterm/linetest/testunistr.c | 138 + mozilla/extensions/xmlterm/makemake | 34 + mozilla/extensions/xmlterm/tests/DocStream.c | 45 + mozilla/extensions/xmlterm/tests/HelloWorld.c | 40 + mozilla/extensions/xmlterm/tests/Makefile.in | 67 + mozilla/extensions/xmlterm/tests/README | 1 + mozilla/extensions/xmlterm/tests/escape.c | 56 + mozilla/extensions/xmlterm/tests/teststream.c | 20 + mozilla/extensions/xmlterm/tests/xls | 84 + mozilla/extensions/xmlterm/tests/xls.csh | 81 + mozilla/extensions/xmlterm/ui/Makefile.in | 57 + mozilla/extensions/xmlterm/ui/README | 1 + .../extensions/xmlterm/ui/content/Makefile.in | 61 + mozilla/extensions/xmlterm/ui/content/README | 5 + .../xmlterm/ui/content/xmlterm.html | 239 ++ .../extensions/xmlterm/ui/skin/Makefile.in | 66 + mozilla/extensions/xmlterm/ui/skin/README | 5 + .../extensions/xmlterm/ui/skin/images/README | 1 + .../xmlterm/ui/skin/images/ficon.gif | Bin 0 -> 161 bytes .../extensions/xmlterm/ui/skin/xmlterm.css | 19 + 94 files changed, 21076 insertions(+) create mode 100644 mozilla/extensions/xmlterm/INSTALL create mode 100644 mozilla/extensions/xmlterm/Makefile.in create mode 100644 mozilla/extensions/xmlterm/README create mode 100644 mozilla/extensions/xmlterm/UUID.txt create mode 100644 mozilla/extensions/xmlterm/base/Makefile.in create mode 100644 mozilla/extensions/xmlterm/base/README create mode 100644 mozilla/extensions/xmlterm/base/lineterm.h create mode 100644 mozilla/extensions/xmlterm/base/ltermEscape.c create mode 100644 mozilla/extensions/xmlterm/base/ltermIO.c create mode 100644 mozilla/extensions/xmlterm/base/ltermInput.c create mode 100644 mozilla/extensions/xmlterm/base/ltermManager.c create mode 100644 mozilla/extensions/xmlterm/base/ltermOutput.c create mode 100644 mozilla/extensions/xmlterm/base/ltermPrivate.h create mode 100644 mozilla/extensions/xmlterm/base/mozILineTerm.idl create mode 100644 mozilla/extensions/xmlterm/base/mozILineTermAux.h create mode 100644 mozilla/extensions/xmlterm/base/mozIXMLTermShell.idl create mode 100644 mozilla/extensions/xmlterm/base/mozIXMLTermStream.h create mode 100644 mozilla/extensions/xmlterm/base/mozIXMLTerminal.h create mode 100644 mozilla/extensions/xmlterm/base/mozLineTerm.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozLineTerm.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLT.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermFactory.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermListeners.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermListeners.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermSession.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermSession.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermShell.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermShell.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermStream.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermStream.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermUtils.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTermUtils.h create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTerminal.cpp create mode 100644 mozilla/extensions/xmlterm/base/mozXMLTerminal.h create mode 100644 mozilla/extensions/xmlterm/base/ptystream.c create mode 100644 mozilla/extensions/xmlterm/base/ptystream.h create mode 100644 mozilla/extensions/xmlterm/base/tracelog.c create mode 100644 mozilla/extensions/xmlterm/base/tracelog.h create mode 100644 mozilla/extensions/xmlterm/base/unistring.c create mode 100644 mozilla/extensions/xmlterm/base/unistring.h create mode 100644 mozilla/extensions/xmlterm/config/README create mode 100644 mozilla/extensions/xmlterm/config/autoconf.mk create mode 100644 mozilla/extensions/xmlterm/config/config.mk create mode 100644 mozilla/extensions/xmlterm/config/rules.mk create mode 100644 mozilla/extensions/xmlterm/config/xmlterm_config.mk create mode 100644 mozilla/extensions/xmlterm/dist/README create mode 100644 mozilla/extensions/xmlterm/doc/BUGS create mode 100644 mozilla/extensions/xmlterm/doc/FinalizeXPCOM create mode 100644 mozilla/extensions/xmlterm/doc/INSTALL.xmlterm create mode 100644 mozilla/extensions/xmlterm/doc/Implementation create mode 100644 mozilla/extensions/xmlterm/doc/MPL create mode 100644 mozilla/extensions/xmlterm/doc/Portability create mode 100644 mozilla/extensions/xmlterm/doc/README create mode 100644 mozilla/extensions/xmlterm/doc/SlowDOMBug create mode 100644 mozilla/extensions/xmlterm/doc/XMLterm_LICENSE create mode 100644 mozilla/extensions/xmlterm/doc/lineterm_LICENSE create mode 100644 mozilla/extensions/xmlterm/geckoterm/Makefile.in create mode 100644 mozilla/extensions/xmlterm/geckoterm/README create mode 100755 mozilla/extensions/xmlterm/geckoterm/default_prefs.js create mode 100755 mozilla/extensions/xmlterm/geckoterm/default_prefs.js.sav create mode 100644 mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp create mode 100644 mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp.sav create mode 100644 mozilla/extensions/xmlterm/geckoterm/mozISimpleContainer.h create mode 100644 mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.cpp create mode 100644 mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.h create mode 100644 mozilla/extensions/xmlterm/geckoterm/nsSetupRegistry.cpp create mode 100644 mozilla/extensions/xmlterm/geckoterm/nsTimer.cpp create mode 100755 mozilla/extensions/xmlterm/geckoterm/remake create mode 100644 mozilla/extensions/xmlterm/linetest/Makefile.in create mode 100644 mozilla/extensions/xmlterm/linetest/README create mode 100644 mozilla/extensions/xmlterm/linetest/lterm.c create mode 100644 mozilla/extensions/xmlterm/linetest/ptytest.c create mode 100755 mozilla/extensions/xmlterm/linetest/remake create mode 100644 mozilla/extensions/xmlterm/linetest/temncurses.c create mode 100644 mozilla/extensions/xmlterm/linetest/testunistr.c create mode 100755 mozilla/extensions/xmlterm/makemake create mode 100644 mozilla/extensions/xmlterm/tests/DocStream.c create mode 100644 mozilla/extensions/xmlterm/tests/HelloWorld.c create mode 100644 mozilla/extensions/xmlterm/tests/Makefile.in create mode 100644 mozilla/extensions/xmlterm/tests/README create mode 100644 mozilla/extensions/xmlterm/tests/escape.c create mode 100644 mozilla/extensions/xmlterm/tests/teststream.c create mode 100755 mozilla/extensions/xmlterm/tests/xls create mode 100755 mozilla/extensions/xmlterm/tests/xls.csh create mode 100644 mozilla/extensions/xmlterm/ui/Makefile.in create mode 100644 mozilla/extensions/xmlterm/ui/README create mode 100644 mozilla/extensions/xmlterm/ui/content/Makefile.in create mode 100644 mozilla/extensions/xmlterm/ui/content/README create mode 100644 mozilla/extensions/xmlterm/ui/content/xmlterm.html create mode 100644 mozilla/extensions/xmlterm/ui/skin/Makefile.in create mode 100644 mozilla/extensions/xmlterm/ui/skin/README create mode 100644 mozilla/extensions/xmlterm/ui/skin/images/README create mode 100644 mozilla/extensions/xmlterm/ui/skin/images/ficon.gif create mode 100644 mozilla/extensions/xmlterm/ui/skin/xmlterm.css diff --git a/mozilla/extensions/xmlterm/INSTALL b/mozilla/extensions/xmlterm/INSTALL new file mode 100644 index 00000000000..522f9eb4321 --- /dev/null +++ b/mozilla/extensions/xmlterm/INSTALL @@ -0,0 +1,170 @@ +INSTALL: Installation instructions for XMLterm source code +---------------------------------------------------------- + +*NOTE* This is work in progress. User beware! + +*NOTE* Check the XMLterm web site for updates. + +29 Nov 1999 + +In the following discussion, file and directory names are relative +to the main ("mozilla/extensions/xmlterm") directory. See the end of the +README file for a brief description of the subdirectories. + + +1. Source tree (skip this step if XMLterm is already in the source tree) +------------------------------------------------------------------------ + +The XMLterm source code is distributed as a tarball, xmlterm.tar.gz + +This tar file needs to be untarred in the "mozilla/extensions" directory, +or any any other "mozilla/dir" directory one level below the top-level. +A subdirectory called "xmlterm" will be created there. +("mozilla" denotes the root directory of the Mozilla source tree) + +If you have already untarred it elsewhere, simply move the "xmlterm" directory +to the right place. + + +2. Configuration +---------------- + +To recursively create all Makefiles from Makefile.in files, type the following: + +makemake -r + +The file "config/xmlterm_config.mk" contains XMLterm specific configuration +information that is needed in addition to any Mozilla configuration +information. It has already been hand-configured for Linux2.0/Linux2.2, and +Solaris2.6 platforms. It may need to be modified slightly to compile XMLterm +on other platforms. + +At present XMLterm has been tested only on Linux (RedHat6.0) and Solaris2.6 +platforms, using the M11 release as the base version of Mozilla. + +XMLterm typically uses the UNIX pseudo-TTY interface to communicate with the +shell. At present, this interface is implemented only for Linux and Solaris +platforms. + +XMLterm may compile on other Unix platforms, but it will use NSPR pipes, +rather than a pseudo-TTY, for process communication; this means that the +terminal control characters, such as Control-C for interrupting jobs, will not +work on those platforms. (See the file doc/PORTABILITY for a discussion of +portability issues) + + +3. Creating the dynamically loaded XPCOM/XPCONNECT component +------------------------------------------------------------ + +To create the dynamically loaded XPCOM library, type the following in the main +directory + + make all + +This creates the self-registering library "libxmlterm.so" and installs it in +the "mozilla/dist/bin/components" directory, along with some chrome +files. After this step, the following interfaces become accessible in Mozilla +through XPCOM/XPCONNECT: + + mozIXMLTermShell (interface to XMLterm) + mozILineTerm (interface to the stand-alone LINETERM) + +To clean up completely, type + + make clean + + +4. Using the lightweight "xmlterm" stand-alone program +---------------------------------------------------- + +Step 3 creates an executable called "xmlterm" in the "mozilla/dist/bin" +directory. This is a lightweight program implementing XMLterm using the Gecko +layout engine only, without the added baggage of the full browser. Executing +"xmlterm" will create an XMLterm window. Click on this window to give it focus +before typing Unix commands. + +The command line can be edited using EMACS-style key bindings. +Command completion should also work with TCSH and BASH, as should history +recall. + +**NOTE** +The command prompt is assumed to be terminated by one of the characters +"#$%>?", followed by a space. If this is not the case, many features will not +work. This restriction will be relaxed in the future. + +By default, blue coloring is used to indicate clickable display elements. +Note that the prompt and the input command line are clickable. +(Of course, the appearance of XMLterm is completely configurable +using the CSS stylesheet chrome://xmlterm/skin/default/xmlterm.css) + +After typing one or two commands, click on the prompt string of any previous +command to see what happens! Then click again on the same prompt string. +Also click on "Hide all output" button at the top of the document. + +Clicking on a previous command line (to the right of the prompt) re-executes +the command. + +The sample Perl script "xls", the iconic/hypertext version of the Unix "ls" +command, is in the "tests" directory. Copy it to some directory in your path +to use it. + +Note: At present, xmlterm only works with the GTK front end. + + +5. Creating an XMLterm window using the browser +----------------------------------------------- + +At this time, XMLterm cannot be accessed through the menu bar. Instead, load +the URL "chrome://xmlterm/content/xmlterm.html" in the browser, either at the +command line or by typing it in the URL box. Then click on the browser window +with the mouse to shift focus and then start typing UNIX commands. + + +6. Stand-alone mode (optional) +------------------------------ + +Although XMLterm resides in the Mozilla source tree, portions of it are +capable of being compiled and linked completely independent of Mozilla. You +may want to do this for testing purposes. The "config" directory contains +make files that are used for this stand-alone mode. There is even a dumb +script called "makemake" which can be used to re-create make files, if the +corresponding Makefile.in files have been changed. + +*NOTE* The executable "lterm" requires the NCURSES include file "curses.h" + +To create the stand-alone executables, type + + make STAND_ALONE=1 all + +(To clean up stand-alone modules, type "make STAND_ALONE=1 clean") + +This creates the stand-alone library in "base/lib" and some stand-alone +executables in the "linetest/lib" directory, in particular, one called +"lterm". + +The executable "lterm" implements a line terminal (LINETERM), i.e., a +non-graphical version of XMLterm. In the future, this may be implemented using +NCURSES for full screen operation. At present, it only provides line-at-a-time +functionality and is used only for testing. + +LINETERM acts as an "engine" for XMLterm, carrying out all the non-graphical +tasks, completely independent of Mozilla. It is written in C and is licensed +under both MPL and GPL. It provides functionality similar to the EMACS shell +mode or the GNU readline package. + +LINETERM has various options where trace output may be redirected to a +different TTY device, for debugging purposes. LINETERM may be used like the +shell command "sh", e.g., + + prompt% lterm + prompt% ls + + prompt% exit + +The "tests/escape" program can be used to generate terminal escape sequences +to test the XMLterm API. In particular, the following command enables +extensive trace output, if executed within an XMLterm or LINETERM: + + tests/escape 1 98 D + +----------------------------------------------------------------------------- diff --git a/mozilla/extensions/xmlterm/Makefile.in b/mozilla/extensions/xmlterm/Makefile.in new file mode 100644 index 00000000000..93b7eb5e169 --- /dev/null +++ b/mozilla/extensions/xmlterm/Makefile.in @@ -0,0 +1,78 @@ +#!gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# makefile for xmlterm root directory + +ifdef STAND_ALONE +DEPTH = . +topsrcdir = . +srcdir = . +include $(topsrcdir)/config/autoconf.mk +else +DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +include $(DEPTH)/config/autoconf.mk +endif + + +# Debug option +DEBUG = 1 + + +ifdef STAND_ALONE + +DIRS = base tests linetest + +else # not STAND_ALONE + +DIRS = base ui geckoterm tests + +LIBRARY_NAME = + +# Exported header files +EXPORTS = + +# Defines +DEFINES = + +# C++ Sources +CPPSRCS = + +endif + +include $(topsrcdir)/config/config.mk + +include config/xmlterm_config.mk + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/extensions/xmlterm/README b/mozilla/extensions/xmlterm/README new file mode 100644 index 00000000000..fd502eecadc --- /dev/null +++ b/mozilla/extensions/xmlterm/README @@ -0,0 +1,63 @@ +xmlterm --- A graphical command line interface +============================================== + +An early prototype of XMLterm, an XTERM-like terminal program implemented +using the open source Mozilla layout engine, is now available to tinker +with. XMLterm aims to add graphical and hypertext capabilities to the XTERM +command line interface, while maintaining backwards compatibility. + +The basic design philosophy of XMLterm is that the user interface is a dynamic +XML document. The user and the computer interact by taking turns at appending +to this XML document. The plain text content of the XML document, i.e., +excluding any markup, corresponds to the plain text that would be displayed by +a plain XTERM. The markup in the XML document is used to add graphical and +hypertext features. XMLterm uses the Mozilla layout engine to display the XML +document. + +XMLterm is an open source project in its early stages. Comments and +contributions are welcome! + +R. Saravanan +28 Nov 1999 +=========== + +NOTES: + + 1. See the INSTALL file for configuration/installation instructions. + + 2. See the file doc/INSTALL.xmlterm for binary installation instructions. + + 3. Check the XMLterm web site for updates. + +=========================================================================== +DOCUMENTATION + + a. There is a README file in each directory that provides some basic + information. + + b. The file "base/README" provides a brief overview of the XMLterm code + architecture. + + c. The header files (*.idl, *.h) have comments describing class methods + and member variables in JAVADOC format. Look at them before delving + into the *.cpp files + +=========================================================================== +FILES: + + INSTALL installation instructions + README this file + UUID.txt list of UUIDs used by XMLterm + +The main subdirectories of the "xmlterm" directory are: + + base/ base source code for XMLterm libraries + config/ make rules for stand-alone mode + dist/ holds include and library file for stand-alone LineTerm only + doc/ some documentation + geckoterm/ lightweight XMLterm executable + linetest/ stand-alone line terminal testing executables + tests/ XMLterm test programs and scripts, including "pagelets" + ui/* user interface/chrome files + +-- diff --git a/mozilla/extensions/xmlterm/UUID.txt b/mozilla/extensions/xmlterm/UUID.txt new file mode 100644 index 00000000000..507bdcfb205 --- /dev/null +++ b/mozilla/extensions/xmlterm/UUID.txt @@ -0,0 +1,28 @@ +UUID.txt: UUIDs used by XMLTerm +------------------------------- + +2 Dec 1999 + +A block of 256 UUIDs was generated by running uuidgen, +ranging from +/* 0eb82b00-43a2-11d3-8e76-006008948af5 */ +to +/* 0eb82bff-43a2-11d3-8e76-006008948af5 */ +with the 7th and 8th hex digits varying from 00 to ff. + +Of these, the following UUIDs are being used as IIDs and CIDs: + +mozILineTerm IID "0eb82b00-43a2-11d3-8e76-006008948af5" +mozLineTerm CID "0eb82b01-43a2-11d3-8e76-006008948af5" +mozILineTermAux IID "0eb82b10-43a2-11d3-8e76-006008948af5" +mozIXMLTerminal IID "0eb82b20-43a2-11d3-8e76-006008948af5" +mozXMLTerminal CID "0eb82b21-43a2-11d3-8e76-006008948af5" +mozIXMLTermShell IID "0eb82b30-43a2-11d3-8e76-006008948af5" +mozXMLTermShell CID "0eb82b31-43a2-11d3-8e76-006008948af5" +mozIXMLTermStream IID "0eb82b40-43a2-11d3-8e76-006008948af5" +mozXMLTermStream CID "0eb82b41-43a2-11d3-8e76-006008948af5" + +mozISimpleContainer IID "0eb82bF0-43a2-11d3-8e76-006008948af5" +mozSimpleContainer CID "0eb82bF1-43a2-11d3-8e76-006008948af5" + +-- diff --git a/mozilla/extensions/xmlterm/base/Makefile.in b/mozilla/extensions/xmlterm/base/Makefile.in new file mode 100644 index 00000000000..ca7a03604a4 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/Makefile.in @@ -0,0 +1,120 @@ +#!gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# makefile for xmlterm/base directory + +ifdef STAND_ALONE +DEPTH = .. +topsrcdir = .. +srcdir = . +include $(topsrcdir)/config/autoconf.mk +else +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +include $(DEPTH)/config/autoconf.mk +endif + + +# Debug option +DEBUG = 1 + +# Library name +LIBRARY_NAME = xmlterm + +# C Sources +ifdef NO_PTY +CSRCS = ltermManager.c ltermIO.c ltermInput.c ltermOutput.c ltermEscape.c \ + tracelog.c unistring.c +else +CSRCS = ltermManager.c ltermIO.c ltermInput.c ltermOutput.c ltermEscape.c \ + tracelog.c unistring.c ptystream.c +endif + +ifdef STAND_ALONE +# Defines +DEFINES += + +# Exported header files +EXPORTS = lineterm.h tracelog.h unistring.h ptystream.h + +# C++ Sources +CPPSRCS = + +else # not STAND_ALONE +# Defines +DEFINES += $(TK_CFLAGS) + +# Exported header files (excluding XPCONNECT interfaces) +EXPORTS = lineterm.h tracelog.h unistring.h ptystream.h mozXMLT.h mozXMLTermUtils.h mozIXMLTerminal.h mozIXMLTermStream.h + +# C++ Sources +CPPSRCS = \ + mozLineTerm.cpp \ + mozXMLTermUtils.cpp \ + mozXMLTerminal.cpp \ + mozXMLTermSession.cpp \ + mozXMLTermListeners.cpp \ + mozXMLTermShell.cpp \ + mozXMLTermFactory.cpp \ + $(NULL) + +MODULE = xmlterm +IS_COMPONENT = 1 + +EXTRA_DSO_LDOPTS = $(TK_LIBS) \ + -L$(DIST)/bin $(NSPR_LIBS) \ + -L$(DIST)/bin -lxpcom + +XPIDLSRCS = \ + mozILineTerm.idl \ + mozIXMLTermShell.idl \ + $(NULL) +endif + +# Also create static library libxmlterm.a +override NO_STATIC_LIB= + +REQUIRES = + +include $(topsrcdir)/config/config.mk + +include ../config/xmlterm_config.mk + +include $(topsrcdir)/config/rules.mk + +ifndef STAND_ALONE +ifeq ($(OS_ARCH),Linux) +OS_CFLAGS += -ansi +endif +endif diff --git a/mozilla/extensions/xmlterm/base/README b/mozilla/extensions/xmlterm/base/README new file mode 100644 index 00000000000..5ce99a2287a --- /dev/null +++ b/mozilla/extensions/xmlterm/base/README @@ -0,0 +1,127 @@ +base --- core source code for XMLterm and LineTerm + + XMLterm control-flow/layering hierarchy + ======================================= + + mozilla-executable xmlterm-executable + | | + ../ui/content/xmlterm.html | + | | + mozXMLTermShell ../geckoterm/mozGeckoTerm + | | | + +--------------+---------------+ | + | mozSimpleContainer + mozXMLTerminal + | + +-------------------+--------------------+ + | | | + mozXMLTermSession mozLineTermAux mozXMLTermListeners + | | | + | | | + mozXMLTermStream... (LineTerm) (user input) + (rendering ...) (pseudo-TTY/shell) + + +XMLterm may be invoked one of two ways: + 1. By loading the URL chrome://xmlterm/content/xmlterm.html in mozilla, or + 2. By running the stand-alone executable "../geckoterm/xmlterm". +The diagram above shows the control-flow/layering hierarchy for both ways +of invoking XMLterm. + +28 Nov 1999 +=========================================================================== +FILES: + +The core source code for XMLterm in this directory consists of two distinct +families of files, those with names that begin with the prefix "moz" and all +the other files. The former are the Mozilla-specific portions of XMLterm, +written in C++. The remaining files constitute the Mozilla-independent portion +of XMLterm, referred to as "LineTerm". + +============================================================================ +LINETERM: + +LineTerm is a line-oriented terminal program, in some respects similar in +functionality to the GNU Readline package. It is completely independent of the +Mozilla source code, is written in plain C, and dually licensed under GPL and +MPL. + +============================================================================ +INTERFACES: + +lineterm.h Plain C interface to LineTerm + (used by mozLineTerm) + +mozILineTerm.idl Scriptable XPCOM/XPCONNECT interface to LineTerm + (not used at the moment) + +mozILineTermAux.h XPCOM interface to LineTerm, with extra features + (used by mozXMLTerminal) + +mozIXMLTermShell.h Scriptable XPCOM/XPCONNECT interface to XMLterm + (used by the Javascript glue code in the XMLterm + start page at ../ui/content/xmlterm.html) + +mozIXMLTerminal.h XPCOM interface to XMLterm + (used by mozXMLTermShell, ../geckoterm/mozGeckoterm) + +mozIXMLTermStream.h XPCOM interface for displaying HTML/XML streams in + IFRAMES (used by mozXMLTermSession) + + +IMPLEMENTATIONS: + + +mozLineTerm.h/cpp Implementation of mozILineTerm, mozILineTermAux + Uses LineTerm to access shell + +mozXMLTermShell.h/cpp Implementation of mozIXMLTermShell + Uses mozIXMLTerminal to create XMLterm + +mozXMLTerminal.h/cpp Implementation of mozIXMLTerminal, + nsIDocumentLoaderObserver, and + nsIObserver + Uses mozILineTermAux to create LineTerm + Uses mozXMLTermListeners to capture user input + Uses mozXMLTermSession to display input/output + +mozXMLTermListeners.h/cpp Implementations of nsIDOMKeyListener, + nsIDOMTextListener, + nsIDOMMouseListener, + nsIDOMDragListener + +mozXMLTermStream.h/cpp Implementation of mozIXMLTermStream + + +CLASSES: + + +mozXMLTermSession.h/cpp Class to manage session input/output display + (used by mozXMLTerminal) + Uses mozIXMLTermStream to display streams + +mozXMLTermUtils.h/cpp Abstract class for static utility functions + (for use by all classes) + +============================================================================ +The following are dually licensed under MPL and GPL: + +LineTerm package: + +lineterm.h Public interface to LineTerm + +ltermPrivate.h Private common header file + +ltermManager.c LineTerm manager +ltermIO.c Overlapping I/O functions +ltermInput.c Input handler +ltermOutput.c Output handler +ltermEscape.c Escape sequence handler + +Low-level packages: + +ptystream.h/c Stream-like interface to Unix pseudo-TTY +tracelog.h/c Simple tracing/logging diagnostic library +unistring.h/c Simple Unicode manipulation library + +============================================================================ diff --git a/mozilla/extensions/xmlterm/base/lineterm.h b/mozilla/extensions/xmlterm/base/lineterm.h new file mode 100644 index 00000000000..732a18cfad7 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/lineterm.h @@ -0,0 +1,387 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* lineterm.h: Line terminal (LTERM) public interface header file + * LINETERM provides a "stream" interface to an XTERM-like terminal, + * using line-oriented input/output. + */ + +#ifndef _LINETERM_H + +#define _LINETERM_H 1 + +#ifndef _UNISTRING_H +#include "unistring.h" +#endif + +/* Define LTERM read callback function type */ +#ifdef USE_GTK_WIDGETS +#include +typedef void (*lterm_callback_func_t)(gpointer, gint, GdkInputCondition); +#else +typedef void* lterm_callback_func_t; +#endif + +/* Unicode character style information (same type as UNICHAR) */ +typedef UNICHAR UNISTYLE; + +#ifdef __cplusplus +extern "C" { +#endif + +/* lineterm functions */ + +/* LTERM module number (used for trace/log operations) */ +#define LTERM_TLOG_MODULE 1 + +/* Initializes all LTERM operations; + * needs to be called before any calls to lterm_new. + * @return 0 on success, or -1 on error. + * + * MESSAGELEVEL specifies the diagnostic message display level: + * 0 => (normal) only fatal errors cause diagnostic messages to be printed. + * -1 => (silent) no diagnostic messages are printed, even for fatal errors. + * 1 => (warning) print non-fatal warning messages as well as error messages. + * >9 and <= 99 (debugging) + * print debugging messages at selected procedure levels/sublevels + * (See tracelog.h for more information on messageLevel) + * + * Returns 0 on successful initialization, -1 otherwise. + */ + +int lterm_init(int messageLevel); + + +/** Creates a new LTERM object and returns its descriptor index but + * does not open it for I/O + * (documented in the LTERM interface) + * @return lterm descriptor index (>= 0) on success, or + * -1 on error + */ + +int lterm_new(); + +/* Opens line terminal indexed by LTERM for input/output and creates + * a process attached to it to execute the command line contained in string + * array ARGV. + * Called from the adminstrative/output thread of LTERM. + * @return 0 on success, or -1 on error. + * + * COOKIE contains a cookie string used for stream security. If it is null, + * or a null string, all streams are considered insecure. + * (only MAXCOOKIESTR-1 characters of the cookie string are used for checking) + * + * PROMPT_REGEXP contains a REGEXP string describing the command prompt. + * (**NOTE** For the moment, only a list of prompt delimiters is accepted; + * a typical list of prompt delimiters would be "#$%>?") + * + * OPTIONS is a bitmask controlling the following options: + * LTERM_NOCANONICAL_FLAG disable TTY canonical mode + * LTERM_NOEDIT_FLAG disable input line editing + * LTERM_NOCOMPLETION_FLAG disable command line completion + * LTERM_NOMETA_FLAG disable meta input + * LTERM_NOPARTLINE_FLAG disable returning of partial line output + * LTERM_NOMARKUP_FLAG disable HTML/XML element processing in command line + * LTERM_NOECHO_FLAG disable TTY echo + * LTERM_NOPTY_FLAG do not use pseudo-TTY + * LTERM_NOSTDERR_FLAG do not use separate STDERR + * LTERM_NONUL_FLAG do not process any NUL characters (discard them) + * LTERM_NOLINEWRAP_FLAG disable line wrapping + * LTERM_NOEXPORT_FLAG disable export of current environment to new process + * + * PROCESS_TYPE specifies the subordinate process type, if set to one + * of the following: + * LTERM_DETERMINE_PROCESS + * LTERM_UNKNOWN_PROCESS + * LTERM_SH_PROCESS + * LTERM_KSH_PROCESS + * LTERM_BASH_PROCESS + * LTERM_CSH_PROCESS + * LTERM_TCSH_PROCESS + * If it is set to LTERM_DETERMINE_PROCESS, the process type is determined + * from the path name. + * + * CALLBACK_FUNC is a pointer to a GTK-style callback function, + * or NULL for no callback. + * The function is called whenever there is data available for + * LTERM_READ to process, with CALLBACK_DATA as the data argument. + * The callback function should call LTERM_READ immediately; + * otherwise the callback function will be called repeatedly. + * (The type LTERM_CALLBACK_FUNC_T is defined at the top of this include file) + * + * In canonical mode, no input line editing is permitted. + * In editing mode, EMACS-style keyboard line editing commands are allowed. + * In completion mode, incomplete command/file names are transmitted to + * the subordinate process for complettion, as in TCSH. + * Meta input refers to input lines that begin with a colon, + * or with a "protocol" name followed by a colon, such as + * "http: ...". + * Meta input lines are not sent to the subordinate process, but simply + * echoed as LTERM output through LTERM_READ for further processing. + * If command line completion is not disabled, incomplete meta input may + * also be echoed for completion. In this case, the completed meta input + * should be supplied to the LTERM through a call to LTERM_WRITE as if the + * user had entered it. + */ + +int lterm_open(int lterm, char *const argv[], const char* cookie, + const UNICHAR* prompt_regexp, int options, int process_type, + lterm_callback_func_t callback_func, void *callback_data); + + +/* Closes line terminal indexed by LTERM. + * The default action is to block until active calls to lterm_write + * and lterm_read to complete. + * Called from the administrative/output thread of LTERM. + * @return 0 on success, or -1 on error. + */ +int lterm_close(int lterm); + + +/** Deletes an LTERM object, closing it if necessary. + * @return 0 on success, or -1 on error. + */ + +int lterm_delete(int lterm); + + +/* Closes all LTERMs, but does not delete them. + * This may be used to free any resources associated with LTERMs for clean up. + * The closed LTERMs should still be deleted, if possible. + */ +void lterm_close_all(void); + + +/* Set input echo flag for line terminal indexed by LTERM. + * Called from the output thread of LTERM. + * @return 0 on success, or -1 on error. + */ + +int lterm_setecho(int lterm, int echo_flag); + + +/* Resizes the line terminal indexed by LTERM. + * Called from the output thread of LTERM. + * @return 0 on success, or -1 on error. + */ + +int lterm_resize(int lterm, int rows, int cols, + int xpix, int ypix); + + +/* Sets cursor position in line terminal indexed by LTERM. + * Called from the output thread of LTERM. + * @return 0 on success, or -1 on error. + */ + +int lterm_setcursor(int lterm, int row, int col); + + +/* Writes supplied to Unicode string in BUF of length COUNT to + * line terminal indexed by LTERM. + * (May be called from any thread, since it uses a pipe to communicate + * with the output thread.) + * DATATYPE may be set to one of the following values: + * LTERM_WRITE_PLAIN_INPUT Plain text user input + * LTERM_WRITE_XML_INPUT XML element user input + * LTERM_WRITE_PLAIN_OUTPUT Plain text server output + * LTERM_WRITE_CLOSE_MESSAGE End of file message + * NOTE: This is a non-blocking call + * Returns the number of characters written. + * Returns -1 on error, and + * -2 if pseudo-TTY has been closed. + * If the return value is less than COUNT, it usually indicates an error. + * If the return value is -1, any further operations on the LTERM, + * other than LTERM_CLOSE, will always fail with an error return value. + */ + +int lterm_write(int lterm, const UNICHAR *buf, int count, int dataType); + + +/* Completes meta input in line terminal indexed by LTERM with the + * supplied to Unicode string in BUF of length COUNT. + * Called from the output thread of the LTERM. + * @return 0 on success, or -1 on error. + */ + +int lterm_metacomplete(int lterm, const UNICHAR *buf, int count); + + +/* reads upto COUNT Unicode characters from a single line of output + * from line terminal indexed by LTERM into BUF. + * Called from the output thread of the LTERM. + * Returns the number of characters read (>=0) on a successful read. + * Returns -1 if an error occurred while reading, + * -2 if pseudo-TTY has been closed, + * -3 if more than COUNT characters are present in the line + * (in this case the first COUNT characters are returned in BUF, + * and the rest are discarded). + * If the return value is -1, any further operations on the LTERM, + * other than LTERM_CLOSE, will always fail with an error return value. + * (If return value is -2, it means that the subordinate process has closed + * the pseudo-TTY. In this case, the LTERM still needs to be explicitly + * closed by calling LTERM_CLOSE for proper clean-up.) + * + * TIMEOUT is the number of platform-dependent time units + * (usually milliseconds on Unix) to wait to read data. + * A zero value implies no waiting. + * A negative TIMEOUT value implies infinite timeout, i.e., a blocking read. + * Non-zero values of TIMEOUT should be used only when the output thread + * is allowed to block. + * + * STYLE should be an array of same length as BUF, and contains + * the style bits associated with each character on return (see below). + * + * OPCODES contains a bit mask describing the type of output (see below). + * Using Extended Backus-Naur Form notation: + * + * OPCODES ::= STREAMDATA NEWLINE? COOKIESTR? XMLSTREAM? DOCSTREAM? WINSTREAM? + * if StreamMode data is being returned. + * + * OPCODES ::= SCREENDATA BELL? ( CLEAR + * | INSERT MOVEDOWN? + * | DELETE MOVEDOWN? + * | OUTPUT ) + * if ScreenMode data is being returned. + * + * OPCODES ::= LINEDATA BELL? ( CLEAR + * | ( PROMPT | OUTPUT)? INPUT ( NEWLINE HIDE? )? + * | PROMPT? INPUT META ( COMPLETION | NEWLINE HIDE? ) + * | OUTPUT NEWLINE? ) + * if LineMode data is being returned. + * + * If OPCODES == 0, then it means that no data has been read. + * + * If the returned OPCODES has META and COMPLETION bits set, then the completed + * version of the meta input should be supplied through a call to + * LTERM_WRITE, with an input data type, as if the user had typed it. + * + * BUF_ROW and BUF_COL denote the row and starting column at which to + * display the data in BUF. + * (If character count returned by lterm_read is zero, implying there is no + * data in BUF, then values of BUF_ROW and BUF_COL should be ignored.) + * In ScreenMode or LineMode, CURSOR_ROW and CURSOR_COL denote the final + * cursor position after any data in BUF is displayed. + * + * The bottom left corner of the screen corresponds to row 0, column 0. + * BUF_COL, CURSOR_COL are always >= 0, with 0 denoting the leftmost column. + * (BUF_COL is always zero if NOPARTLINE flag is set for LTERM.) + * (CURRENT IMPLEMENTATION: BUF_COL is always zero.) + * BUF_ROW, CURSOR_ROW are always set to -1 when LTERM is in line mode, + * BUF_ROW, CURSOR_ROW are always >=0 when LTERM is in screen mode, + * with 0 denoting the bottom row. + */ + +int lterm_read(int lterm, int timeout, UNICHAR *buf, int count, + UNISTYLE *style, int *opcodes, + int *buf_row, int *buf_col, int *cursor_row, int *cursor_col); + +/* opcodes describing terminal operations: + */ +#define LTERM_STREAMDATA_CODE 0x0001U /* Stream mode */ +#define LTERM_SCREENDATA_CODE 0x0002U /* Screen mode */ +#define LTERM_LINEDATA_CODE 0x0004U /* Line mode */ +#define LTERM_BELL_CODE 0x0008U /* Ring bell */ +#define LTERM_CLEAR_CODE 0x0010U /* Clear screen */ +#define LTERM_INSERT_CODE 0x0020U /* Insert row at cursor */ +#define LTERM_DELETE_CODE 0x0040U /* Delete row at cursor */ +#define LTERM_MOVEDOWN_CODE 0x0080U /* Move text down on insert/delete */ +#define LTERM_INPUT_CODE 0x0100U /* Contains STDIN at end of line */ +#define LTERM_PROMPT_CODE 0x0200U /* Contains prompt at beginning */ +#define LTERM_OUTPUT_CODE 0x0400U /* Contains STDOUT/STDERR/ALTOUT */ +#define LTERM_META_CODE 0x0800U /* Meta input */ +#define LTERM_COMPLETION_CODE 0x1000U /* Completion requested */ +#define LTERM_NEWLINE_CODE 0x2000U /* Complete (new) line */ +#define LTERM_HIDE_CODE 0x4000U /* Hide output */ + +#define LTERM_COOKIESTR_CODE 0x8000U /* Stream prefixed with cookie */ +#define LTERM_XMLSTREAM_CODE 0x10000U /* Stream contains XML, not HTML */ +#define LTERM_DOCSTREAM_CODE 0x20000U /* Stream contains complete document */ +#define LTERM_WINSTREAM_CODE 0x40000U /* Display stream in entire window */ + + +/* LTERM/XTERM 16-bit style mask: + * PROMPT, STDIN, STDOUT, STDERR, ALTOUT are mutually exclusive. + * The markup styles apply to STDIN/STDOUT/ALTOUT data. + * The highlighting styles only apply to STDOUT data. + * The VT100 foreground and background styles are not implemented. + */ + +#define LTERM_PROMPT_STYLE 0x0001UL /* prompt string */ +#define LTERM_STDIN_STYLE 0x0002UL /* standard input */ +#define LTERM_STDOUT_STYLE 0x0004UL /* standard output */ +#define LTERM_STDERR_STYLE 0x0008UL /* standard error */ +#define LTERM_ALTOUT_STYLE 0x0010UL /* alternate output */ + +#define LTERM_URI_STYLE 0x0020UL /* URI markup */ +#define LTERM_HTML_STYLE 0x0040UL /* HTML markup */ +#define LTERM_XML_STYLE 0x0080UL /* XML markup */ + +#define LTERM_BOLD_STYLE 0x0100UL /* boldface */ +#define LTERM_ULINE_STYLE 0x0200UL /* underline */ +#define LTERM_BLINK_STYLE 0x0400UL /* blink */ +#define LTERM_DIM_STYLE 0x0800UL /* inverse video */ + +/* LTERM option flags */ +#define LTERM_NOCANONICAL_FLAG 0x0001U +#define LTERM_NOEDIT_FLAG 0x0002U +#define LTERM_NOCOMPLETION_FLAG 0x0004U +#define LTERM_NOMETA_FLAG 0x0008U +#define LTERM_NOPARTLINE_FLAG 0x0010U +#define LTERM_NOECHO_FLAG 0x0020U +#define LTERM_NOMARKUP_FLAG 0x0040U +#define LTERM_NOPTY_FLAG 0x0080U +#define LTERM_NOSTDERR_FLAG 0x0100U +#define LTERM_NONUL_FLAG 0x0200U +#define LTERM_NOLINEWRAP_FLAG 0x0400U +#define LTERM_NOEXPORT_FLAG 0x0800U + +/* Process type codes */ +#define LTERM_DETERMINE_PROCESS -1 /* Determine process type from name */ +#define LTERM_UNKNOWN_PROCESS 0 /* Unknown process type */ +#define LTERM_SH_PROCESS 1 /* Bourne shell */ +#define LTERM_KSH_PROCESS 2 /* Korn shell */ +#define LTERM_BASH_PROCESS 3 /* Bourne Again shell */ +#define LTERM_CSH_PROCESS 4 /* C shell */ +#define LTERM_TCSH_PROCESS 5 /* TC shell */ + +/* lterm_write data type codes (XML server output not permitted) */ +#define LTERM_WRITE_PLAIN_INPUT 0 /* Plain text user input */ +#define LTERM_WRITE_XML_INPUT 1 /* XML element user input */ +#define LTERM_WRITE_PLAIN_OUTPUT 2 /* Plain text server output */ +#define LTERM_WRITE_CLOSE_MESSAGE 3 /* End of file message */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LINETERM_H */ diff --git a/mozilla/extensions/xmlterm/base/ltermEscape.c b/mozilla/extensions/xmlterm/base/ltermEscape.c new file mode 100644 index 00000000000..a57cef8babf --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ltermEscape.c @@ -0,0 +1,1029 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ltermEscape.c: LTERM escape sequence processing + */ + +/* public declarations */ +#include "lineterm.h" + +/* private declarations */ +#include "ltermPrivate.h" + + +static int ltermProcessCSISequence(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style, int *consumed, int *opcodes); +static int ltermProcessDECPrivateMode(struct lterms *lts, + const int *paramValues, int paramCount, UNICHAR uch, int *opcodes); +static int ltermProcessXTERMSequence(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style,int *consumed,int *opcodes); +static int ltermProcessXMLTermSequence(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style,int *consumed,int *opcodes); + + +/** Processes ESCAPE sequence in string BUF containing COUNT characters, + * returning the number of characters CONSUMED and the OPCODES. + * Using Extended Backus-Naur Form notation: + * OPCODES ::= 0 if the sequence was processed without any change of + * outputMode or terminating condition. + * OPCODES ::= LINEDATA OUTPUT if a switch from LineMode to ScreenMode + * or StreamMode was triggered by the ESCAPE sqeuence. + * OPCODES ::= SCREENDATA OUTPUT if a switch from ScreenMode to StreamMode + * was triggered by the ESCAPE sequence. + * (A switch from ScreenMode to LineMode is not considered a terminating + * condition and occurs transparently.) + * OPCODES ::= SCREENDATA ( CLEAR + * | INSERT MOVEDOWN? + * | DELETE MOVEDOWN? ) + * if the ESCAPE sequence corresponds to the ScreenMode terminal operation. + * OPCODES ::= LINEDATA CLEAR + * if the ESCAPE sequence corresponds to the LineMode terminal operation. + * + * @return 0 on successful processing of the ESCAPE sequence, + * 1 if BUF contains an incomplete ESCAPE sequence, + * -1 if error an error occurred. + */ +int ltermProcessEscape(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style, int *consumed, int *opcodes) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + + LTERM_LOG(ltermProcessEscape,50,("count=%d, buf[1]='%c', cursorChar=%d, Chars=%d\n", + count, buf[1], lto->outputCursorChar, lto->outputChars)); + + if (count < 2) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + if (buf[1] == U_LBRACKET) { + /* ESC [ Process CSI sequence */ + return ltermProcessCSISequence(lts, buf, count, style, consumed, opcodes); + } + + if (buf[1] == U_RBRACKET) { + /* ESC ] Process XTERM sequence */ + return ltermProcessXTERMSequence(lts, buf, count, style, consumed,opcodes); + } + + if (buf[1] == U_LCURLY) { + /* ESC { Process XMLTerm sequence */ + return ltermProcessXMLTermSequence(lts, buf, count, style, consumed,opcodes); + } + + /* Set returned opcodes to zero */ + *opcodes = 0; + + /* Assume two characters will be consumed at this point */ + *consumed = 2; + + switch (buf[1]) { + /* Three character sequences */ + case U_NUMBER: /* ESC # 8 DEC Screen Alignment Test */ + case U_LPAREN: /* ESC ( C Designate G0 Character Set */ + case U_RPAREN: /* ESC ) C Designate G1 Character Set */ + case U_STAR: /* ESC * C Designate G2 Character Set */ + case U_PLUS: /* ESC + C Designate G3 Character Set */ + case U_DOLLAR: /* ESC $ C Designate Kanji Character Set */ + LTERM_LOG(ltermProcessEscape,51,("3 char sequence, buf[1:2]='%c%c'\n", + buf[1], buf[2])); + + if (count < 3) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + *consumed = 3; + + if (buf[1] == U_NUMBER) { + /* ESC # 8 DEC Screen Alignment Test */ + } else { + /* ESC ()*+$ C Designate Character Set */ + } + return 0; + + /* Two character sequences */ + case U_SEVEN: /* ESC 7 Save Cursor */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_EIGHT: /* ESC 8 Restore Cursor */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_EQUALS: /* ESC = Application Keypad */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_GREATERTHAN: /* ESC > Normal Keypad */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_D_CHAR: /* ESC D Index (IND) */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_E_CHAR: /* ESC E Next Line (NEL) */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_H_CHAR: /* ESC H Tab Set (HTS) */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_M_CHAR: /* ESC M Reverse Index (TI) */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_N_CHAR: /* ESC N Single Shift Select of G2 Character Set */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_O_CHAR: /* ESC O Single Shift Select of G3 Character Set */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_Z_CHAR: /* ESC Z Obsolete form of ESC[c */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_c_CHAR: /* ESC c Full reset (RIS) */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_n_CHAR: /* ESC n Invoke the G2 Character Set */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + case U_o_CHAR: /* ESC o Invoke the G3 Character Set */ + LTERM_WARNING("ltermProcessEscape: Warning - unimplemented %c\n", + buf[1]); + return 0; + + default: + LTERM_WARNING("ltermProcessEscape: Warning - unknown sequence %x\n", + buf[1]); + return 0; + } +} + + +/** Processes CSI sequence (a special case of Escape sequence processing) + * @return 0 on success and -1 on error. + */ +static int ltermProcessCSISequence(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style, int *consumed, int *opcodes) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int offset, value, privateMode; + int paramCount, paramValues[MAXESCAPEPARAMS], param1, param2; + + if (count < 3) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + LTERM_LOG(ltermProcessCSISequence,50,("buf[2]='%c', cursorChar=%d, Chars=%d\n", + buf[2], lto->outputCursorChar, lto->outputChars)); + + privateMode = 0; + offset = 2; + if (buf[2] == U_QUERYMARK) { + /* ESC [ ? Process DEC Private Mode */ + privateMode = 1; + offset = 3; + } + + /* Set returned opcodes to zero */ + *opcodes = 0; + + /* Process numerical parameters */ + paramCount = 0; + while ((offset < count) && + ((buf[offset] >= U_ZERO) && (buf[offset] <= U_NINE)) ) { + /* Starts with a digit */ + value = buf[offset] - U_ZERO; + offset++; + + /* Process all contiguous digits */ + while ((offset < count) && + ((buf[offset] >= U_ZERO) && (buf[offset] <= U_NINE)) ) { + value = value * 10 + buf[offset] - U_ZERO; + offset++; + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + if (paramCount < MAXESCAPEPARAMS) { + /* Store numerical parameter */ + paramValues[paramCount++] = value; + + } else { + /* Numeric parameter buffer overflow */ + LTERM_WARNING("ltermProcessCSISequence: Warning - numeric parameter buffer overflow\n"); + } + + /* If next character not semicolon, stop processing */ + if (buf[offset] != U_SEMICOLON) + break; + + /* Process next argument */ + offset++; + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + /* Assume that all parsed characters will be consumed at this point */ + *consumed = offset+1; + + LTERM_LOG(ltermProcessCSISequence,51,("paramCount=%d, offset=%d, buf[offset]='%d'\n", + paramCount, offset, buf[offset])); + + if (privateMode) { + /* ESC [ ? Process DEC Private Mode */ + return ltermProcessDECPrivateMode( lts, paramValues, paramCount, + buf[offset], opcodes); + } + + /* Set returned opcodes to zero */ + *opcodes = 0; + + /* Default parameter values: 1, 1 */ + param1 = (paramCount > 0) ? paramValues[0] : 1; + param2 = (paramCount > 1) ? paramValues[1] : 1; + + switch (buf[offset]) { + + case U_ATSIGN: /* Insert Ps (Blank) Character(s) [default: 1] (ICH) */ + if (ltermInsDelEraseChar(lts, param1, LTERM_INSERT_CHAR) != 0) + return -1; + return 0; + + case U_e_CHAR: + case U_A_CHAR: /* Cursor Up Ps Times [default: 1] (CUU) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_B_CHAR: /* Cursor Down Ps Times [default: 1] (CUD) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_a_CHAR: + case U_C_CHAR: /* Cursor Forward Ps Times [default: 1] (CUF) */ + LTERM_LOG(ltermProcessCSISequence,52,("Cursor Forward Count = %d\n", + param1)); + + if (lto->outputMode == LTERM2_LINE_MODE) { + + if (param1 <= (lto->outputChars - lto->outputCursorChar)) { + lto->outputCursorChar += param1; + } else { + lto->outputCursorChar = lto->outputChars; + } + } + return 0; + + case U_D_CHAR: /* Cursor Backward Ps Times [default: 1] (CUB) */ + LTERM_LOG(ltermProcessCSISequence,52,("Cursor Back Count = %d\n", + param1)); + + if (lto->outputMode == LTERM2_LINE_MODE) { + + if (param1 <= lto->outputCursorChar) { + lto->outputCursorChar -= param1; + } else { + lto->outputCursorChar = 0; + } + } + return 0; + + case U_E_CHAR: /* Cursor Down Ps Times [default: 1] and to first column */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_F_CHAR: /* Cursor Up Ps Times [default: 1] and to first column */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_SNGLQUOTE: + case U_G_CHAR: /* Cursor to Column Ps (HPA) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_H_CHAR: /* Cursor Position [row;column] [default: 1;1] (CUP) */ + LTERM_LOG(ltermProcessCSISequence,52,("Cursor Position = (%d, %d)\n", + param1, param2)); + + if (lto->outputMode == LTERM2_LINE_MODE) { + + if ((param1 > 0) && ((param1-1) <= lto->outputChars)) { + lto->outputCursorChar = param1-1; + } else { + lto->outputCursorChar = 0; + } + } + return 0; + + case U_I_CHAR: /* Move forward Ps tab stops [default: 1] */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_J_CHAR: /* Erase in Display (ED) + * Ps = 0 Clear Below (default) + * Ps = 1 Clear Above + * Ps = 2 Clear All + */ + param1 = (paramCount > 0) ? paramValues[0] : 0; + + LTERM_LOG(ltermProcessCSISequence,52,("Erase display code %d\n", + param1)); + + if (lto->outputMode == LTERM2_LINE_MODE) { + /* Clear line */ + ltermClearOutputLine(lts); + + /* Set opcodes to return incomplete line */ + *opcodes = LTERM_LINEDATA_CODE|LTERM_CLEAR_CODE; + } + return 0; + + case U_K_CHAR: /* Erase in Line (EL) + * Ps = 0 Clear to Right (default) + * Ps = 1 Clear to Left + * Ps = 2 Clear All + */ + param1 = (paramCount > 0) ? paramValues[0] : 0; + + LTERM_LOG(ltermProcessCSISequence,52,("Line erase code %d\n", + param1)); + + if (lto->outputMode == LTERM2_LINE_MODE) { + + switch(param1) { + case 0: /* Clear to Right */ + lto->outputChars = lto->outputCursorChar; + lto->outputModifiedChar = lto->outputCursorChar; + break; + case 1: /* Clear to Left */ + lto->outputChars -= lto->outputCursorChar; + lto->outputCursorChar = 0; + lto->outputModifiedChar = 0; + break; + case 2: /* Clear All */ + lto->outputChars = 0; + lto->outputCursorChar = 0; + lto->outputModifiedChar = 0; + break; + default: /* Invalid erase code */ + LTERM_WARNING("ltermProcessCSISequence: Warning - invalid erase code %d\n", param1); + } + + } + return 0; + + case U_L_CHAR: /* Insert Ps Line(s) [default: 1] (IL) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_M_CHAR: /* Delete Ps Line(s) [default: 1] (DL) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_P_CHAR: /* Delete Ps Character(s) [default: 1] (DCH) */ + if (ltermInsDelEraseChar(lts, param1, LTERM_DELETE_CHAR) != 0) + return -1; + return 0; + + case U_T_CHAR: /* Initiate hilite mouse tracking. Parameters + * [func;startx;starty;firstrow;lastrow]. + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_W_CHAR: /* Tabulator functions: + * Ps = 0 Tab Set (HTS) + * Ps = 2 Tab Clear (TBC), Clear Current Column (default) + * Ps = 5 Tab Clear (TBC), Clear All + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_X_CHAR: /* Erase Ps Character(s) [default: 1] (ECH) */ + if (ltermInsDelEraseChar(lts, param1, LTERM_ERASE_CHAR) != 0) + return -1; + return 0; + + case U_Z_CHAR: /* Move backward Ps [default: 1] tab stops */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_c_CHAR: /* Send Device Attributes (DA) + * Ps = 0 (or omitted) : request attributes from terminal + * returns: ESC[?1;2c + * (``I am a VT100 with Advanced Video Option'') + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_d_CHAR: /* Cursor to Line Ps (VPA) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_f_CHAR: /* Horizontal and Vertical Position [row;column] (HVP) + * [default: 1;1] + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_g_CHAR: /* Tab Clear (TBC) + * Ps = 0 Clear Current Column (default) + * Ps = 3 Clear All (TBC) + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_i_CHAR: /* Printing + * Ps = 4 disable transparent print mode (MC4) + * Ps = 5 enable transparent print mode (MC5) + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_h_CHAR: /* Set Mode (SM) + * Ps = 4 Insert Mode (SMIR) + * Ps = 20 Automatic Newline (LNM) + */ + LTERM_LOG(ltermProcessCSISequence,52,("Set Mode %d\n", + param1)); + + if (param1 == 4) { + lto->insertMode = 1; + } else if (param1 == 4) { + lto->automaticNewline = 1; + } + return 0; + + case U_l_CHAR: /* Reset Mode (RM) + * Ps = 4 Replace Mode (RMIR) + * Ps = 20 Normal Linefeed (LNM) + */ + LTERM_LOG(ltermProcessCSISequence,52,("Reset Mode %d\n", + param1)); + + if (param1 == 4) { + lto->insertMode = 0; + } else if (param1 == 4) { + lto->automaticNewline = 0; + } + return 0; + + case U_m_CHAR: /* Character Attributes (SGR) + * Ps = 0 Normal (default) + * Ps = 1 / 22 On / Off Bold (bright fg) + * Ps = 4 / 24 On / Off Underline + * Ps = 5 / 25 On / Off Blink (bright bg) + * Ps = 7 / 27 On / Off Inverse + * Ps = 30 / 40 fg/bg Black + * Ps = 31 / 41 fg/bg Red + * Ps = 32 / 42 fg/bg Green + * Ps = 33 / 43 fg/bg Yellow + * Ps = 34 / 44 fg/bg Blue + * Ps = 35 / 45 fg/bg Magenta + * Ps = 36 / 46 fg/bg Cyan + * Ps = 37 / 47 fg/bg White + * Ps = 39 / 49 fg/bg Default + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_n_CHAR: /* Device Status Report (DSR) + * Ps = 5 Status Report ESC [ 0 n (``OK'') + * Ps = 6 Report Cursor Position (CPR) [row;column] + * as ESC [ r ; c R + * Ps = 7 Request Display Name + * Ps = 8 Request Version Number (place in window title) + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_r_CHAR: /* Set Scrolling Region [top;bottom] + * [default: full size of window] (CSR) + */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + case U_x_CHAR: /* Request Terminal Parameters (DECREQTPARM) */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unimplemented %c\n", + buf[offset]); + return 0; + + default: /* Unknown Escape sequence */ + LTERM_WARNING("ltermProcessCSISequence: Warning - unknown sequence %x\n", + buf[offset]); + return 0; + } + +} + + +/** Processes DEC Private Modes (a special case of CSI sequence processing) + * ESC [ ? Pm h + * @return 0 on success and -1 on error. + */ +static int ltermProcessDECPrivateMode(struct lterms *lts, + const int *paramValues, int paramCount, UNICHAR uch, int *opcodes) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + + LTERM_LOG(ltermProcessDECPrivateMode,50,("ch='%c', cursorChar=%d, Chars=%d\n", + (char) uch, lto->outputCursorChar, lto->outputChars)); + + /* Set returned opcodes to zero */ + *opcodes = 0; + + switch (uch) { + case U_h_CHAR: /* DEC Private Mode Set (DECSET) */ + LTERM_WARNING("ltermProcessDECPrivateMode: Warning - unimplemented %c\n", + (char) uch); + return 0; + + case U_l_CHAR: /* DEC Private Mode Reset (DECRST) */ + LTERM_WARNING("ltermProcessDECPrivateMode: Warning - unimplemented %c\n", + (char) uch); + return 0; + + case U_r_CHAR: /* Restore previously saved DEC Private Mode Values */ + LTERM_WARNING("ltermProcessDECPrivateMode: Warning - unimplemented %c\n", + (char) uch); + return 0; + + case U_s_CHAR: /* Save DEC Private Mode Values */ + LTERM_WARNING("ltermProcessDECPrivateMode: Warning - unimplemented %c\n", + (char) uch); + return 0; + + case U_t_CHAR: /* Toggle DEC Private Mode Values */ + LTERM_WARNING("ltermProcessDECPrivateMode: Warning - unimplemented %c\n", + (char) uch); + return 0; + + default: /* Unknown escape sequence */ + LTERM_WARNING("ltermProcessDECPrivateMode: Warning - unknown sequence %x\n", + uch); + return 0; + } + +} + + +/** Processes XTERM sequence (a special case of Escape sequence processing) + * ESC ] Ps;Pt BEL + * @return 0 on success and -1 on error. + */ +static int ltermProcessXTERMSequence(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style,int *consumed,int *opcodes) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int offset, paramValue, strLength; + UNICHAR paramString[MAXSTRINGPARAM+1]; + + if (count < 3) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + LTERM_LOG(ltermProcessXTERMSequence,50,("cursorChar=%d, Chars=%d\n", + lto->outputCursorChar, lto->outputChars)); + + offset = 2; + + /* Set returned opcodes to zero */ + *opcodes = 0; + + /* Process numerical parameter */ + paramValue = 0; + while ((offset < count) && + ((buf[offset] >= U_ZERO) && (buf[offset] <= U_NINE)) ) { + paramValue = paramValue * 10 + buf[offset] - U_ZERO; + offset++; + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + if (buf[offset] != U_SEMICOLON) { + /* If next character not semicolon, return */ + *consumed = offset; + return 0; + } + + LTERM_LOG(ltermProcessXTERMSequence,51,("paramValue=%d, offset=%d, buf[offset]=%x\n", + paramValue, offset, buf[offset])); + + /* Skip the semicolon */ + offset++; + + /* Process string parameter */ + strLength = 0; + while ((offset < count) && (buf[offset] != U_BEL)) { + if (strLength < MAXSTRINGPARAM) { + paramString[strLength++] = buf[offset]; + offset++; + + } else { + LTERM_WARNING("ltermProcessXTERMSequence: Warning - string parameter too long; truncated\n"); + break; + } + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + /* Insert terminating NULL character in string */ + paramString[strLength] = U_NUL; + + LTERM_LOGUNICODE(ltermProcessXTERMSequence,52,(paramString, strLength)); + + /* All parsed characters have been consumed at this point */ + *consumed = offset+1; + + LTERM_WARNING("ltermProcessXTERMSequence: Warning - unimplemented %c\n", + buf[offset]); + + return 0; +} + +/** Processes XMLTerm sequence (a special case of Escape sequence processing) + * XMLterm escape sequences are of the form + * ESC { Pm C Pt BEL + * where Pm denotes multiple numeric arguments separated by semicolons, + * character C is a not a digit and not a semicolon, and + * text parameter Pt may be a null string. + * Omitted numeric parameters are assumed to be zero. + * @return 0 on success and -1 on error. + */ +static int ltermProcessXMLTermSequence(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style,int *consumed,int *opcodes) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int offset, value, strLength; + int paramCount, paramValues[MAXESCAPEPARAMS], param1, param2, param3; + UNICHAR termChar, paramString[MAXSTRINGPARAM+1]; + char paramCString[MAXSTRINGPARAM+1]; + + if (count < 4) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + LTERM_LOG(ltermProcessXMLTermSequence,50,("cursorChar=%d, Chars=%d\n", + lto->outputCursorChar, lto->outputChars)); + + offset = 2; + + /* Set returned opcodes to zero */ + *opcodes = 0; + + /* Process numerical parameters */ + paramCount = 0; + while ((offset < count) && + ((buf[offset] >= U_ZERO) && (buf[offset] <= U_NINE)) ) { + /* Starts with a digit */ + value = buf[offset] - U_ZERO; + offset++; + + /* Process all contiguous digits */ + while ((offset < count) && + ((buf[offset] >= U_ZERO) && (buf[offset] <= U_NINE)) ) { + value = value * 10 + buf[offset] - U_ZERO; + offset++; + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + if (paramCount < MAXESCAPEPARAMS) { + /* Store numerical parameter */ + paramValues[paramCount++] = value; + + } else { + /* Numeric parameter buffer overflow */ + LTERM_WARNING("ltermProcessXMLTermSequence: Warning - numeric parameter buffer overflow\n"); + } + + /* If next character not semicolon, stop processing */ + if (buf[offset] != U_SEMICOLON) + break; + + /* Process next argument */ + offset++; + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + /* Terminating character */ + termChar = buf[offset]; + + /* Skip terminating character */ + offset++; + + LTERM_LOG(ltermProcessXMLTermSequence,51,("paramCount=%d, offset=%d, termChar=%x\n", + paramCount, offset, termChar)); + + /* Process string parameter */ + strLength = 0; + while ((offset < count) && (buf[offset] != U_BEL)) { + if (strLength < MAXSTRINGPARAM) { + paramCString[strLength] = buf[offset]; + paramString[strLength++] = buf[offset]; + offset++; + + } else { + LTERM_WARNING("ltermProcessXMLTermSequence: Warning - string parameter too long; truncated\n"); + break; + } + } + + if (offset == count) { + /* Incomplete Escape sequence */ + *consumed = 0; + return 1; + } + + /* Insert terminating NULL character in string */ + paramCString[strLength] = U_NUL; + paramString[strLength] = U_NUL; + + LTERM_LOGUNICODE(ltermProcessXMLTermSequence,52,(paramString, strLength)); + + /* All parsed characters have been consumed at this point (including BEL) */ + *consumed = offset+1; + + /* Default parameter values: 0, 0, 0 */ + param1 = (paramCount > 0) ? paramValues[0] : 0; + param2 = (paramCount > 1) ? paramValues[1] : 0; + param3 = (paramCount > 2) ? paramValues[2] : 0; + + switch (termChar) { + int streamOpcodes; + + case U_D_CHAR: /* Set debugging messageLevel/search-string */ + LTERM_LOG(ltermProcessXMLTermSequence,52,("Setting message level etc.\n")); + if (strLength == 0) { + tlog_set_level(param1, param2, NULL); + } else { + tlog_set_level(param1, param2, paramCString); + } + return 0; + + case U_E_CHAR: /* Enable/disable input echo setting */ + if (param1) { + /* Enable input echo */ + lts->disabledInputEcho = 0; + + LTERM_LOG(ltermProcessXMLTermSequence,52,("Enabled input echo\n")); + } else { + /* Disable input echo */ + lts->disabledInputEcho = 1; + + LTERM_LOG(ltermProcessXMLTermSequence,52,("Disabled input echo\n")); + } + return 0; + + case U_R_CHAR: /* Enable/disable raw input mode */ + if (param1) { + /* Switch to raw input mode */ + ltermSwitchToRawMode(lts); + + LTERM_LOG(ltermProcessXMLTermSequence,52,("Raw input mode\n")); + + } else { + /* Switch to regular input mode */ + ltermClearInputLine(lts); + + LTERM_LOG(ltermProcessXMLTermSequence,52,("Line input mode\n")); + } + return 0; + + case U_S_CHAR: /* Switch to null-terminated stream mode, with cookie */ + + if (lto->outputMode == LTERM1_SCREEN_MODE) { + *opcodes = LTERM_SCREENDATA_CODE | LTERM_OUTPUT_CODE; + } else if (lto->outputMode == LTERM2_LINE_MODE) { + *opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE; + } + + assert(lto->outputMode != LTERM0_STREAM_MODE); + + /* Set stream codes */ + streamOpcodes = 0; + + if (param1) + streamOpcodes |= LTERM_XMLSTREAM_CODE; + + if (param2) + streamOpcodes |= LTERM_DOCSTREAM_CODE; + + if (param3) + streamOpcodes |= LTERM_WINSTREAM_CODE; + + /* Check if cookie matches */ + if ((strLength > 0) && (strcmp(paramCString, lts->cookie) == 0)) { + streamOpcodes |= LTERM_COOKIESTR_CODE; + } + + LTERM_LOG(ltermProcessXMLTermSequence,52, + ("Switching to stream mode, codes=0x%x\n", streamOpcodes)); + + if (0 != ltermSwitchToStreamMode(lts, streamOpcodes, NULL)) + return -1; + + return 0; + + default: /* Unknown escape sequence */ + LTERM_WARNING("ltermProcessXMLTermSequence: Warning - unknown sequence %c\n", + termChar); + return 0; + } + + return 0; +} + + +/** Insert/delete/erase COUNT characters at current output cursor position. + * ACTION = LTERM_INSERT_CHAR (insert) + * LTERM_DELETE_CHAR (delete) + * LTERM_ERASE_CHAR (erase) + * @return 0 on success and -1 on error. + */ +int ltermInsDelEraseChar(struct lterms *lts, int count, int action) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int charCount = count; + int j; + + assert(count >= 0); + + LTERM_LOG(ltermInsDelEraseChar,60,("count=%d, action=%d\n", + count, action)); + + if (lto->outputMode == LTERM2_LINE_MODE) { + /* Line mode */ + switch (action) { + + case LTERM_INSERT_CHAR: + + if (lto->outputChars + charCount > MAXCOLM1) { + /* Output buffer overflow; ignore extra inserts */ + LTERM_WARNING("ltermInsDelEraseChar: Warning - output line buffer overflow\n"); + charCount = MAXCOLM1 - lto->outputChars; + } + + LTERM_LOG(ltermInsDelEraseChar,62,("Line insert %d blank chars\n", + charCount)); + + /* Shift characters to the right to make room for insertion */ + for (j=lto->outputChars-1; j>=lto->outputCursorChar; j--) { + lto->outputLine[j+charCount] = lto->outputLine[j]; + lto->outputStyle[j+charCount] = lto->outputStyle[j]; + } + + /* Insert blank characters */ + for (j=lto->outputCursorChar; joutputCursorChar+charCount; j++) { + lto->outputLine[j] = U_SPACE; + lto->outputStyle[j] = LTERM_STDOUT_STYLE | lto->styleMask; + } + + /* Increment character count */ + lto->outputChars += charCount; + break; + + case LTERM_DELETE_CHAR: + if (lto->outputCursorChar+charCount > lto->outputChars) + charCount = lto->outputChars - lto->outputCursorChar; + + LTERM_LOG(ltermInsDelEraseChar,62,("Delete %d chars\n", + charCount)); + + /* Shift characters to the left */ + for (j=lto->outputCursorChar; joutputChars-charCount; j++) { + lto->outputLine[j] = lto->outputLine[j+charCount]; + lto->outputStyle[j] = lto->outputStyle[j+charCount]; + } + + /* Decrement character count */ + lto->outputChars -= charCount; + break; + + case LTERM_ERASE_CHAR: + if (lto->outputCursorChar+charCount > lto->outputChars) + charCount = lto->outputChars - lto->outputCursorChar; + + LTERM_LOG(ltermInsDelEraseChar,62,("Erase %d chars\n", + charCount)); + + /* Erase characters */ + for (j=lto->outputCursorChar; joutputCursorChar+charCount; j++) { + lto->outputLine[j] = U_SPACE; + lto->outputStyle[j] = LTERM_STDOUT_STYLE | lto->styleMask; + } + + break; + } + + /* Note modifications */ + if (lto->outputCursorChar < lto->outputModifiedChar) + lto->outputModifiedChar = lto->outputCursorChar; + + } else if (lto->outputMode == LTERM1_SCREEN_MODE) { + /* Screen mode */ + } + + return 0; +} diff --git a/mozilla/extensions/xmlterm/base/ltermIO.c b/mozilla/extensions/xmlterm/base/ltermIO.c new file mode 100644 index 00000000000..cc1ca427839 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ltermIO.c @@ -0,0 +1,1113 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ltermIO.c: LTERM PTY input/output data processing + */ + +/* public declarations */ +#include "lineterm.h" + +/* private declarations */ +#include "ltermPrivate.h" + + +static int ltermWrite(struct lterms *lts, int *opcodes); + +static int ltermReturnStreamData(struct lterms *lts, struct LtermRead *ltr); +static int ltermReturnScreenData(struct lterms *lts, struct LtermRead *ltr); +static int ltermReturnInputLine(struct lterms *lts, struct LtermRead *ltr); +static int ltermReturnOutputLine(struct lterms *lts, struct LtermRead *ltr); + + +/** Transmits input line + optional control character UCH to child process. + * If UCH is 0, no control character is transmitted. + * Copy of the transmitted plain text (without any markup or character escapes) + * is saved in the echo buffer, prefixed by the prompt. + * If echoControl is true, control character is echoed in printable form. + * If completionCode == LTERM_NO_COMPLETION, transmit complete line + * and set input line break flag. + * If completionCode != LTERM_NO_COMPLETION, transmit only characters to + * left of current and set completion request flag. + * Called from ltermLineInput. + * @return 0 on success, -1 on error. + */ +int ltermSendLine(struct lterms *lts, UNICHAR uch, + int echoControl, int completionCode) +{ + struct LtermInput *lti = &(lts->ltermInput); + struct LtermOutput *lto = &(lts->ltermOutput); + UNICHAR insch; + int glyphCount, prefixChars, charCount, sendCount; + int j, k, startCol, nCols, charIndex; + + LTERM_LOG(ltermSendLine,40, + ("uch=0x%x, echoControl=%d, completionCode=%d, completionRequest=%d\n", + uch, echoControl, completionCode, lts->completionRequest)); + + if ((lts->completionRequest == LTERM_HISTORY_COMPLETION) && + (lts->completionChars > 0)) { + /* Delete prior completion inserts */ + if (ltermDeleteGlyphs(lti, lts->completionChars) != 0) + return -1; + } + + if (completionCode != LTERM_NO_COMPLETION) { + /* Send only glyphs to left of cursor */ + glyphCount = lti->inputCursorGlyph; + + } else { + /* Send all glyphs in input line */ + glyphCount = lti->inputGlyphs; + } + + if (lto->promptChars > 0) { + /* Insert output prompt into echo buffer */ + prefixChars = lto->promptChars; + } else { + /* Insert entire output line into echo buffer */ + prefixChars = lto->outputChars; + } + + charCount = prefixChars; + + LTERM_LOG(ltermSendLine,42, + ("lto->promptChars=%d, outputChars=%d, glyphCount=%d\n", + lto->promptChars, lto->outputChars, glyphCount)); + + if (charCount >= MAXCOLM1) { + /* Buffer overflow; error return */ + LTERM_ERROR("ltermSendLine: Error - character buffer overflow\n"); + return -1; + } + + for (j=0; jechoLine[j] = lto->outputLine[j]; + + /* Append input line */ + for (j=0; jinputGlyphColIndex[j]; + nCols = lti->inputGlyphColIndex[j+1] - startCol; + + for (k=startCol; kinputColCharIndex[k]; + + insch = lti->inputLine[charIndex]; + +#if 0 + /* COMMENTED OUT: Plain text not escaped; use later in HTML insert */ + if (insch == U_AMPERSAND) { + /* Escaped character */ + + /* Assert that there is one free character position in buffer */ + assert(lti->inputChars < MAXCOL); + + /* Insert null character at the end of the input buffer */ + lti->inputLine[lti->inputChars] = U_NUL; + + /* Match escape sequence against known escape sequences */ + for (m=0; minputLine+charIndex, + ltermGlobal.escapeSeq[m], + (unsigned int) ltermGlobal.escapeLen[m]) == 0) + break; + } + + if (m < LTERM_XML_ESCAPES) { + /* Subsitute single character for escape sequence */ + insch = (UNICHAR) ltermGlobal.escapeChars[m]; + } else { + LTERM_WARNING("ltermSendLine: Warning - unknown XML character escape sequence\n"); + } + } +#endif /* 0 */ + + if (charCount >= MAXCOLM1) { + /* Buffer overflow; error return */ + LTERM_ERROR("ltermSendLine: Error - character buffer overflow\n"); + return -1; + + } else { + /* Insert character into echo line buffer */ + lts->echoLine[charCount++] = insch; + } + } + } + + + /* Transmit data to process */ + sendCount = charCount - prefixChars; + + if (lts->completionRequest != LTERM_NO_COMPLETION) { + /* Completion already requested */ + + /* Send only control character */ + if (uch != U_NUL) { + if (ltermSendData(lts, &uch, 1) != 0) + return -1; + } + + } else { + if (uch != U_NUL) { + /* Send line+control character to child process */ + + /* Insert control character at the end of the buffer (temporarily) */ + lts->echoLine[charCount] = uch; + + sendCount++; + } + + if (ltermSendData(lts, lts->echoLine+prefixChars, sendCount) != 0) + return -1; + } + + if (completionCode != LTERM_NO_COMPLETION) { + /* Request completion */ + lts->completionRequest = completionCode; + + /* No completion text inserted yet */ + lts->completionChars = 0; + + } else { + /* Set input line break flag; + * cleared only by output line break processing + */ + lts->inputLineBreak = 1; + } + + if (echoControl && (charCount+2 < MAXCOLM1)) { + /* Echo control character in printable form */ + lts->echoLine[charCount++] = U_CARET; + lts->echoLine[charCount++] = U_ATSIGN + uch; + } + + /* Set count of echo characters (excluding control character) */ + lts->echoChars = charCount; + + LTERM_LOG(ltermSendLine,41,("glyphCount=%d, sendCount=%d\n", + glyphCount, sendCount)); + LTERM_LOGUNICODE(ltermSendLine,41,(lts->echoLine, charCount)); + + return 0; +} + + +/** Writes data from input buffer pipe to pseudo-TTY, + * processing one complete record read from input buffer pipe + * and returning + * OPCODES ::= LINEDATA ( INPUT ( NEWLINE HIDE? )? + * | INPUT META ( COMPLETION | NEWLINE HIDE? ) ) + * NOTE: This call may block to read data from input buffer pipe, + * if lts->inputBufRecord is false. + * Non-zero OPCODES means echoable input line data was processed. + * Zero OPCODES implies that no echoable input data was processed, i.e., + * an incomplete record or screen/output data processing. + * @return 0 if successful, + * -1 on error, and + * -2 if pseudo-TTY has been closed. + */ +int ltermWrite(struct lterms *lts, int *opcodes) +{ + struct LtermInput *lti = &(lts->ltermInput); + struct LtermOutput *lto = &(lts->ltermOutput); + char *byteBuf = (char *) lti->inputBuf; + int returnCode, availableChars, processedChars, headerChars, totalChars, j; + + LTERM_LOG(ltermWrite,20, ("inputLineBreak=%d, inputBufRecord=%d\n", + lts->inputLineBreak, lts->inputBufRecord)); + + *opcodes = 0; + + if (!lts->inputBufRecord) { + /* Complete record not available in buffer; read data from input pipe */ + int readMax, n_read; + + readMax = (PIPEHEADER+MAXCOL)*sizeof(UNICHAR) - lti->inputBufBytes; + + assert(readMax > 0); + + n_read = READ(lts->readBUFFER, byteBuf + lti->inputBufBytes, + (SIZE_T) readMax); + + if (n_read < 0) { + LTERM_WARNING("ltermWrite: Warning - error %d in reading from input buffer pipe\n", n_read); + return -1; + } + + LTERM_LOG(ltermWrite,22, + ("read %d bytes from input buffer pipe\n", n_read)); + + if (n_read == 0) { + /* End of file */ + LTERM_LOG(ltermWrite,21,("input buffer pipe has been closed\n")); + + /* Suspend LTERM */ + lts->suspended = 1; + + return -2; + } + + /* Update count of bytes read so far */ + lti->inputBufBytes += n_read; + + LTERM_LOGUNICODE(ltermWrite,12,(lti->inputBuf, + lti->inputBufBytes/sizeof(UNICHAR))); + + /* Check if one or more complete records is now available in buffer */ + lts->inputBufRecord = (lti->inputBufBytes >= sizeof(UNICHAR)) && + (lti->inputBufBytes >= (PIPEHEADER+lti->inputBuf[0])*sizeof(UNICHAR)); + + if (!lts->inputBufRecord) { + /* Incomplete input record; return */ + return 0; + } + } + + /* availableChars may be zero; such zero length input data records + * are used to notify the "input thread" about output processing events, + * such as the detection of a command line prompt (which would + * enable the command completion input mode) + */ + availableChars = lti->inputBuf[0]; + processedChars = 0; + + LTERM_LOG(ltermWrite,22, ("inputBuf[0]=%d, inputBuf[1]=%d\n", + lti->inputBuf[0], lti->inputBuf[1])); + + if (lti->inputBuf[1] == LTERM_WRITE_CLOSE_MESSAGE) { + /* LTERM being closed */ + return -2; + } + + if (lti->inputBuf[1] == LTERM_WRITE_PLAIN_INPUT) { + /* Process plain text input record */ + int doNotCancelCompletion = 0; + + if ( (lti->inputMode >= LTERM3_COMPLETION_MODE) && + (availableChars == 1) ) { + + doNotCancelCompletion = + ((lts->completionRequest == LTERM_TAB_COMPLETION) && + (lti->inputBuf[2] == U_TAB)) || + ((lts->completionRequest == LTERM_HISTORY_COMPLETION) && + ((lti->inputBuf[2] == U_CTL_P) || (lti->inputBuf[2] == U_CTL_N)) ); + } + + if (!doNotCancelCompletion && + (lts->completionRequest != LTERM_NO_COMPLETION)) { + /* Cancel any completion request */ + + if (ltermCancelCompletion(lts) != 0) + return -1; + } + + LTERM_LOGUNICODE(ltermWrite,12,(lti->inputBuf+PIPEHEADER, availableChars)); + + returnCode = ltermPlainTextInput(lts, lti->inputBuf+PIPEHEADER, + availableChars, opcodes); + if (returnCode < 0) + return returnCode; + + processedChars = availableChars; + + } else if (lti->inputBuf[1] == LTERM_WRITE_XML_INPUT) { + /* Insert complete XML element into input line, after checks */ + + if (lts->completionRequest != LTERM_NO_COMPLETION) { + /* Cancel command completion request */ + if (ltermCancelCompletion(lts) != 0) + return -1; + } + + LTERM_WARNING("ltermWrite: Warning - LTERM_WRITE_XML_INPUT not yet implemented\n"); + + processedChars = availableChars; + + } else if (lti->inputBuf[1] == LTERM_WRITE_PLAIN_OUTPUT) { + /* Insert plain text in decoded character buffer */ + int decodeMax = MAXCOLM1 - lto->decodedChars; + + processedChars = availableChars; + + if (processedChars > decodeMax) + processedChars = decodeMax; + + if (processedChars > 0) { + /* Copy characters to decoded character buffer */ + int offset; + + if ((lto->decodedChars > 0) && + lto->incompleteEscapeSequence && + (lto->decodedStyle[0] != LTERM_ALTOUT_STYLE)) { + /* Move incomplete escape sequence to end of decoded buffer */ + for (j=lto->decodedChars-1; j>=0; j--) { + lto->decodedOutput[j+processedChars] = lto->decodedOutput[j]; + lto->decodedStyle[j+processedChars] = lto->decodedStyle[j]; + } + + /* Incomplete escape sequence no longer at beginning of buffer */ + lto->incompleteEscapeSequence = 0; + + /* Insert new characters at beginning of decoded buffer */ + offset = 0; + + } else { + /* Append new characters at the end of the decoded buffer */ + offset = lto->decodedChars; + } + + /* Insert new characters in decoded buffer, with appropriate offset */ + for (j=0; jdecodedOutput[j+offset] = lti->inputBuf[PIPEHEADER+j]; + lto->decodedStyle[j+offset] = LTERM_ALTOUT_STYLE; + } + + /* Increment decoded character count */ + lto->decodedChars += processedChars; + } + + returnCode = 0; + } + + if (processedChars == availableChars) { + /* Delete current record completely from buffer */ + processedChars += PIPEHEADER; + headerChars = 0; + + } else { + /* Delete processed characters from current record */ + headerChars = PIPEHEADER; + + /* Decrement character count in record header */ + lti->inputBuf[0] -= processedChars; + } + + LTERM_LOG(ltermWrite,23, ("processedChars=%d, headerChars=%d\n", + processedChars, headerChars)); + + /* Shift remaining data in buffer */ + totalChars = lti->inputBufBytes/sizeof(UNICHAR); + + for (j=headerChars; j<(totalChars-processedChars); j++) + lti->inputBuf[j] = lti->inputBuf[j+processedChars]; + + /* Decrement buffer count */ + lti->inputBufBytes -= processedChars*sizeof(UNICHAR); + + /* Check if one or more complete records is now left in buffer */ + lts->inputBufRecord = (lti->inputBufBytes >= sizeof(UNICHAR)) && + (lti->inputBufBytes >= (PIPEHEADER+lti->inputBuf[0])*sizeof(UNICHAR)); + + LTERM_LOG(ltermWrite,21, + ("return opcodes=0x%x, inputBufBytes=%d, inputBufRecord=%d\n", + *opcodes, lti->inputBufBytes, lts->inputBufRecord)); + + return 0; +} + + +/** Reads a (possibly incomplete) line from LTERM. + * The LtermRead structure *LTR contains both input and output parameters, + * returning opcodes values of + * OPCODES ::= STREAMDATA NEWLINE? COOKIESTR? XMLSTREAM? DOCSTREAM? WINSTREAM? + * if StreamMode data is being returned. + * + * OPCODES ::= SCREENDATA BELL? ( CLEAR + * | INSERT MOVEDOWN? + * | DELETE MOVEDOWN? + * | OUTPUT ) + * if ScreenMode data is being returned. + * + * OPCODES ::= LINEDATA BELL? ( CLEAR + * | OUTPUT NEWLINE? ) + * if LineMode data is being returned. + * + * (Auxiliary procedure for lterm_read.) + * @return 0 if successful, + * -1 if an error occurred while reading, + * -2 if pseudo-TTY has been closed, + * -3 if more than MAX_COUNT characters are present in the line + * (in this case the first MAX_COUNT characters are returned in BUF, + * and the rest are discarded). + */ +int ltermRead(struct lterms *lts, struct LtermRead *ltr, int timeout) +{ + struct LtermInput *lti = &(lts->ltermInput); + struct LtermOutput *lto = &(lts->ltermOutput); + int waitTime, nfds_all, pollCode, rePoll; + int inputAvailable, newOutputAvailable; + int outOpcodes, returnCode; + int j; + + LTERM_LOG(ltermRead,20,("start outputMode=%d\n", lto->outputMode)); + + waitTime = timeout; + + if (lts->inputBufRecord) { + /* Complete input record available in buffer */ + + LTERM_LOG(ltermRead,21,("inputBufRecord=%d\n", lts->inputBufRecord)); + waitTime = 0; + + } else if ((lto->decodedChars > 0) && !lto->incompleteEscapeSequence) { + /* Do not wait if there are decoded characters to be processed that are + not part of an incomplete ESCAPE sequence */ + + LTERM_LOG(ltermRead,21,("decodedChars=%d,incompleteEscapeSequence=%d\n", + lto->decodedChars, lto->incompleteEscapeSequence)); + + waitTime = 0; + + } else if (lto->outputMode == LTERM1_SCREEN_MODE) { + /* Screen mode: do not wait if there are any modified rows */ + for (j=0; jnRows; j++) + if (lto->modifiedCol[j] >= 0) { + waitTime = 0; + break; + } + + if (waitTime == 0) { + LTERM_LOG(ltermRead,21,("j=%d, modifiedCol[j] = %d\n", + j, lto->modifiedCol[j])); + } + } + + /* If stream mode, do not poll STDERR output */ + if (lto->outputMode == LTERM0_STREAM_MODE) + nfds_all = POLL_COUNT-1; + else + nfds_all = lto->nfds; + + + do { + /* Do not re-poll unless something special occurs */ + rePoll = 0; + + /* Default return values in LtermRead structure */ + ltr->read_count = 0; + ltr->opcodes = 0; + ltr->buf_row = -1; + ltr->buf_col = -1; + ltr->cursor_row = -1; + ltr->cursor_col = -1; + + LTERM_LOG(ltermRead,21,("polling nfds = %d, waitTime = %d\n", + lto->nfds, waitTime)); + + /* Poll all files for data to read */ + pollCode = POLL(lto->pollFD, (SIZE_T) lto->nfds, waitTime); + + if (pollCode == -1) { + LTERM_ERROR( "ltermRead: Error return from poll\n"); + return -1; + } + + /* Do not wait for polling the second time around */ + waitTime = 0; + + /* Check if input data is available */ + inputAvailable = lts->inputBufRecord || + ( (pollCode > 0) && + (lto->pollFD[POLL_INPUTBUF].POLL_REVENTS != 0) ); + + /* Check if STDOUT/STDERR data is available */ + newOutputAvailable = (pollCode > 0) && + ( (lto->pollFD[POLL_STDOUT].POLL_REVENTS != 0) || + (lto->pollFD[POLL_STDERR].POLL_REVENTS != 0) ); + + LTERM_LOG(ltermRead,21, + ("inputAvailable=%d, newOutputAvailable=%d, completionRequest=%d\n", + inputAvailable, newOutputAvailable, lts->completionRequest)); + + if (inputAvailable && (!newOutputAvailable || + (lts->completionRequest == LTERM_NO_COMPLETION)) ) { + /* Process an input data record; either no new output is available, or + * output is available but command completion has not been requested + */ + int inOpcodes; + + returnCode = ltermWrite(lts, &inOpcodes); + if (returnCode < 0) + return returnCode; + + if (inOpcodes != 0) { + /* Echoable input data processed; return input line */ + returnCode = ltermReturnInputLine(lts, ltr); + if (returnCode < 0) + return returnCode; + + if (inOpcodes & LTERM_META_CODE) { + ltr->opcodes |= LTERM_META_CODE; + + if (inOpcodes & LTERM_COMPLETION_CODE) + ltr->opcodes |= LTERM_COMPLETION_CODE; + } + + if (inOpcodes & LTERM_NEWLINE_CODE) { + /* Input line break */ + ltr->opcodes |= LTERM_NEWLINE_CODE; + + if (inOpcodes & LTERM_HIDE_CODE) + ltr->opcodes |= LTERM_HIDE_CODE; + + /* Clear input line buffer */ + ltermClearInputLine(lts); + } + + if (lts->disabledInputEcho) { + /* Input echo is disabled, re-poll */ + rePoll = 1; + LTERM_LOG(ltermRead,32,("Input echo disabled; RE-POLLING\n\n")); + continue; + } + + return 0; + } + + inputAvailable = 0; + } + + if (newOutputAvailable) { + /* Read data from STDOUT/STDERR */ + int outChars; + + outChars = ltermReceiveData(lts, nfds_all==POLL_COUNT); + if (outChars < 0) + return outChars; + } + + if (lto->outputMode == LTERM0_STREAM_MODE) { + /* Stream mode */ + return ltermReturnStreamData(lts, ltr); + } + + /* If there is some complete decoded output, process it */ + if ((lto->decodedChars > 0) && !lto->incompleteEscapeSequence) { + returnCode = ltermProcessOutput(lts, &outOpcodes); + if (returnCode < 0) + return -1; + + } else { + /* No new output to process */ + if (lto->outputMode == LTERM1_SCREEN_MODE) { + outOpcodes = LTERM_SCREENDATA_CODE | LTERM_OUTPUT_CODE; + } else { + /* No new output in line mode; return nothing */ + return 0; + } + } + + if (outOpcodes & LTERM_SCREENDATA_CODE) { + + if (outOpcodes & LTERM_OUTPUT_CODE) { + /* Return screen mode output */ + return ltermReturnScreenData(lts, ltr); + + } else { + /* Screen mode data with modifier flags; return just cursor position */ + ltr->opcodes = outOpcodes; + + /* Copy full screen cursor position */ + ltr->cursor_row = lto->cursorRow; + ltr->cursor_col = lto->cursorCol; + + ltr->read_count = 0; + + return 0; + } + } + + if (outOpcodes & LTERM_LINEDATA_CODE) { + + LTERM_LOG(ltermRead,32, + ("inputLineBreak=%d, completionRequest=%d, completionChars=%d\n", + lts->inputLineBreak, lts->completionRequest, lts->completionChars)); + + if (outOpcodes & LTERM_OUTPUT_CODE) { + /* Return output line */ + int echoMatch = 0; + + returnCode = ltermReturnOutputLine(lts, ltr); + if (returnCode < 0) + return returnCode; + + if (lts->inputLineBreak) { + /* Compare output line to initial portion of echo line */ + echoMatch = 1; + + if ( (ltr->read_count > lts->echoChars) || + ((ltr->read_count != lts->echoChars) && + (outOpcodes & LTERM_NEWLINE_CODE)) ) { + echoMatch = 0; + } else { + int k; + for (k=0; kread_count; k++) { + if (ltr->buf[k] != lts->echoLine[k]) { + echoMatch = 0; + break; + } + } + } + } + + if (outOpcodes & LTERM_NEWLINE_CODE) { + /* Complete output line */ + if (!echoMatch) + ltr->opcodes |= LTERM_NEWLINE_CODE; + + /* Clear output line buffer */ + ltermClearOutputLine(lts); + + /* Clear input line break flag */ + lts->inputLineBreak = 0; + + } else { + /* Incomplete output line */ + + if (lts->completionRequest != LTERM_NO_COMPLETION) { + /* Completion requested; + * Compare first/last part of output line to parts of echo line + */ + int k; + int extraChars = ltr->read_count - lts->echoChars; + int compChars = ltr->read_count; + int preMatch = 1; + + if (extraChars > 0) + compChars = lts->echoChars; + + for (k=0; kbuf[k] != lts->echoLine[k]) { + preMatch = 0; + break; + } + } + + if (!preMatch) { + /* No match; cancel completion request */ + if (ltermCancelCompletion(lts) != 0) + return -1; + + } else if (extraChars >= 0) { + /* Matched complete echo line and perhaps more */ + + if ((extraChars > 0) && (extraChars <= MAXCOLM1)) { + /* Insert extra characters into input line */ + lts->completionChars = extraChars; + + for (k=0; kbuf[compChars+k]) != 0) + return -1; + } + + LTERM_LOG(ltermRead,32, + ("++++++++++++ COMPLETION SUCCESSFUL\n")); + + LTERM_LOGUNICODE(ltermRead,32, + (ltr->buf+compChars, extraChars)); + } + + /* Return updated input line, prefixed with prompt */ + returnCode = ltermReturnInputLine(lts, ltr); + if (returnCode < 0) + return returnCode; + + } else { + /* Partial match; do not echo */ + echoMatch = 1; + } + + } else if (lto->promptChars == lto->outputChars) { + /* Incomplete output line with just a prompt */ + + LTERM_LOG(ltermRead,32,("Prompt-only line\n")); + + /* Return updated input line, prefixed with prompt */ + returnCode = ltermReturnInputLine(lts, ltr); + if (returnCode < 0) + return returnCode; + } + } + + if (echoMatch) { + /* Do not display output line; re-poll */ + rePoll = 1; + LTERM_LOG(ltermRead,32,("Echo match; RE-POLLING\n\n")); + continue; + } else { + return 0; + } + + } else { + /* Line mode data with modifier flags; return just cursor position */ + ltr->opcodes = outOpcodes; + + /* Copy full screen cursor position */ + ltr->cursor_row = -1; + ltr->cursor_col = 0; + + ltr->read_count = 0; + + return 0; + } + } + + } while (rePoll); + + return -1; +} + + +/** Returns stream data from STDOUT + * (Auxiliary procedure for ltermRead.) + * OPCODES ::= STREAMDATA NEWLINE? COOKIESTR? XMLSTREAM? DOCSTREAM? WINSTREAM? + * The LtermRead structure *LTR contains both input and output parameters. + * @return 0 if successful, + * -1 if an error occurred while reading, + */ +static int ltermReturnStreamData(struct lterms *lts, struct LtermRead *ltr) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + UNICHAR *locTerminator; + int streamTerminated, charCount, deleteCount, j; + + LTERM_LOG(ltermReturnStreamData,30,("start\n")); + + if (lto->decodedChars == 0) + return 0; + + ltr->opcodes = LTERM_STREAMDATA_CODE | lto->streamOpcodes; + + if (ucslen(lto->streamTerminator) == 0) { + /* Null terminated stream */ + locTerminator = NULL; + for (j=0; jdecodedChars; j++) { + if (lto->decodedOutput[j] == 0) { + locTerminator = <o->decodedOutput[j]; + break; + } + } + + } else { + /* Non-null terminated stream */ + assert(lto->decodedChars < MAXCOL); + + /* Insert terminating null character in decoded buffer */ + lto->decodedOutput[lto->decodedChars] = U_NUL; + + /* There should be no NULs in decoded output */ + assert(ucslen(lto->decodedOutput) == lto->decodedChars); + + /* Search for stream terminator string in decoded output */ + locTerminator = ucsucs(lto->decodedOutput, lto->streamTerminator); + } + + /* Stream termination flag */ + streamTerminated = 0; + + if (locTerminator == NULL) { + /* No terminator found; return decoded stream data */ + charCount = lto->decodedChars; + if (charCount > ltr->max_count) + charCount = ltr->max_count; + + } else { + /* Count stream portion of decoded output (excluding terminator) */ + charCount = locTerminator - lto->decodedOutput; + + if (charCount > ltr->max_count) { + /* Return only portion of stream data that fits into output buffer, + * without terminating stream mode + */ + charCount = ltr->max_count; + + } else { + /* Return all remaining stream data, terminate stream mode and + * revert to saved output mode + */ + streamTerminated = 1; + if (lto->savedOutputMode == LTERM1_SCREEN_MODE) { + if (ltermSwitchToScreenMode(lts) != 0) + return -1; + } else { + if (ltermSwitchToLineMode(lts) != 0) + return -1; + } + LTERM_LOG(ltermReturnStreamData,22,("terminating STREAM mode\n")); + } + } + + /* Copy stream data to output buffer */ + for (j=0; jbuf[j] = lto->decodedOutput[j]; + ltr->style[j] = LTERM_STDOUT_STYLE; + } + + /* Count of characters read */ + ltr->read_count = charCount; + + /* Count of characters to be deleted */ + deleteCount = charCount; + + if (streamTerminated) { + /* Stream terminated */ + ltr->opcodes |= LTERM_NEWLINE_CODE; + + /* Delete terminator string from decoded buffer */ + if (ucslen(lto->streamTerminator) == 0) { + deleteCount += 1; + } else { + deleteCount += ucslen(lto->streamTerminator); + } + } + + /* Shift remaining characters in decoded buffer */ + for (j=deleteCount; jdecodedChars; j++) + lto->decodedOutput[j-deleteCount] = lto->decodedOutput[j]; + + lto->decodedChars -= deleteCount; + + LTERM_LOG(ltermReturnStreamData,31,("returning STREAM data (%d bytes)\n", + ltr->read_count)); + + return 0; +} + + +/** Returns processed screen data + * (Auxiliary procedure for ltermRead.) + * The LtermRead structure *LTR contains both input and output parameters. + * @return 0 if successful, + * -1 if an error occurred while reading, + * -3 if more than COUNT characters are present in the line + * (in this case the first COUNT characters are returned in BUF, + * and the rest are discarded). + */ +static int ltermReturnScreenData(struct lterms *lts, struct LtermRead *ltr) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int returnRow, charCount, returnCode; + int jOffset, j; + + LTERM_LOG(ltermReturnScreenData,30,("start\n")); + + /* Copy full screen cursor position */ + ltr->cursor_row = lto->cursorRow; + ltr->cursor_col = lto->cursorCol; + + /* Check if any row has been modified */ + returnRow = -1; + + for (j=0; jnRows; j++) + if (lto->modifiedCol[j] >= 0) { + returnRow = j; + break; + } + + if (returnRow < 0) { + /* No modified rows; return no data */ + ltr->opcodes = 0; + return 0; + } + + /* Returning screen mode data without modifiers */ + ltr->opcodes = LTERM_SCREENDATA_CODE; + + charCount = lts->nCols - lto->modifiedCol[returnRow]; + + if (charCount <= ltr->max_count) { + returnCode = 0; + } else { + /* Too much data to fit into output buffer; truncate */ + charCount = ltr->max_count; + returnCode = -3; + } + + /* Copy modified part of row and return */ + ltr->buf_row = returnRow; + ltr->buf_col = lto->modifiedCol[returnRow]; + + jOffset = ltr->buf_row * lts->nCols + ltr->buf_col; + for (j=0; jbuf[j] = lto->screenChar[jOffset+j]; + ltr->style[j] = lto->screenStyle[jOffset+j]; + } + + /* Clear modified flag in returned row */ + lto->modifiedCol[returnRow] = -1; + + ltr->read_count = charCount; + + LTERM_LOG(ltermReturnScreenData,31,("returning SCREEN data\n")); + LTERM_LOGUNICODE(ltermReturnScreenData,31,(ltr->buf, ltr->read_count)); + + return returnCode; +} + + +/** Returns incomplete input line, prefixed with prompt or incomplete output. + * (Auxiliary procedure for ltermRead.) + * The LtermRead structure *LTR contains both input and output parameters. + * @return 0 if successful, + * -1 if an error occurred while reading, + * -3 if more than COUNT characters are present in the line + * (in this case the first COUNT characters are returned in BUF, + * and the rest are discarded). + */ +static int ltermReturnInputLine(struct lterms *lts, struct LtermRead *ltr) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + struct LtermInput *lti = &(lts->ltermInput); + int outChars, charCount, inputCursorCol, returnCode; + int j; + + LTERM_LOG(ltermReturnInputLine,30, ("outputChars=%d, promptChars=%d\n", + lto->outputChars, lto->promptChars)); + + if (lto->promptChars > 0) { + /* Prefix with prompt portion of output only */ + ltr->opcodes = LTERM_LINEDATA_CODE; + + outChars = lto->promptChars; + if (outChars > ltr->max_count) + outChars = 0; + + if (outChars > 0) { + ltr->opcodes |= LTERM_PROMPT_CODE; + for (j=0; jbuf[j] = lto->outputLine[j]; + ltr->style[j] = LTERM_PROMPT_STYLE; + } + } + + } else { + /* Prefix with entire output line */ + returnCode = ltermReturnOutputLine(lts, ltr); + if (returnCode < 0) + return returnCode; + + outChars = ltr->read_count; + } + + ltr->opcodes |= LTERM_INPUT_CODE; + + charCount = outChars + lti->inputChars; + + if (charCount <= ltr->max_count) { + returnCode = 0; + } else { + /* Too much data to fit into output buffer; truncate */ + charCount = ltr->max_count; + returnCode = -3; + } + + /* Append STDIN data, with markup and escape sequences */ + for (j=outChars; jbuf[j] = lti->inputLine[j-outChars]; + ltr->style[j] = LTERM_STDIN_STYLE; + } + + inputCursorCol = lti->inputGlyphColIndex[lti->inputCursorGlyph]; + + ltr->buf_row = -1; + ltr->buf_col = 0; + + ltr->cursor_row = -1; + ltr->cursor_col = outChars + lti->inputColCharIndex[inputCursorCol]; + + ltr->read_count = charCount; + + LTERM_LOG(ltermReturnInputLine,32,("returning INPUT LINE data\n")); + LTERM_LOGUNICODE(ltermReturnInputLine,32,(ltr->buf, ltr->read_count)); + + return returnCode; +} + + +/** Returns output line data + * (Auxiliary procedure for ltermRead.) + * The LtermRead structure *LTR contains both input and output parameters. + * @return 0 if successful, + * -1 if an error occurred while reading, + * -3 if more than COUNT characters are present in the line + * (in this case the first COUNT characters are returned in BUF, + * and the rest are discarded). + */ +static int ltermReturnOutputLine(struct lterms *lts, struct LtermRead *ltr) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int charCount, returnCode, j; + + LTERM_LOG(ltermReturnOutputLine,30, + ("outputChars=%d, promptChars=%d, CursorChar=%d\n", + lto->outputChars, lto->promptChars, lto->outputCursorChar)); + + ltr->opcodes = LTERM_LINEDATA_CODE; + + charCount = lto->outputChars; + + if (charCount <= ltr->max_count) { + returnCode = 0; + } else { + /* Too much data to fit into output buffer; truncate */ + charCount = ltr->max_count; + returnCode = -3; + } + + if ((lto->promptChars > 0) && (lto->promptChars == lto->outputChars)) { + /* Copy prompt characters (plain text; no markup or escape sequences) */ + ltr->opcodes |= LTERM_PROMPT_CODE; + for (j=0; jbuf[j] = lto->outputLine[j]; + ltr->style[j] = LTERM_PROMPT_STYLE; + } + } else { + /* Copy output characters (plain text; no markup or escape sequences) */ + ltr->opcodes |= LTERM_OUTPUT_CODE; + for (j=0; jbuf[j] = lto->outputLine[j]; + ltr->style[j] = lto->outputStyle[j]; + } + } + + ltr->buf_row = -1; + ltr->buf_col = 0; + + ltr->cursor_row = -1; + ltr->cursor_col = lto->outputCursorChar; + + ltr->read_count = charCount; + + LTERM_LOG(ltermReturnOutputLine,31,("returning OUTPUT LINE data\n")); + LTERM_LOGUNICODE(ltermReturnOutputLine,31,(ltr->buf, ltr->read_count)); + + return returnCode; +} diff --git a/mozilla/extensions/xmlterm/base/ltermInput.c b/mozilla/extensions/xmlterm/base/ltermInput.c new file mode 100644 index 00000000000..733d025fe63 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ltermInput.c @@ -0,0 +1,829 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ltermInput.c: LTERM PTY input data processing + */ + +/* public declarations */ +#include "lineterm.h" + +/* private declarations */ +#include "ltermPrivate.h" + + +static int ltermLineInput(struct lterms *lts, const UNICHAR *buf, int count, + int *opcodes); +static int ltermMetaInput(struct lterms *lts); +static int ltermRequestCompletion(struct lterms *lts, UNICHAR uch); + + +/** Processes plain text input data and returns + * OPCODES ::= LINEDATA ( INPUT ( NEWLINE HIDE? )? + * | INPUT META ( COMPLETION | NEWLINE HIDE? ) ) + * if echoable input data was processed. + * (OPCODES is set to zero if raw input data was processed) + * Called from ltermWrite + * @return 0 on success, + * -1 on error, and + * -2 if pseudo-TTY has been closed. + */ +int ltermPlainTextInput(struct lterms *lts, + const UNICHAR *buf, int count, int *opcodes) +{ + struct LtermInput *lti = &(lts->ltermInput); + int returnCode; + + LTERM_LOG(ltermPlainTextInput,20, + ("start lti->inputMode=%d\n", lti->inputMode)); + + if (lti->inputMode == LTERM0_RAW_MODE) { + /* Transmit characters immediately to child process; no buffering */ + + LTERM_LOG(ltermPlainTextInput,29, + ("Raw mode, transmitting %d characters\n", + count)); + + if (ltermSendData(lts, buf, count) != 0) + return -1; + + *opcodes = 0; + + } else { + /* Not raw input mode; process line mode input */ + int processTrailingTab = 0; + + LTERM_LOG(ltermPlainTextInput,21, + ("Line mode, lts->commandNumber=%d, inputMode=%d\n", + lts->commandNumber, lti->inputMode)); + + if ((lti->inputMode >= LTERM3_COMPLETION_MODE) && + (lts->commandNumber == 0)) { + /* Downgrade input mode */ + lti->inputMode = LTERM2_EDIT_MODE; + + LTERM_LOG(ltermPlainTextInput,21, + ("------------ Downgraded input mode=%d\n\n", + lti->inputMode)); + + } else if ((lti->inputMode < lts->maxInputMode) && + (lts->commandNumber != 0)) { + /* Upgrade input mode */ + int priorInputMode = lti->inputMode; + + /* Set input mode (possibly allowing completion) */ + lti->inputMode = lts->maxInputMode; + + /* Do not allow command completion without TTY echo */ + if ( (lts->disabledInputEcho || lts->noTTYEcho) && + (lti->inputMode > LTERM2_EDIT_MODE) ) + lti->inputMode = LTERM2_EDIT_MODE; + + if ((lti->inputChars > 0) && + (priorInputMode < LTERM3_COMPLETION_MODE) && + (lti->inputMode >= LTERM3_COMPLETION_MODE)) { + /* Process prior input TABs before switching to completion mode */ + int j; + + if ((count == 0) && + (lti->inputCursorGlyph == lti->inputGlyphs) && + (lti->inputGlyphColIndex[lti->inputGlyphs] == lti->inputCols) && + (lti->inputColCharIndex[lti->inputCols] == lti->inputChars) && + (lti->inputLine[lti->inputChars] == U_TAB)) { + /* Trailing TAB in prior input; delete it, and process it later */ + if (ltermDeleteGlyphs(lti, 1) != 0) + return -1; + processTrailingTab = 1; + } + + /* Replace all input TABs with spaces */ + for (j=0; j < lti->inputChars; j++) { + if (lti->inputLine[j] == U_TAB) + lti->inputLine[j] = U_SPACE; + } + } + + LTERM_LOG(ltermPlainTextInput,21, + ("------------ Upgraded input mode=%d, trailingTab=%d\n\n", + lti->inputMode, processTrailingTab)); + + } + + if (processTrailingTab) { + /* Re-process trailing TAB */ + UNICHAR uch = U_TAB; + + assert(count == 0); + + LTERM_LOG(ltermPlainTextInput,21,("Reprocessing trailing TAB\n")); + + returnCode= ltermLineInput(lts, &uch, 1, opcodes); + if (returnCode < 0) + return returnCode; + + } else { + /* Process new input characters */ + returnCode = ltermLineInput(lts, buf, count, opcodes) != 0; + if (returnCode < 0) + return returnCode; + } + } + + return 0; +} + + +/** Cancels a prior command line completion request + * @return 0 on success, + * -1 on error + */ +int ltermCancelCompletion(struct lterms *lts) +{ + + LTERM_LOG(ltermCancelCompletion,40, + ("++++++++++++ CANCELED COMPLETION REQUEST\n\n")); + + if (lts->completionRequest != LTERM_NO_COMPLETION) { + + /* Kill input line transmitted to process */ + if (ltermSendData(lts, lts->control+TTYKILL, 1) != 0) + return -1; + + lts->completionRequest = LTERM_NO_COMPLETION; + } + + return 0; +} + + +/** Inserts plain text character UCH as a single-column glyph at the + * current input cursor location, translating to escape sequence if needed. + * @return 0 on success, -1 on error. + */ +int ltermInsertChar(struct LtermInput *lti, UNICHAR uch) +{ + UNICHAR* escapeSequence; + int insChars, insertColIndex, insertCharIndex, j; + + LTERM_LOG(ltermInsertChar,40,("inserting character 0x%x at glyph %d\n", + uch, lti->inputCursorGlyph)); + + /* Ignore null character */ + if (uch == 0) + return 0; + + escapeSequence = NULL; + insChars = 1; + +#if 0 + /* COMMENTED OUT: Plain text not escaped; use code later in HTML insert */ + /* Check if plain text character needs to be escaped for XML/HTML */ + for (j=0; jinputChars+insChars > MAXCOLM1) { + /* Input buffer overflow; ignore insert character */ + LTERM_WARNING("ltermInsertChar: Warning - input line buffer overflow\n"); + return 0; + } + + assert(lti->inputChars >= 0); + assert(lti->inputCols >= 0); + assert(lti->inputGlyphs >= 0); + assert(lti->inputCursorGlyph >= 0); + + assert(lti->inputCols <= lti->inputChars); + assert(lti->inputGlyphs <= lti->inputCols); + + insertColIndex = lti->inputGlyphColIndex[lti->inputCursorGlyph]; + insertCharIndex = lti->inputColCharIndex[insertColIndex]; + + LTERM_LOG(ltermInsertChar,41,("insertColIndex=%d, insertCharIndex=%d, insChars=%d\n", + insertColIndex, insertCharIndex, insChars)); + + /* Shift portion of input line to the right; + remember that the column/glyph index arrays have an extra element */ + for (j=lti->inputChars - 1; j >= insertCharIndex; j--) + lti->inputLine[j+insChars] = lti->inputLine[j]; + + for (j=lti->inputCols; j >= insertColIndex; j--) + lti->inputColCharIndex[j+1] = lti->inputColCharIndex[j]+insChars; + + for (j=lti->inputGlyphs; j >= lti->inputCursorGlyph; j--) { + lti->inputGlyphCharIndex[j+1] = lti->inputGlyphCharIndex[j]+insChars; + lti->inputGlyphColIndex[j+1] = lti->inputGlyphColIndex[j]+1; + } + + /* Insert character(s) in input line */ + if (escapeSequence == NULL) { + lti->inputLine[insertCharIndex] = uch; + } else { + for (j=0; j < insChars; j++) + lti->inputLine[j+insertCharIndex] = escapeSequence[j]; + } + + /* Insert column/glyph */ + lti->inputColCharIndex[insertColIndex] = insertCharIndex; + + lti->inputGlyphCharIndex[lti->inputCursorGlyph] = insertCharIndex; + lti->inputGlyphColIndex[lti->inputCursorGlyph] = insertColIndex; + + lti->inputChars += insChars; /* Increment character count */ + + lti->inputCols++; /* Increment column count */ + + lti->inputGlyphs++; /* Increment glyph count */ + + lti->inputCursorGlyph++; /* Reposition cursor */ + + return 0; +} + + +/** switches to raw input mode */ +void ltermSwitchToRawMode(struct lterms *lts) +{ + struct LtermInput *lti = &(lts->ltermInput); + + LTERM_LOG(ltermSwitchToRawMode,40,("\n")); + + if (lti->inputMode != LTERM0_RAW_MODE) { + /* Do other things ... */ + lti->inputMode = LTERM0_RAW_MODE; + } +} + + +/** clears input line buffer and switches to regular input mode */ +void ltermClearInputLine(struct lterms *lts) +{ + struct LtermInput *lti = &(lts->ltermInput); + + LTERM_LOG(ltermClearInputLine,40,("\n")); + + lti->inputChars = 0; + + lti->inputCols = 0; + lti->inputColCharIndex[0] = 0; + + lti->inputGlyphs = 0; + lti->inputGlyphCharIndex[0] = 0; + lti->inputGlyphColIndex[0] = 0; + + lti->inputCursorGlyph = 0; + + if (lts->maxInputMode >= LTERM2_EDIT_MODE) + lti->inputMode = LTERM2_EDIT_MODE; + else + lti->inputMode = lts->maxInputMode; + + lti->escapeFlag = 0; + lti->escapeCSIFlag = 0; + lti->escapeCSIArg = 0; +} + + +/** Processes an input string in canonical or higher mode and returns + * OPCODES ::= LINEDATA ( INPUT (NEWLINE HIDE?)? + * | INPUT META (COMPLETION|NEWLINE HIDE?) ) + * if echoable input data was processed. + * (OPCODES is set to zero if raw input data was processed) + * Called from ltermPlainTextInput + * @return 0 on success, + * -1 on error, and + * -2 if pseudo-TTY has been closed. + */ +static int ltermLineInput(struct lterms *lts, + const UNICHAR *buf, int count, int *opcodes) +{ + struct LtermInput *lti = &(lts->ltermInput); + UNICHAR uch; + int charIndex, metaInput; + + /* Default returned opcodes (maybe overridden) */ + *opcodes = LTERM_LINEDATA_CODE | LTERM_INPUT_CODE; + + charIndex = 0; + + LTERM_LOG(ltermLineInput,30, + ("lti->inputMode=%d, inputCursorGlyph=%d\n", + lti->inputMode, lti->inputCursorGlyph)); + LTERM_LOGUNICODE(ltermLineInput,31,(buf, count)); + LTERM_LOG(ltermLineInput,31,("Glyphs=%d,Cols=%d,Chars=%d\n", + lti->inputGlyphs, lti->inputCols, lti->inputChars)); + + while (charIndex < count) { + uch = buf[charIndex]; + + if (uch == U_ESCAPE) { + /* Escape */ + lti->escapeFlag = 1; + uch = U_NUL; + + } else if (lti->escapeFlag) { + /* Escaped character */ + lti->escapeFlag = 0; + + switch (uch) { + + case U_LBRACKET: + /* Start of escape code sequence */ + lti->escapeCSIFlag = 1; + lti->escapeCSIArg = 0; + uch = U_NUL; + break; + + default: + uch = U_NUL; + } + + } else if (lti->escapeCSIFlag) { + /* Character part of escape code sequence */ + + if ((uch >= U_ZERO && uch <= U_NINE)) { + /* Process numerical argument to escape code sequence */ + lti->escapeCSIArg = lti->escapeCSIArg*10 + (uch - U_ZERO); + uch = U_NUL; + + } else { + /* End of escape code sequence */ + lti->escapeCSIFlag = 0; + + /* SUN arrow key bindings */ + switch (uch) { + case U_A_CHAR: + uch = U_CTL_P; + break; + case U_B_CHAR: + uch = U_CTL_N; + break; + case U_C_CHAR: + uch = U_CTL_F; + break; + case U_D_CHAR: + uch = U_CTL_B; + break; + default: + uch = U_NUL; + } + } + } + + if ( ((uch >= U_SPACE) && (uch != U_DEL)) || + ((uch == U_TAB) && (lti->inputMode <= LTERM2_EDIT_MODE)) ) { + /* printable character or non-completion mode TAB; insert in buffer */ + /* (NEED TO UPDATE THIS CHECK FOR UNICODE PRINTABILITY) */ + + LTERM_LOG(ltermLineInput,39,("inserting printable character - %c\n", + (char) uch)); + + /* Insert character */ + if (ltermInsertChar(lti, uch) != 0) + return -1; + + } else { + /* Control character */ + + /* Line break control characters */ + if ( (uch == U_LINEFEED) || + (uch == lts->control[TTYDISCARD]) || + (uch == lts->control[TTYSUSPEND]) || + (uch == lts->control[TTYINTERRUPT])) { + /* Newline/TTYdiscard/TTYsuspend/TTYinterrupt character */ + + /* Assert that linebreak character occurs at end of buffer; + * enforced by lterm_write. + */ + assert(charIndex == count-1); + + /* Check if meta input line */ + metaInput = ltermMetaInput(lts); + + if ((uch == lts->control[TTYDISCARD]) && !metaInput + && (lts->commandNumber == 0)) { + /* Not meta/command line; simply transmit discard character */ + if (ltermSendData(lts, lts->control+TTYDISCARD, 1) != 0) + return -1; + + } else { + /* Newline behaviour, with hide option */ + LTERM_LOG(ltermLineInput,31,("------------ NEWLINE (0x%x)\n\n", + uch)); + LTERM_LOGUNICODE(ltermLineInput,31,( lti->inputLine, + lti->inputChars)); + + /* The NEWLINE code tells ltermReturnInputLine to clear + * the input line buffer after copying it + */ + *opcodes = LTERM_LINEDATA_CODE | LTERM_INPUT_CODE + | LTERM_NEWLINE_CODE; + + if (uch == lts->control[TTYDISCARD]) { + *opcodes |= LTERM_HIDE_CODE; + uch = U_LINEFEED; /* essentially newline behaviour otherwise */ + } + + if (metaInput) { + /* meta input; do not send line */ + *opcodes |= LTERM_META_CODE; + } else { + /* Send line and copy to echo buffer */ + if (ltermSendLine(lts, uch, (uch != U_LINEFEED), + LTERM_NO_COMPLETION) != 0) + return -1; + } + + } + + } else if (uch == lts->control[TTYKILL]) { + /* kill line */ + ltermClearInputLine(lts); + + LTERM_LOG(ltermLineInput,31,("TTYKILL\n")); + + } else if ((uch == U_BACKSPACE) || + (uch == lts->control[TTYERASE])) { + /* erase glyph */ + if (ltermDeleteGlyphs(lti, 1) != 0) + return -1; + + LTERM_LOG(ltermLineInput,39,("TTYERASE\n")); + + } else { + /* other control characters */ + if (lti->inputMode >= LTERM2_EDIT_MODE) { + switch (uch) { + + case U_NUL: /* Null character; ignore */ + break; + + case U_CTL_B: /* move cursor backward */ + LTERM_LOG(ltermLineInput,32,("^B\n")); + if (lti->inputCursorGlyph > 0) { + lti->inputCursorGlyph--; + } + break; + + case U_CTL_F: /* move cursor forward */ + LTERM_LOG(ltermLineInput,32,("^F\n")); + if (lti->inputCursorGlyph < lti->inputGlyphs) { + lti->inputCursorGlyph++; + } + break; + + case U_CTL_A: /* position cursor at beginning of line */ + LTERM_LOG(ltermLineInput,32,("^A\n")); + lti->inputCursorGlyph = 0; + break; + + case U_CTL_E: /* position cursor at end of line */ + LTERM_LOG(ltermLineInput,32,("^E\n")); + lti->inputCursorGlyph = lti->inputGlyphs; + break; + + case U_CTL_K: /* delete to end of line */ + LTERM_LOG(ltermLineInput,32,("^K\n")); + if (ltermDeleteGlyphs(lti,-(lti->inputGlyphs-lti->inputCursorGlyph)) + != 0) + return -1; + break; + + case U_CTL_L: /* form feed */ + case U_CTL_R: /* redisplay */ + LTERM_LOG(ltermLineInput,32,("^%c\n", uch+U_ATSIGN)); + break; + + case U_CTL_D: /* ^D */ + case U_CTL_N: /* dowN history */ + case U_CTL_P: /* uP history */ + case U_CTL_Y: /* yank */ + case U_TAB: /* command completion */ + + /* Assert that completion character occurs at end of buffer; + * enforced by lterm_write. + */ + assert(charIndex == count-1); + + metaInput = ltermMetaInput(lts); + + if (metaInput) { + /* Meta input command completion */ + LTERM_LOG(ltermLineInput,40, + ("++++++++++++ meta COMPLETION uch=0x%X\n\n", uch)); + if (uch == U_TAB) { + *opcodes = LTERM_LINEDATA_CODE | LTERM_INPUT_CODE + | LTERM_META_CODE + | LTERM_COMPLETION_CODE; + } else { + LTERM_WARNING("ltermLineInput: Warning - meta command completion not yet implemented for uch=0x%x\n", uch); + } + + } else if (lti->inputMode >= LTERM3_COMPLETION_MODE) { + /* Completion mode; non-completion TABs already processed */ + + if (ltermRequestCompletion(lts, uch) != 0) + return -1; + } + + break; + } + } + } + } + + /* Increment character index */ + charIndex++; + } + + return 0; +} + + +/** Check if input line contains a meta delimiter; + * @return 1 if it does, 0 otherwise. + */ +static int ltermMetaInput(struct lterms *lts) +{ + struct LtermInput *lti = &(lts->ltermInput); + UNICHAR *delimLoc, *ustr, *ustr2; + + LTERM_LOG(ltermMetaInput,40,("\n")); + + if (lts->options & LTERM_NOMETA_FLAG) + return 0; + + /* Assert that there is at least one free character position in the buffer */ + assert(lti->inputChars < MAXCOL); + + /* Insert null character at the end of the input buffer */ + lti->inputLine[lti->inputChars] = U_NUL; + + /* Locate first occurrence of meta delimiter in input line */ + delimLoc = ucschr(lti->inputLine, ltermGlobal.metaDelimiter); + + if (delimLoc == NULL) + return 0; + + for (ustr=lti->inputLine; ustrprocessType == LTERM_TCSH_PROCESS)){ + /* If ^D and not TCSH, simply transmit character */ + if (ltermSendData(lts, &uch, 1) != 0) + return -1; + return 0; + } + + switch (uch) { + case U_TAB: + /* Send line and copy to echo buffer */ + if (ltermSendLine(lts, uch, 0, LTERM_TAB_COMPLETION) != 0) + return -1; + break; + case U_CTL_P: + case U_CTL_N: + /* Send line and copy to echo buffer */ + if (ltermSendLine(lts, uch, 0, LTERM_HISTORY_COMPLETION) != 0) + return -1; + break; + default: + LTERM_WARNING("ltermCompletionRequest: Warning - command completion not yet implemented for uch=0x%x\n", uch); + } + + return 0; +} + + +/** Deletes glyphs from the input line. + * If COUNT > 0, glyphs are deleted to the left of the cursor. + * If COUNT < 0, glyphs are deleted to the right of the cursor. + * Called from ltermLineInput. + * @return 0 on success, -1 on error. + */ +int ltermDeleteGlyphs(struct LtermInput *lti, int count) +{ + int leftGlyph, leftColIndex, leftCharIndex; + int rightGlyph, rightColIndex, rightCharIndex; + int deleteGlyphs, deleteCols, deleteChars, j; + + LTERM_LOG(ltermDeleteGlyphs,40,("deleting %d glyphs from glyph %d\n", + count, lti->inputCursorGlyph)); + + if (count >= 0) { + /* Delete to the left */ + deleteGlyphs = count; + + /* Limit the number of glyphs deleted to that present to the left */ + if (deleteGlyphs > lti->inputCursorGlyph) + deleteGlyphs = lti->inputCursorGlyph; + + rightGlyph = lti->inputCursorGlyph; + leftGlyph = rightGlyph - deleteGlyphs; + + } else { + /* Delete to the right */ + deleteGlyphs = -count; + + /* Limit the number of glyphs deleted to that present to the right */ + if (deleteGlyphs > (lti->inputGlyphs - lti->inputCursorGlyph)) + deleteGlyphs = lti->inputGlyphs - lti->inputCursorGlyph; + + leftGlyph = lti->inputCursorGlyph; + rightGlyph = leftGlyph + deleteGlyphs; + } + + leftColIndex = lti->inputGlyphColIndex[leftGlyph]; + leftCharIndex = lti->inputGlyphCharIndex[leftGlyph]; + + rightColIndex = lti->inputGlyphColIndex[rightGlyph]; + rightCharIndex = lti->inputGlyphCharIndex[rightGlyph]; + + deleteCols = rightColIndex - leftColIndex; + deleteChars = rightCharIndex - leftCharIndex; + + LTERM_LOG(ltermDeleteGlyphs,41,("deleteCols=%d, deleteChars=%d\n", + deleteCols, deleteChars)); + + LTERM_LOG(ltermDeleteGlyphs,42,("leftGlyph=%d, leftCol=%d, leftChar=%d\n", + leftGlyph, leftColIndex, leftCharIndex)); + + LTERM_LOG(ltermDeleteGlyphs,42,("rightGlyph=%d, rightCol=%d, rightChar=%d\n", + rightGlyph, rightColIndex, rightCharIndex)); + + /* Shift portion of input line to the left; + remember that the column/glyph index arrays have an extra element */ + for (j = leftCharIndex; j < lti->inputChars-deleteChars; j++) + lti->inputLine[j] = lti->inputLine[j+deleteChars]; + + for (j = leftColIndex; j <= lti->inputCols-deleteCols; j++) + lti->inputColCharIndex[j] = lti->inputColCharIndex[j+deleteCols] + - deleteChars; + + for (j = leftGlyph; j <= lti->inputGlyphs-deleteGlyphs; j++) + lti->inputGlyphColIndex[j] = lti->inputGlyphColIndex[j+deleteGlyphs] + - deleteCols; + + lti->inputChars -= deleteChars; /* Decrement character count */ + + lti->inputCols -= deleteCols; /* Decrement column count */ + + lti->inputGlyphs -= deleteGlyphs; /* Decrement glyph count */ + + if (count > 0) + lti->inputCursorGlyph -= deleteGlyphs; /* Reposition glyph cursor */ + + return 0; +} + + +/** Transmits COUNT Unicode characters from BUF to child process + * after translating Unicode to UTF8 or Latin1, as appropriate. + * The data is transmitted in smallish chunks so as not to overflow the + * PTY input buffer. + * @return 0 on successful write, -1 on error. + */ +int ltermSendData(struct lterms *lts, const UNICHAR *buf, int count) +{ + char ch, ptyBuf[MAXPTYIN]; + int remainingChars, chunkSize, success; + + assert(lts != NULL); + assert(count >= 0); + + LTERM_LOG(ltermSendData,40,("count=%d\n", count)); + LTERM_LOGUNICODE(ltermSendData,41,(buf, count)); + + if ((count == 1) && (*buf < 0x80)) { + /* Optimized code to transmit single ASCII character */ + ch = (char) *buf; + + if (lts->ptyMode) +#ifndef USE_NSPR_IO + success = (write(lts->pty.ptyFD, &ch, 1) == 1); +#else + assert(0); +#endif + else + success = (WRITE(lts->ltermProcess.processIN, &ch, 1) == 1); + + if (!success) { +#if defined(DEBUG) && !defined(USE_NSPR_IO) + int errcode = errno; + perror("ltermSendData"); +#else + int errcode = 0; +#endif + LTERM_ERROR("ltermSendData: Error %d in writing to child STDIN\n", + errcode); + return -1; + } + + return 0; + } + + remainingChars = count; + while (remainingChars > 0) { + /* Convert Unicode to UTF8 */ + ucstoutf8(&buf[count-remainingChars], remainingChars, + ptyBuf, MAXPTYIN, + &remainingChars, &chunkSize); + + assert(chunkSize > 0); + + LTERM_LOG(ltermSendData,42,("remainingChars=%d, chunkSize=%d\n", + remainingChars, chunkSize)); + + /* Send UTF8 to process */ + if (lts->ptyMode) +#ifndef USE_NSPR_IO + success = (write(lts->pty.ptyFD, &ptyBuf, + (SIZE_T) chunkSize) == chunkSize); +#else + assert(0); +#endif + else + success = (WRITE(lts->ltermProcess.processIN, &ptyBuf, + (SIZE_T) chunkSize) == chunkSize); + + if (!success) { +#if defined(DEBUG) && !defined(USE_NSPR_IO) + int errcode = errno; + perror("ltermSendData"); +#else + int errcode = 0; +#endif + LTERM_ERROR("ltermSendData: Error %d in writing to child STDIN\n", + errcode); + return -1; + } + } + + return 0; +} diff --git a/mozilla/extensions/xmlterm/base/ltermManager.c b/mozilla/extensions/xmlterm/base/ltermManager.c new file mode 100644 index 00000000000..5e9c6a3f5f7 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ltermManager.c @@ -0,0 +1,1190 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ltermManager.c: LTERM control operations + */ + +/* public declarations */ +#include "lineterm.h" + +/* private declarations */ +#include "ltermPrivate.h" + +/* LTERM global variables */ +LtermGlobal ltermGlobal; + +#define CHECK_IF_VALID_LTERM_NUMBER(procname,lterm) \ + if ((lterm < 0) || (lterm >= MAXTERM)) { \ + LTERM_ERROR("procname: Error - LTERM index %d out of range\n", \ + lterm); \ + return -1; \ + } + +/* Macros for use in thread synchronization */ +#define GLOBAL_LOCK MUTEX_LOCK(ltermGlobal.listMutex) +#define GLOBAL_UNLOCK MUTEX_UNLOCK(ltermGlobal.listMutex) + +/* The following macros assume that ltermGlobal.listMutex has already been + * locked. + * A UNILOCK is lock that can be locked only by one thread at a time; + * attempts to lock it by another thread result in an error return. + * This can be used to detect violations of thread discipline. + */ + +#define SWITCH_GLOBAL_TO_UNILOCK(procname,mutex,mutex_flag) \ + if (lts->mutex_flag) { \ + LTERM_ERROR("procname: Error - MUTEX mutex already locked\n", \ + lts->mutex); \ + MUTEX_UNLOCK(ltermGlobal.listMutex); \ + return -1; \ + } \ + MUTEX_LOCK(lts->mutex); \ + lts->mutex_flag = 1; \ + MUTEX_UNLOCK(ltermGlobal.listMutex); + +#define RELEASE_UNILOCK(mutex,mutex_flag) \ + lts->mutex_flag = 0; \ + MUTEX_UNLOCK(lts->mutex); + + +int ltermClose(struct lterms *lts); +static int ltermCreatePipe(FILEDESC *writePIPE, FILEDESC *readPIPE); +static int ltermCreateProcess(struct LtermProcess *ltp, + char *const argv[], int nostderr, int noexport); +static void ltermDestroyProcess(struct LtermProcess *ltp); + + +/** Initializes all LTERM operations + * (documented in the LTERM interface) + * @return 0 on success, or -1 on error. + */ +int lterm_init(int messageLevel) +{ + if (!ltermGlobal.initialized) { + int result, j; + /* Assert that INTs have at least 32-bit precision. + * This assumption underlies the choice of various bit codes. + */ + assert(sizeof(int) >= 4); + + if (sizeof(UNICHAR) == 2) { + /* Assert that the maximum column count fits into an UNICHAR. + * This assumption is used for input buffer pipe I/O by lterm_write + * and ltermWrite, but could be relaxed by using different buffer record + * structure. + */ + assert(MAXCOL <= 0x7FFF); + } + + /* Initialize lock for accessing LTERMs array */ + if (MUTEX_INITIALIZE(ltermGlobal.listMutex) != 0) + return -1; + + /* Initialize trace/log module for STDERR; + * this could perhaps be eliminated, if TLOG_PRINT is redefined to PR_LOG + * and so on, with the USE_NSPR_IO option enabled. + */ + tlog_init(stderr); + result = tlog_set_level(LTERM_TLOG_MODULE, messageLevel, NULL); + + /* Meta input delimiter */ + ltermGlobal.metaDelimiter = U_COLON; + + /* String of five ASCII characters escaped in XML; + * only the first four characters are escaped in HTML; + * it is sufficient to escape just the first three characters, "&<>" + * when inserting plain text (outside markup) in XML/HTML fragments + */ + ltermGlobal.escapeChars[LTERM_AMP_ESCAPE] = '&'; + ltermGlobal.escapeChars[LTERM_LT_ESCAPE] = '<'; + ltermGlobal.escapeChars[LTERM_GT_ESCAPE] = '>'; + ltermGlobal.escapeChars[LTERM_QUOT_ESCAPE] = '\"'; + ltermGlobal.escapeChars[LTERM_APOS_ESCAPE] = '\''; + ltermGlobal.escapeChars[LTERM_XML_ESCAPES] = 0; + + /* List of XML character escape sequences (Unicode) */ + ltermGlobal.escapeSeq[LTERM_AMP_ESCAPE] = L"&"; + ltermGlobal.escapeSeq[LTERM_LT_ESCAPE] = L"<"; + ltermGlobal.escapeSeq[LTERM_GT_ESCAPE] = L">"; + ltermGlobal.escapeSeq[LTERM_QUOT_ESCAPE] = L"""; + ltermGlobal.escapeSeq[LTERM_APOS_ESCAPE] = L"'"; + + /* Escape sequence lengths (including delimiters) */ + for (j=0; j= 0) on success, or + * -1 on error + */ +int lterm_new() +{ + int lterm; + struct lterms *lts; + + if (!ltermGlobal.initialized) { + LTERM_ERROR("lterm_new: Error - call lterm_init() to initialize LTERM library\n"); + return -1; + } + + LTERM_LOG(lterm_new,10,("Creating LTERM ...\n")); + + /* Allocate memory for new LTERMS structure: needs clean-up */ + lts = (struct lterms *) MALLOC(sizeof(struct lterms)); + + if (lts == NULL) { + LTERM_ERROR("lterm_new: Error - failed to allocate memory for LTERM\n"); + return -1; + } + + GLOBAL_LOCK; + + for (lterm=0; lterm < MAXTERM; lterm++) { + if (ltermGlobal.termList[lterm] == NULL) + break; + } + + if (lterm == MAXTERM) { + LTERM_ERROR( "lterm_new: Error - too many LTERMS; recompile with increased MAXTERM\n"); + FREE(lts); /* Clean up memory allocation for LTERMS structure */ + GLOBAL_UNLOCK; + return -1; + } + + /* Insert LTERM pointer in list of LTERMs */ + ltermGlobal.termList[lterm] = lts; + + MUTEX_INITIALIZE(lts->adminMutex); + + /* Administrative thread inactive */ + lts->adminMutexLocked = 0; + + /* LTERM not yet opened for I/O */ + lts->opened = 0; + + GLOBAL_UNLOCK; + + LTERM_LOG(lterm_new,11,("created lterm = %d\n", lterm)); + + return lterm; +} + + +/* Macro to close and delete LTERM */ +#define LTERM_OPEN_ERROR_RETURN(lterm,lts,errmsg) \ + LTERM_ERROR(errmsg); \ + ltermClose(lts); \ + RELEASE_UNILOCK(adminMutex,adminMutexLocked) \ + lterm_delete(lterm); \ + return -1; + +/** Opens an LTERM for I/O + * (documented in the LTERM interface) + * @return 0 on success, or -1 on error + */ +int lterm_open(int lterm, char *const argv[], const char* cookie, + const UNICHAR* prompt_regexp, int options, int process_type, + lterm_callback_func_t callback_func, void *callback_data) +{ + int nostderr, noPTY, j; + struct ptys ptyStruc; + struct lterms *lts; + struct LtermInput *lti; + struct LtermOutput *lto; + struct LtermProcess *ltp; + char *const *cargv; + char *defaultArgs[3]; + + if (!ltermGlobal.initialized) { + LTERM_ERROR("lterm_open: Error - call lterm_init() to initialize LTERM library\n"); + return -1; + } + + CHECK_IF_VALID_LTERM_NUMBER(lterm_open,lterm) + + LTERM_LOG(lterm_open,10,("Opening LTERM %d\n", lterm)); + + GLOBAL_LOCK; + + lts = ltermGlobal.termList[lterm]; + + if (lts == NULL) { + LTERM_ERROR("lterm_open: Error - LTERM %d not created using lterm_new\n", + lterm); + GLOBAL_UNLOCK; + return -1; + } + + if (lts->opened) { + LTERM_ERROR("lterm_open: Error - LTERM %d is already open\n", + lterm); + GLOBAL_UNLOCK; + return -1; + } + + SWITCH_GLOBAL_TO_UNILOCK(lterm_open,adminMutex,adminMutexLocked) + + /* Pointers to LTERM process/input/output structures */ + ltp = &(lts->ltermProcess); + lti = &(lts->ltermInput); + lto = &(lts->ltermOutput); + + /* Initialize flags/pointers/file descriptors that need to be cleaned up */ + lts->suspended = 0; + lts->ptyMode = 0; + + /* Initialize TTY control characters */ + assert(TTYWERASE < MAXTTYCONTROL); + lts->control[TTYINTERRUPT] = U_CTL_C; + lts->control[TTYERASE] = U_DEL; + lts->control[TTYKILL] = U_CTL_U; + lts->control[TTYEOF] = U_CTL_D; + lts->control[TTYSUSPEND] = U_CTL_Z; + lts->control[TTYREPRINT] = U_CTL_R; + lts->control[TTYDISCARD] = U_CTL_O; + lts->control[TTYWERASE] = U_CTL_W; + + lts->writeBUFFER = NULL_FILEDESC; + lts->readBUFFER = NULL_FILEDESC; + + /* Clear input line break flag */ + lts->inputLineBreak = 0; + + /* Clear input buffer */ + lti->inputBufBytes = 0; + lts->inputBufRecord = 0; + + /* Clear styleMask */ + lto->styleMask = 0; + + /* Clear incomplete raw output buffers */ + lto->rawOUTBytes = 0; + lto->rawERRBytes = 0; + + /* Clear decoded output buffer */ + lto->decodedChars = 0; + lto->incompleteEscapeSequence = 0; + + /* Set screen parameters (VT100) */ + lts->nRows = 24; + lts->nCols = 80; + lts->screenSize = lts->nRows * lts->nCols; + + /* Clear screen buffer */ + lto->screenChar = NULL; + lto->screenStyle = NULL; + + lts->outputMutexLocked = 0; + + MUTEX_INITIALIZE(lts->outputMutex); + + /* AT THIS POINT, LTERMCLOSE MAY BE CALLED FOR CLEAN-UP */ + + /* Create input buffer pipe; needs clean-up */ + if (ltermCreatePipe(&(lts->writeBUFFER), &(lts->readBUFFER)) != 0) { + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - input buffer pipe creation failed\n") + } + + LTERM_LOG(lterm_open,11,("Created input buffer pipe\n", lterm)); + + defaultArgs[0] = NULL; + defaultArgs[1] = "-i"; + defaultArgs[2] = NULL; + + if (argv != NULL) { + /* Use supplied command arguments */ + cargv= argv; + + } else { + /* Default command arguments */ + defaultArgs[0] = (char *) getenv("SHELL"); + if (defaultArgs[0] == NULL) + defaultArgs[0] = "/bin/sh"; + cargv= defaultArgs; + } + + if (process_type >= 0) { + /* Specified process type code */ + lts->processType = process_type; + + } else { + /* Determine process type code from path name */ + char *lastSlash; + char *tailStr; + + /* Find the last occurrence of slash */ + lastSlash = (char *) strrchr(cargv[0], '/'); + if (lastSlash == NULL) { + tailStr = cargv[0]; + } else { + tailStr = lastSlash + 1; + } + + if (strcmp(tailStr,"sh") == 0) { + lts->processType = LTERM_SH_PROCESS; + + } else if (strcmp(tailStr,"ksh") == 0) { + lts->processType = LTERM_KSH_PROCESS; + + } else if (strcmp(tailStr,"bash") == 0) { + lts->processType = LTERM_BASH_PROCESS; + + } else if (strcmp(tailStr,"csh") == 0) { + lts->processType = LTERM_CSH_PROCESS; + + } else if (strcmp(tailStr,"tcsh") == 0) { + lts->processType = LTERM_TCSH_PROCESS; + + } else { + lts->processType = LTERM_UNKNOWN_PROCESS; + } + } + + LTERM_LOG(lterm_open,11,("process type code = %d\n", lts->processType)); + + /* TTY options */ + lts->options = options; + lts->noTTYEcho = (options & LTERM_NOECHO_FLAG) != 0; + lts->disabledInputEcho = 0; + + nostderr = (options & LTERM_NOSTDERR_FLAG) != 0; + +#if defined(NO_PTY) || defined(USE_NSPR_IO) + /* Current implementation of pseudo-TTY is incompatible with the NSPR I/O + option; set the USE_NSPR_IO option only on platforms where + PTYSTREAM is not implemented. + Reason for incompatibility: cannot combine the UNIX-style integral + PTY file descriptor and NSPR's PRFileDesc in the same poll function + call. + */ + noPTY = 1; +#else + noPTY = (options & LTERM_NOPTY_FLAG); +#endif + + if (noPTY) { + /* Create pipe process: needs clean-up */ + if (ltermCreateProcess(ltp, cargv, nostderr, 0) == -1) { + + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Pipe process creation failed\n") + } + + } else { + /* Create pseudo-TTY with blocking I/O: needs clean-up */ + int noblock = 1; + int noexport = 0; + int debugPTY = (tlogGlobal.messageLevel[LTERM_TLOG_MODULE] > 1); + +#ifndef NO_PTY + if (pty_create(&ptyStruc, cargv, nostderr?-1:-2, + noblock, lts->noTTYEcho, noexport, debugPTY) == -1) { + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - PTY creation failed\n") + } + + /* Resize TTY */ + if (pty_resize(&ptyStruc, lts->nRows, lts->nCols, 0, 0) != 0) { + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - PTY resizing failed\n") + } +#endif /* NO_PTY */ + + /* Copy PTY structure */ + lts->pty = ptyStruc; + lts->ptyMode = 1; + } + + /* Set up LtermOutput polling structure */ + lto->pollFD[POLL_INPUTBUF].fd = lts->readBUFFER; + lto->pollFD[POLL_INPUTBUF].POLL_EVENTS = POLLIN; + + if (lts->ptyMode) { +#ifndef USE_NSPR_IO + lto->pollFD[POLL_STDOUT].fd = lts->pty.ptyFD; + lto->pollFD[POLL_STDOUT].POLL_EVENTS = POLLIN; + + if (VALID_FILEDESC(lts->pty.errpipeFD)) { + lto->pollFD[POLL_STDERR].fd = lts->pty.errpipeFD; + lto->pollFD[POLL_STDERR].POLL_EVENTS = POLLIN; + lto->nfds = POLL_COUNT; + } else { + lto->nfds = POLL_COUNT-1; + } +#else + /* Current implementation of pseudo-TTY incompatible with USE_NSPR_IO */ + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - pseudo-TTY incompatible with USE_NSPR_IO\n") +#endif + + } else { + lto->pollFD[POLL_STDOUT].fd = ltp->processOUT; + lto->pollFD[POLL_STDOUT].POLL_EVENTS = POLLIN; + + if (VALID_FILEDESC(ltp->processERR)) { + lto->pollFD[POLL_STDERR].fd = ltp->processERR; + lto->pollFD[POLL_STDERR].POLL_EVENTS = POLLIN; + lto->nfds = POLL_COUNT; + } else { + lto->nfds = POLL_COUNT-1; + } + } + + /* No callbacks initially associated with this LTERM */ + for (j=0; jnfds; j++) + lto->callbackTag[j] = 0; + + /* Determine whether STDERR should be read before STDOUT */ + if (lts->processType == LTERM_TCSH_PROCESS) { + lts->readERRfirst = 0; + } else { + lts->readERRfirst = 1; + } + + /* Determine whether STDERR and STDOUT should be interleaved */ + lts->interleave = 1; + + /* Determine maximum value for input mode */ + if (options & LTERM_NOCANONICAL_FLAG) + lts->maxInputMode = LTERM0_RAW_MODE; + + else if (options & LTERM_NOEDIT_FLAG) + lts->maxInputMode = LTERM1_CANONICAL_MODE; + + else if ((options & LTERM_NOCOMPLETION_FLAG) || + lts->noTTYEcho) + lts->maxInputMode = LTERM2_EDIT_MODE; + + else { + if ((lts->processType == LTERM_BASH_PROCESS) || + (lts->processType == LTERM_TCSH_PROCESS)) + lts->maxInputMode = LTERM3_COMPLETION_MODE; + else + lts->maxInputMode = LTERM2_EDIT_MODE; + } + + LTERM_LOG(lterm_open,11,("options=%x, processType=%d, readERRfirst=%d, maxInputMode=%d\n", + lts->options, lts->processType, lts->readERRfirst, lts->maxInputMode)); + LTERM_LOGUNICODE(lterm_open,11,(prompt_regexp, (int) ucslen(prompt_regexp) )); + + if (cookie != NULL) { + /* Copy cookie string (no more than MAXCOOKIESTR-1 characters) */ + if (strlen(cookie) > MAXCOOKIESTR-1) { + LTERM_WARNING("lterm_open: Warning - cookie string truncated\n"); + } + strncpy(lts->cookie, cookie, MAXCOOKIESTR-1); + lts->cookie[MAXCOOKIESTR-1] = '\0'; + } else { + /* No cookie */ + lts->cookie[0] = '\0'; + } + + LTERM_LOG(lterm_open,11,("cookie='%s'\n",lts->cookie)); + + /* Initialize regular expression string matching command prompt */ + if ((ucslen(prompt_regexp) == 0) || + (ucslen(prompt_regexp) > MAXPROMPT-1)) { + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - prompt_regexp string too short/long\n") + } + + ucsncpy( lts->promptRegexp, prompt_regexp, MAXPROMPT); + + /* Command number counter */ + lts->lastCommandNum = 0; + + /* Command completion request code */ + lts->completionRequest = LTERM_NO_COMPLETION; + + /* Clear output line buffer and switch to line output mode */ + ltermClearOutputLine(lts); + lto->outputMode = LTERM2_LINE_MODE; + lto->styleMask = 0; + + /* Reset terminal modes */ + lto->insertMode = 0; + lto->automaticNewline = 0; + + /* Clear input line buffer */ + ltermClearInputLine(lts); + + /* Clear input line flag not yet set */ + lti->clearInputLine = 0; + + /* Reset input opcodes */ + lti->inputOpcodes = 0; + + /* Open LTERM */ + lts->opened = 1; + + /* Initialize any callbacks associated with this LTERM */ + if (callback_func != NULL) { +#if !defined(USE_NSPR_IO) && defined(USE_GTK_WIDGETS) + LTERM_LOG(lterm_open,11,("Initializing %d callbacks for LTERM %d\n", + lto->nfds, lterm)); + + for (j=0; jnfds; j++) { + lto->callbackTag[j] = gdk_input_add(lto->pollFD[j].fd, + GDK_INPUT_READ, + callback_func, + (gpointer) callback_data); + if (lto->callbackTag[j] == 0) { + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - unable to add callback\n") + } + } +#else + LTERM_OPEN_ERROR_RETURN(lterm,lts, + "lterm_open: Error - callbacks not implemented for this configuration\n") +#endif + } + + + RELEASE_UNILOCK(adminMutex,adminMutexLocked) + + LTERM_LOG(lterm_open,11, + ("outputMode=%d, inputMode=%d, maxInputMode=%d\n", + lto->outputMode, lti->inputMode,lts->maxInputMode )); + + return 0; +} + + +/** Closes an LTERM described by structure pointed to by LTS. + * (Auxiliary routine for lterm_close, lterm_delete, and lterm_close_all) + * NOTE: This routine should not attempt to acquire the global lock, + * since it is called from LTERM_CLOSE_ALL under a global lock. + * @return 0 on success, or -1 on error. + */ +int ltermClose(struct lterms *lts) +{ + struct LtermInput *lti; + struct LtermOutput *lto; + UNICHAR closeMessage[2] = {0, LTERM_WRITE_CLOSE_MESSAGE}; + int j; + + LTERM_LOG(ltermClose,10,("Closing LTERM\n")); + + assert(lts != NULL); + + /* Admin thread must be active */ + assert(lts->adminMutexLocked); + + /* Suspend LTERM to prevent any further I/O operations */ + lts->suspended = 1; + + /* Pointers to LTERM input/output structures */ + lti = &(lts->ltermInput); + lto = &(lts->ltermOutput); + + /* Send close signal to any terminate blocked read operation */ + WRITE(lts->writeBUFFER, closeMessage, (SIZE_T)(2*sizeof(UNICHAR)) ); + + /* Wait for read operations to complete */ + MUTEX_LOCK(lts->outputMutex); + MUTEX_UNLOCK(lts->outputMutex); + + /* Destroy output mutex */ + MUTEX_DESTROY(lts->outputMutex); + + /* Close input buffer pipe */ + if (VALID_FILEDESC(lts->writeBUFFER)) + CLOSE(lts->writeBUFFER); + + if (VALID_FILEDESC(lts->readBUFFER)) + CLOSE(lts->readBUFFER); + +#ifdef USE_GTK_WIDGETS + /* Remove any callbacks associated with this LTERM */ + for (j=0; jnfds; j++) { + if (lto->callbackTag[j] != 0) { + gdk_input_remove((gint) lto->callbackTag[j]); + lto->callbackTag[j] = 0; + } + } +#endif + + if (lts->ptyMode) { + /* Close PTY */ +#ifndef NO_PTY + pty_close(&(lts->pty)); +#endif + + } else { + /* Destroy process */ + ltermDestroyProcess(&(lts->ltermProcess)); + } + + /* Free full screen buffers */ + if (lto->screenChar != NULL) + FREE(lto->screenChar); + + if (lto->screenStyle != NULL) + FREE(lto->screenStyle); + + /* Close LTERM */ + lts->opened = 0; + + LTERM_LOG(ltermClose,11,("LTERM closed\n")); + + return 0; +} + + +/** Closes an LTERM + * (documented in the LTERM interface) + * @return 0 on success, or -1 on error. + */ +int lterm_close(int lterm) +{ + struct lterms *lts; + int returnCode; + + CHECK_IF_VALID_LTERM_NUMBER(lterm_close,lterm) + + LTERM_LOG(lterm_close,10,("Closing LTERM %d\n", lterm)); + + GLOBAL_LOCK; + + lts = ltermGlobal.termList[lterm]; + + if (lts == NULL) { + /* Forgiving return for non-existent LTERM */ + GLOBAL_UNLOCK; + return 0; + } + + if (!lts->opened) { + LTERM_WARNING("lterm_close: Error - LTERM %d not opened\n", lterm); + GLOBAL_UNLOCK; + return -1; + } + + SWITCH_GLOBAL_TO_UNILOCK(lterm_close,adminMutex,adminMutexLocked) + + returnCode = ltermClose(lts); + + RELEASE_UNILOCK(adminMutex,adminMutexLocked) + + return returnCode; +} + + +/** Deletes an LTERM object, closing it if necessary + * (documented in the LTERM interface) + * @return 0 on success, or -1 on error. + */ +int lterm_delete(int lterm) +{ + struct lterms *lts; + int returnCode; + + CHECK_IF_VALID_LTERM_NUMBER(lterm_delete,lterm) + + LTERM_LOG(lterm_delete,10,("Closing LTERM %d\n", lterm)); + + GLOBAL_LOCK; + + lts = ltermGlobal.termList[lterm]; + + if (lts == NULL) { + /* Forgiving return for non-existent LTERM */ + GLOBAL_UNLOCK; + return 0; + } + + /* Remove LTERM structure from list */ + ltermGlobal.termList[lterm] = NULL; + + SWITCH_GLOBAL_TO_UNILOCK(lterm_open,adminMutex,adminMutexLocked) + + returnCode = 0; + if (lts->opened) { + /* Opened LTERM; close it */ + returnCode = ltermClose(lts); + } + + RELEASE_UNILOCK(adminMutex,adminMutexLocked) + + MUTEX_DESTROY(lts->adminMutex); + + /* Free memory for LTERMS structure */ + FREE(lts); + + LTERM_LOG(lterm_delete,11,("LTERM deleted\n")); + + return returnCode; +} + + +/* closes all LTERMs (documented in the LTERM interface) */ +void lterm_close_all() +{ + int lterm; + struct lterms *lts; + + LTERM_LOG(lterm_close_all,10,("\n")); + + GLOBAL_LOCK; + + for (lterm=0; lterm < MAXTERM; lterm++) { + lts = ltermGlobal.termList[lterm]; + + if ((lts != NULL) && lts->opened) { + /* Opened LTERM; close it, disregarding return code */ + lts->adminMutexLocked = 1; + MUTEX_LOCK(lts->adminMutex); + + /* NOTE,10, ("lterm_close_all:\n"******** This call is being made from within a global lock; + * POTENTIAL FOR DEADLOCK? + */ + ltermClose(lts); + + lts->adminMutexLocked = 0; + MUTEX_UNLOCK(lts->adminMutex); + } + } + + GLOBAL_UNLOCK; +} + + +/** Sets input echo flag for LTERM (documented in the LTERM interface) */ +int lterm_setecho(int lterm, int echo_flag) +{ + struct lterms *lts; + + CHECK_IF_VALID_LTERM_NUMBER(lterm_setecho,lterm) + + LTERM_LOG(lterm_setecho,10,("LTERM=%d, echo_flag=%d\n", lterm, echo_flag)); + + GLOBAL_LOCK; + + lts = ltermGlobal.termList[lterm]; + + if (lts == NULL || !lts->opened || lts->suspended) { + /* LTERM is deleted/closed/suspended */ + if (lts == NULL) + LTERM_WARNING("lterm_setecho: Warning - LTERM %d not active\n", lterm); + GLOBAL_UNLOCK; + return -2; + } + + lts->disabledInputEcho = !echo_flag; + + GLOBAL_UNLOCK; + + return 0; +} + + +/** Writes a string to LTERM (documented in the LTERM interface) */ +int lterm_write(int lterm, const UNICHAR *buf, int count, int dataType) +{ + struct lterms *lts; + FILEDESC writeBUFFER; + int byteCount, sentCount, packetCount, j; + UNICHAR temLine[PIPEHEADER+MAXCOL], uch; + + CHECK_IF_VALID_LTERM_NUMBER(lterm_write,lterm) + + LTERM_LOG(lterm_write,10,("Writing to LTERM %d\n", lterm)); + + GLOBAL_LOCK; + + lts = ltermGlobal.termList[lterm]; + + if (lts == NULL || !lts->opened || lts->suspended) { + /* LTERM is deleted/closed/suspended */ + if (lts == NULL) + LTERM_WARNING("lterm_write: Warning - LTERM %d not active\n", lterm); + GLOBAL_UNLOCK; + return -2; + } + + assert(VALID_FILEDESC(lts->writeBUFFER)); + + /* Save copy of input buffer file descriptor */ + writeBUFFER = lts->writeBUFFER; + + GLOBAL_UNLOCK; + + assert(count >= 0); + + sentCount = 0; + while (sentCount < count) { + packetCount = count - sentCount; /* always > 0 */ + + if (packetCount > MAXCOLM1) + packetCount = MAXCOLM1; + + if ( (dataType == LTERM_WRITE_PLAIN_INPUT) || + (dataType == LTERM_WRITE_PLAIN_OUTPUT) ) { + /* Plain text data; break at control characters, + * but break at ESCape character only if not the first character; + * this ensures that escape sequences fit into one record + */ + + for (j=0; j 0))) + break; + } + + if (j 1) && + (temLine[PIPEHEADER+packetCount-1] == U_ESCAPE) ) { + /* Save any terminal ESCape character for next packet, unless alone */ + packetCount--; + } + + } else { + /* XML element data (must represent complete element) */ + for (j=0; jwriteBUFFER,temLine,(SIZE_T)byteCount) != byteCount) { + LTERM_ERROR("lterm_write: Error in writing to input pipe buffer\n"); + return -1; + } + + LTERM_LOG(lterm_write,11, + ("wrote %d characters of type %d data to input buffer pipe\n", + packetCount, dataType)); + + sentCount += packetCount; + } + + return 0; +} +/** Reads a (possibly incomplete) line from LTERM + * (documented in the LTERM interface) + */ +int lterm_read(int lterm, int timeout, UNICHAR *buf, int count, + UNISTYLE *style, int *opcodes, + int *buf_row, int *buf_col, int *cursor_row, int *cursor_col) +{ + struct lterms *lts; + int returnCode, temCode; + struct LtermRead ltrStruc; + + CHECK_IF_VALID_LTERM_NUMBER(lterm_read,lterm) + + LTERM_LOG(lterm_read,10,("Reading from LTERM %d\n", lterm)); + + GLOBAL_LOCK; + + lts = ltermGlobal.termList[lterm]; + + if (lts == NULL || !lts->opened || lts->suspended) { + /* LTERM is deleted/closed/suspended */ + if (lts == NULL) + LTERM_WARNING("lterm_read: Warning - LTERM %d not active\n", lterm); + + *opcodes = 0; + *buf_row = 0; + *buf_col = 0; + *cursor_row = 0; + *cursor_col = 0; + + GLOBAL_UNLOCK; + return -2; + } + + SWITCH_GLOBAL_TO_UNILOCK(lterm_read,outputMutex,outputMutexLocked) + + /* Copy "input" parameters to LtermRead structure */ + ltrStruc.buf = buf; + ltrStruc.style = style; + ltrStruc.max_count = count; + + /* Call auxiliary function to read data */ + temCode = ltermRead(lts, <rStruc, timeout); + + if (temCode == 0) { + /* Return count of characters read */ + returnCode = ltrStruc.read_count; + } else { + /* Error return */ + returnCode = temCode; + } + + /* Copy "output" parameters from LtermRead structure */ + *opcodes = ltrStruc.opcodes; + *buf_row = ltrStruc.buf_row; + *buf_col = ltrStruc.buf_col; + *cursor_row = ltrStruc.cursor_row; + *cursor_col = ltrStruc.cursor_col; + + if (returnCode == -1) { + /* Error return code; suspend TTY */ + LTERM_WARNING("lterm_read: Warning - LTERM %d suspended due to error\n", lterm); + lts->suspended = 1; + } + + RELEASE_UNILOCK(outputMutex,outputMutexLocked) + + LTERM_LOG(lterm_read,11,("return code = %d\n", returnCode)); + + return returnCode; +} + + +/** Creates unidirectional pipe which can be written to and read from using + * the file descriptors writePIPE and readPIPE. + * @return 0 on success and -1 on error. + */ +static int ltermCreatePipe(FILEDESC *writePIPE, FILEDESC *readPIPE) +{ + FILEDESC pipeFD[2]; + + LTERM_LOG(ltermCreatePipe,20,("Creating pipe\n")); + + /* Assume that pipe is unidirectional, although in some UNIX + systems pipes are actually bidirectional */ + + if (PIPE(pipeFD) == -1) { + LTERM_ERROR("ltermCreatePipe: Error - pipe creation failed\n"); + return -1; + } + + /* Copy pipe file descriptor */ + *readPIPE = pipeFD[0]; + *writePIPE = pipeFD[1]; + + return 0; +} + + +/** Creates a new process to execute the command line contained in array + * ARGV and redirects its standard I/O and standard error through pipes. + * The process details are stored in the structure pointed to by LTP. + * If NOSTDERR is true, STDERR is redirected to STDOUT. + * If NOEXPORT is true, then the current environment is not exported + * to the new process. + * @return 0 on success and -1 on error. + */ +static int ltermCreateProcess(struct LtermProcess *ltp, + char *const argv[], int nostderr, int noexport) +{ + FILEDESC stdIN, stdOUT, stdERR; +#ifdef USE_NSPR_IO + PRProcessAttr *processAttr; +#else + long child_pid; +#endif + + LTERM_LOG(ltermCreateProcess,20,("Creating process %s, nostderr=%d, noexport=%d\n", argv[0], nostderr, noexport)); + + stdERR= NULL_FILEDESC; + if (!nostderr) { + /* Create STDERR pipe: needs clean-up */ + FILEDESC pipeFD[2]; + + if (PIPE(pipeFD) == -1) { + LTERM_ERROR("ltermCreateProcess: Error - STDERR pipe creation failed\n"); + return -1; + } + + /* Copy pipe file descriptor */ + ltp->processERR = pipeFD[0]; + stdERR = pipeFD[1]; + } + + /* Create I/O pipes: needs clean up */ + if ( (ltermCreatePipe(&(ltp->processIN), &stdIN) != 0) || + (ltermCreatePipe(&stdOUT, &(ltp->processOUT)) != 0) ) + return -1; + +#ifdef USE_NSPR_IO + /* Create new process attribute structure */ + processAttr = PR_NewProcessAttr(); + + /* Redirect standard error for process */ + if (VALID_FILEDESC(stdERR)) + PR_ProcessAttrSetStdioRedirect(processAttr, (PRSpecialFD) 2, stdERR); + else + PR_ProcessAttrSetStdioRedirect(processAttr, (PRSpecialFD) 2, stdOUT); + + /* Redirect standard I/O for process */ + PR_ProcessAttrSetStdioRedirect(processAttr, (PRSpecialFD) 0, stdIN); + PR_ProcessAttrSetStdioRedirect(processAttr, (PRSpecialFD) 1, stdOUT); + + /* Create NSPR process; do not export environment */ + ltp->processID = PR_CreateProcess(argv[0], argv, + (char *const *)0, processAttr); + + if (!VALID_PROCESS(ltp->processID)) { + LTERM_ERROR("ltermCreateProcess: Error in creating NSPR process %s\n", + argv[0]); + return -1; + } + + LTERM_LOG(ltermCreateProcess,21,("Created NSPR process\n")); + +#else /* not USE_NSPR_IO */ + + /* Fork a child process (FORK) */ + child_pid = fork(); + if (child_pid < 0) { + LTERM_ERROR("ltermCreateProcess: Error - fork failed\n"); + return -1; + } + + LTERM_LOG(ltermCreateProcess,21,("vfork child pid = %d\n", child_pid)); + + if (child_pid == 0) { + /* Child process */ + int fdMax, fd; + + /* Redirect to specified descriptor or to PTY */ + if (VALID_FILEDESC(stdERR)) { + /* Redirect STDERR to specified file descriptor */ + if (dup2(stdERR, 2) == -1) { + LTERM_ERROR("ltermCreateProcess: Error - failed dup2 for specified stderr\n"); + return -1; + } + + } else { + /* Redirect STDERR to STDOUT pipe */ + if (dup2(stdOUT, 2) == -1) { + LTERM_ERROR("ltermCreateProcess: Error - failed dup2 for default stderr\n"); + return -1; + } + } + + /* Redirect STDIN and STDOUT to pipes */ + if (dup2(stdIN, 0) == -1) { + LTERM_ERROR("ltermCreateProcess: Error - failed dup2 for stdin\n"); + return -1; + } + + if (dup2(stdOUT, 1) == -1) { + LTERM_ERROR("ltermCreateProcess: Error - failed dup2 for stdout\n"); + return -1; + } + + /* Close all other file descriptors in child process */ + fdMax = sysconf(_SC_OPEN_MAX); + for (fd = 3; fd < fdMax; fd++) + close(fd); + + if (argv != NULL) { + /* Execute specified command with arguments */ + if (noexport) + execve(argv[0], argv, NULL); + else + execvp(argv[0], argv); + + LTERM_ERROR("ltermCreateProcess: Error in executing command %s\n", + argv[0]); + return -1; + } + } + + /* Parent process; copy child pid */ + ltp->processID = child_pid; + + /* Close child-side pipe end(s) */ + if (stdIN != stdOUT) + close(stdIN); + + close(stdOUT); + + /* Close writable end of STDERR pipe in parent process */ + if (VALID_FILEDESC(stdERR)) + close(stdERR); + +#endif /* not USE_NSPR_IO */ + + LTERM_LOG(ltermCreateProcess,21,("return code = 0\n")); + + return 0; +} + +/** Destroys process pointed by LTP + */ +static void ltermDestroyProcess(struct LtermProcess *ltp) +{ + + LTERM_LOG(ltermDestroyProcess,20,("Destroying process\n")); + + if (VALID_PROCESS(ltp->processID)) { + /* Kill process */ +#ifdef USE_NSPR_IO + /* **NOTE** Possible memory leak here, because processID is not freed? */ + PR_KillProcess(ltp->processID); +#else /* not USE_NSPR_IO */ + LTERM_LOG(ltermDestroyProcess,21,("Killing process %d\n",ltp->processID)); + kill(ltp->processID, SIGKILL); +#endif /* not USE_NSPR_IO */ + + ltp->processID = NULL_PROCESS; + } + + /* Close process pipes (assumed to be unidirectional) */ + if (VALID_FILEDESC(ltp->processERR)) + CLOSE(ltp->processERR); + + if (VALID_FILEDESC(ltp->processOUT)) + CLOSE(ltp->processOUT); + + if (VALID_FILEDESC(ltp->processIN)) + CLOSE(ltp->processIN); +} diff --git a/mozilla/extensions/xmlterm/base/ltermOutput.c b/mozilla/extensions/xmlterm/base/ltermOutput.c new file mode 100644 index 00000000000..1d652d62eb6 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ltermOutput.c @@ -0,0 +1,895 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ltermOutput.c: LTERM PTY output processing + */ + +/* public declarations */ +#include "lineterm.h" + +/* private declarations */ +#include "ltermPrivate.h" + + +static int ltermAppendOutput(struct lterms *lts, const char *cbuf, int count, + UNISTYLE style, int interleaveCheck, + int *interleavedBytes, int rawIncompleteMax, + int *rawIncompleteBytes, char *rawIncompleteBuf); +static int ltermDecode(const char *rawBuf, int n_total, + UNICHAR* decodedBuf, int decodeMax, + int decodeNUL, + int *rawIncompleteBytes); +static int ltermPromptLocate(struct lterms *lts); + + +/** Processes output from decoded output buffer and returns *opcodes: + * OPCODES ::= SCREENDATA BELL? ( CLEAR + * | INSERT MOVEDOWN? + * | DELETE MOVEDOWN? + * | OUTPUT ) + * if ScreenMode data is being returned. + * OPCODES ::= LINEDATA BELL? ( CLEAR + * | OUTPUT NEWLINE?) + * if LineMode data is being returned. + * @return 0 on success and -1 on error. + */ +int ltermProcessOutput(struct lterms *lts, int *opcodes) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + UNICHAR uch; + UNISTYLE ustyle; + int charIndex, returnCode, consumedChars, remainingChars, j; + int bellFlag; + + LTERM_LOG(ltermProcessOutput,30,("lto->outputMode=%d, cursorChar=%d, Chars=%d\n", + lto->outputMode, lto->outputCursorChar, lto->outputChars)); + + LTERM_LOG(ltermProcessOutput,32, ("lts->commandNumber=%d\n", + lts->commandNumber)); + + *opcodes = 0; + charIndex = 0; + bellFlag = 0; + + while ((*opcodes == 0) && (charIndex < lto->decodedChars)) { + uch = lto->decodedOutput[charIndex]; + ustyle = lto->decodedStyle[charIndex] | lto->styleMask; + + consumedChars = 1; + + if (uch == U_ESCAPE) { + /* Process escape sequence */ + int savedOutputMode = lto->outputMode; + + LTERM_LOG(ltermProcessOutput,31,("ESCAPE sequence\n")); + + returnCode = ltermProcessEscape(lts, lto->decodedOutput+charIndex, + lto->decodedChars-charIndex, + lto->decodedStyle+charIndex, + &consumedChars, opcodes); + if (returnCode < 0) + return -1; + + if (returnCode == 1) { + /* Incomplete escape sequence */ + lto->incompleteEscapeSequence = 1; + if (lto->outputMode == LTERM1_SCREEN_MODE) + *opcodes = LTERM_SCREENDATA_CODE | LTERM_OUTPUT_CODE; + else + *opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE; + } + + /* Assert that change in output mode is a loop terminating condition */ + if (lto->outputMode != savedOutputMode) + assert(*opcodes != 0); + + } else if (lto->outputMode == LTERM1_SCREEN_MODE) { + /* Screen mode processing */ + + if ((uch >= U_SPACE) && (uch != U_DEL)) { + /* Printable non-TAB character */ + + LTERM_LOG(ltermProcessOutput,39,("Screen mode, printable char - %c\n", + (char) uch)); + + if (lto->insertMode) { + /* Insert blank character at cursor position */ + if (ltermInsDelEraseChar(lts, 1, LTERM_INSERT_CHAR) != 0) + return -1; + } + + /* Mark column as being modified */ + if ((lto->modifiedCol[lto->cursorRow] == -1) || + (lto->modifiedCol[lto->cursorRow] > lto->cursorCol)) + lto->modifiedCol[lto->cursorRow] = lto->cursorCol; + + /* Replace character and style info at current cursor location */ + j = lto->cursorRow*lts->nCols + lto->cursorCol; + + assert(j < lts->screenSize); + + lto->screenChar[j] = uch; + lto->screenStyle[j] = ustyle; + + if (lto->cursorCol < lts->nCols-1) { + /* Move cursor right */ + lto->cursorCol++; + + /* Increase row column count, if necessary */ + if (lto->rowCols[lto->cursorRow] < lto->cursorCol) + lto->rowCols[lto->cursorRow] = lto->cursorCol; + + } else { + /* Set row column count to maximum value */ + lto->rowCols[lto->cursorRow] = lts->nCols; + } + + } else { + /* Control character */ + + switch (uch) { + case U_BACKSPACE: /* Backspace */ + LTERM_LOG(ltermProcessOutput,32,("Screen mode, BACKSPACE\n")); + if (lto->cursorCol > 0) + lto->cursorCol--; + break; + + case U_BEL: /* Bell */ + LTERM_LOG(ltermProcessOutput,32,("************ Screen mode, BELL\n")); + bellFlag = 1; + break; + + default: + /* Ignore other control characters (including NULs) */ + break; + } + } + + } else { + /* Line mode processing */ + + if ( ((uch >= U_SPACE) && (uch != U_DEL)) || + (uch == U_TAB)) { + /* Printable/TAB character; replace/insert at current cursor location + or append to end of line */ + + LTERM_LOG(ltermProcessOutput,39,("Line mode, printable char - %c\n", + (char) uch)); + + if (lto->outputCursorChar == lto->outputChars) { + /* Append single character to end of line */ + + if (lto->outputChars+1 > MAXCOLM1) { + /* Output buffer overflow; ignore character */ + LTERM_WARNING("ltermProcessOutput: Warning - output line buffer overflow\n"); + } + + lto->outputLine[lto->outputChars] = uch; + lto->outputStyle[lto->outputChars] = ustyle; + lto->outputChars++; /* Insert character in output line */ + + lto->outputCursorChar++; /* Reposition cursor */ + + } else { + /* Replace/insert single character in the middle of line */ + + if (lto->insertMode) { + /* Insert blank character at cursor position */ + if (ltermInsDelEraseChar(lts, 1, LTERM_INSERT_CHAR) != 0) + return -1; + } + + /* Overwrite single character in the middle of line */ + lto->outputLine[lto->outputCursorChar] = uch; + lto->outputStyle[lto->outputCursorChar] = ustyle; + + /* Note modifications */ + if (lto->outputCursorChar < lto->outputModifiedChar) + lto->outputModifiedChar = lto->outputCursorChar; + + lto->outputCursorChar++; /* Reposition cursor */ + } + + } else { + /* Control character */ + + switch (uch) { + case U_BACKSPACE: /* Backspace */ + LTERM_LOG(ltermProcessOutput,32,("Line mode, BACKSPACE\n")); + if (lto->outputCursorChar > 0) + lto->outputCursorChar--; + break; + + case U_CRETURN: /* Carriage return */ + LTERM_LOG(ltermProcessOutput,32,("Line mode, CRETURN\n")); + lto->outputCursorChar = 0; + break; + + case U_BEL: /* Bell */ + LTERM_LOG(ltermProcessOutput,32,("************ Line mode, BELL\n")); + bellFlag = 1; + break; + + case U_CTL_L: /* Formfeed; clear line and return */ + LTERM_LOG(ltermProcessOutput,32,("************ Line mode, FORMFEED\n\n")); + + ltermClearOutputLine(lts); + *opcodes = LTERM_LINEDATA_CODE | LTERM_CLEAR_CODE; + break; + + case U_LINEFEED: /* Newline; return complete line */ + LTERM_LOG(ltermProcessOutput,32,("************ Line mode, NEWLINE\n\n")); + + *opcodes = LTERM_LINEDATA_CODE + | LTERM_OUTPUT_CODE + | LTERM_NEWLINE_CODE; + break; + + default: + /* Ignore other control characters (including NULs) */ + break; + } + } + } + + /* Increment character index */ + charIndex += consumedChars; + } + + /* Determine count of unprocessed characters */ + remainingChars = lto->decodedChars - charIndex; + + if (remainingChars > 0) { + /* Move unprocessed output to beginning of decode buffer */ + + LTERM_LOG(ltermProcessOutput,32,("Moved %d chars to beginning of decodedOutput\n", remainingChars)); + for (j=0; jdecodedOutput[j] = lto->decodedOutput[j+charIndex]; + lto->decodedStyle[j] = lto->decodedStyle[j+charIndex]; + } + } + + /* Update remaining decoded character count */ + lto->decodedChars = remainingChars; + + if (*opcodes == 0) { + /* All output processed; without any special terminating condition */ + if (lto->outputMode == LTERM1_SCREEN_MODE) { + /* Full screen mode */ + *opcodes = LTERM_SCREENDATA_CODE | LTERM_OUTPUT_CODE; + + } else { + /* Line mode */ + *opcodes = LTERM_LINEDATA_CODE | LTERM_OUTPUT_CODE; + } + } + + /* Set bell code */ + if (bellFlag) + *opcodes |= LTERM_BELL_CODE; + + if (*opcodes & LTERM_LINEDATA_CODE) { + /* Returning line mode data; check for prompt */ + + if ((lts->commandNumber == 0) || + (lto->outputModifiedChar < lto->promptChars)) { + /* If not command line or if "prompt string" may have been modified, + * search for prompt + */ + int promptLen; + + LTERM_LOG(ltermProcessOutput,39,("Prompt? modifiedChar=%d, promptChars=%d\n", + lto->outputModifiedChar, lto->promptChars)); + + /* Reset modification marker */ + lto->outputModifiedChar = lto->outputChars; + + /* Check if prompt string is present in output */ + promptLen = ltermPromptLocate(lts); + + if (promptLen > 0) { + /* Prompt string found */ + lto->promptChars = promptLen; + + if (lts->commandNumber == 0) { + /* Set command number */ + + /* New command number */ + if (lts->lastCommandNum == 0xFFFF) + lts->lastCommandNum = 0; + lts->lastCommandNum++; + + lts->commandNumber = lts->lastCommandNum; + + LTERM_LOG(ltermProcessOutput,32, + ("************ Prompt found; commandNumber=%d\n\n", + lts->commandNumber)); + } + + } else { + /* No prompt string */ + if (lts->commandNumber != 0) { + /* Unset command number and prompt columns */ + UNICHAR temLine[2] = {0, LTERM_WRITE_PLAIN_INPUT}; + + lts->commandNumber = 0; + lto->promptChars = 0; + + /* Notify "input thread" by writing null input record */ + WRITE(lts->writeBUFFER, temLine, 2*sizeof(UNICHAR)); + + LTERM_LOG(ltermProcessOutput,32, + ("************ No prompt found; not command line\n\n")); + } + } + } + } + + LTERM_LOG(ltermProcessOutput,31,("returned opcodes=0x%X\n", *opcodes)); + + return 0; +} + + +/** Clears output line buffer */ +void ltermClearOutputLine(struct lterms *lts) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + + LTERM_LOG(ltermClearOutputLine,40,("\n")); + + lto->outputChars = 0; + lto->outputCursorChar = 0; + lto->outputModifiedChar = 0; + lto->promptChars = 0; + + lts->commandNumber = 0; +} + + +/** Clears output screen buffer (allocating memory, if first time) */ +int ltermClearOutputScreen(struct lterms *lts) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int j; + + LTERM_LOG(ltermClearOutputScreen,40,("\n")); + + if (lto->screenChar == NULL) { + /* Allocate memory for full screen */ + lto->screenChar = (UNICHAR *) MALLOC(lts->screenSize * sizeof(UNICHAR)); + + if (lto->screenChar == NULL) { + LTERM_ERROR("ltermClearOutputScreen: Error - failed to allocate memory for chars\n"); + return -1; + } + + assert(lto->screenStyle == NULL); + lto->screenStyle = (UNISTYLE *) MALLOC(lts->screenSize * sizeof(UNISTYLE)); + + if (lto->screenStyle == NULL) { + LTERM_ERROR("ltermClearOutputScreen: Error - failed to allocate memory for style\n"); + return -1; + } + } + + lto->cursorRow = lts->nRows - 1; + lto->cursorCol = 0; + + for (j=0; jnRows; j++) { + lto->rowCols[j] = 0; + lto->modifiedCol[j] = -1; + } + + return 0; +} + + +/** Saves current output mode value and switches to stream output mode, + * with specified opcodes and terminator string. + * @return 0 on success and -1 on error. + */ +int ltermSwitchToStreamMode(struct lterms *lts, int streamOpcodes, + const UNICHAR *streamTerminator) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int strLength; + + LTERM_LOG(ltermSwitchToStreamMode,40,("streamOpcodes=0x%s\n",streamOpcodes)); + + if (streamTerminator != NULL) { + /* Save terminator string (may be null) */ + strLength = ucslen(streamTerminator); + ucsncpy( lto->streamTerminator, streamTerminator, MAXSTREAMTERM); + + LTERM_LOGUNICODE(ltermSwitchToStreamMode,41,(streamTerminator, + (int) strLength)); + } else { + /* Null terminator */ + strLength = 0; + lto->streamTerminator[0] = U_NUL; + } + + if (strLength > MAXSTREAMTERM-1) { + LTERM_ERROR("ltermSwitchToStreamMode: Error - terminator string too long\n"); + return -1; + } + + if (lts->options & LTERM_NONUL_FLAG) { + /* No decoding of NUL characters */ + if (strLength == 0) { + LTERM_ERROR("ltermSwitchToStreamMode: Error - null terminator string not allowed\n"); + return -1; + } + } else { + /* Decoding NUL characters */ + if (strLength > 0) { + LTERM_ERROR("ltermSwitchToStreamMode: Error - terminator string must be NUL\n"); + return -1; + } + } + + lto->savedOutputMode = lto->outputMode; + lto->outputMode = LTERM0_STREAM_MODE; + lto->streamOpcodes = streamOpcodes; + return 0; +} + + +/** Switches to screen output mode. + * @return 0 on success and -1 on error. + */ +int ltermSwitchToScreenMode(struct lterms *lts) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + + LTERM_LOG(ltermSwitchToScreenMode,40,("\n")); + + if (lto->outputMode == LTERM1_SCREEN_MODE) { + /* Switching from line mode to screen mode */ + + if (ltermClearOutputScreen(lts) != 0) + return -1; + + /* Clear styleMask */ + lto->styleMask = 0; + } + + lto->outputMode = LTERM1_SCREEN_MODE; + return 0; +} + + +/** Switches to line output mode. + * @return 0 on success and -1 on error. + */ +int ltermSwitchToLineMode(struct lterms *lts) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int j; + + LTERM_LOG(ltermSwitchToLineMode,40,("\n")); + + if (lto->outputMode == LTERM1_SCREEN_MODE) { + /* Switching from screen mode to line mode */ + ltermClearOutputLine(lts); + + /* Copy bottom line to line output buffer */ + lto->outputChars = lto->rowCols[0]; + + assert(lto->rowCols[0] < MAXCOL); + + for (j=0; jrowCols[0]; j++) { + lto->outputLine[j] = lto->screenChar[j]; + lto->outputStyle[j] = lto->screenStyle[j]; + } + + /* Clear styleMask */ + lto->styleMask = 0; + + } + + lto->outputMode = LTERM2_LINE_MODE; + return 0; +} + + +/** Reads data from process STDOUT and/or STDERR using file descriptors + * from the LTERM POLL structure, and converts to Unicode, saving + * incomplete character encodings in corresponding incomplete raw buffers. + * Decoded characters are appended to the decodedOutput buffer, + * with appropriate style settings. + * If READERR is false, STDERR is never read. + * @return the number of decoded characters appended (>=0) if successful, + * -1 if an error occurred during processing, or + * -2 if pseudo-TTY has been closed. + */ +int ltermReceiveData(struct lterms *lts, int readERR) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + char temERRBuf[MAXCOL], temOUTBuf[MAXCOL]; + int readERRMax, readOUTMax; + int nReadERR, nTotalERR, nReadOUT, nTotalOUT; + int interleavedBytes, n_decoded, n_decoded_tot, j; + + LTERM_LOG(ltermReceiveData,30,("\n")); + + nTotalERR = 0; + if (readERR && (lto->pollFD[POLL_STDERR].POLL_REVENTS != 0)) { + /* Read data from STDERR */ + + /* Read maximum number of bytes that will all fit into decodedOutput + when decoded, assuming number of decoded characters will not exceed + the number of encoded bytes */ + + readERRMax = MAXCOLM1 - lto->decodedChars - lto->rawERRBytes; + + /* Reduce by half to leave some space for STDOUT data */ + readERRMax = readERRMax / 2; + + if (readERRMax <= 0) { + /* Decoded buffer overflow */ + LTERM_WARNING("ltermReceiveData: Warning - decoded buffer overflow\n"); + + /* Non-fatal error recovery; return without reading */ + return 0; + } + + /* Copy any incomplete raw output to beginning of buffer */ + for (j=0; jrawERRBytes; j++) + temERRBuf[j] = lto->rawERRBuf[j]; + + /* Read STDERRdata (blocking mode) */ + nReadERR = READ(lto->pollFD[POLL_STDERR].fd, + temERRBuf + lto->rawERRBytes, (SIZE_T) readERRMax); + + if (nReadERR < 0) { +#if defined(DEBUG) && !defined(USE_NSPR_IO) + int errcode = errno; + /* perror("ltermReceiveData"); */ +#else + int errcode = 0; +#endif + LTERM_ERROR( "ltermReceiveData: Error %d in reading from process STDERR\n", + errcode); + return -1; + } + + if (nReadERR == 0) { + /* End of file => pseudo-TTY has been closed */ + LTERM_LOG(ltermReceiveData,31,("pseudo-TTY has been closed\n")); + + /* Suspend LTERM */ + lts->suspended = 1; + + return -2; + } + + + LTERM_LOG(ltermReceiveData,32,("Read %d raw bytes from STDERR\n", nReadERR)); + nTotalERR = nReadERR + lto->rawERRBytes; + } + + nTotalOUT = 0; + if (lto->pollFD[POLL_STDOUT].POLL_REVENTS != 0) { + /* Read data from STDOUT */ + + /* Read maximum number of bytes that will all fit into decodedOutput + when decoded, assuming number of decoded characters will not exceed + the number of encoded bytes */ + readOUTMax = MAXCOLM1 - lto->decodedChars - lto->rawOUTBytes - nTotalERR; + + if (readOUTMax <= 0) { + /* Decoded buffer overflow */ + LTERM_WARNING("ltermReceiveData: Warning - decoded buffer overflow\n"); + + /* Non-fatal error recovery; return without reading */ + return 0; + } + + /* Copy any incomplete raw output to beginning of buffer */ + for (j=0; jrawOUTBytes; j++) + temOUTBuf[j] = lto->rawOUTBuf[j]; + + /* Read STDOUTdata (blocking mode) */ + nReadOUT = READ(lto->pollFD[POLL_STDOUT].fd, + temOUTBuf + lto->rawOUTBytes, (SIZE_T) readOUTMax); + + if (nReadOUT < 0) { +#if defined(DEBUG) && !defined(USE_NSPR_IO) + int errcode = errno; + /* perror("ltermReceiveData"); */ +#else + int errcode = 0; +#endif + LTERM_ERROR( "ltermReceiveData: Error %d in reading from process STDOUT\n", + errcode); + return -1; + } + + if (nReadOUT == 0) { + /* End of file => pseudo-TTY has been closed */ + LTERM_LOG(ltermReceiveData,31,("pseudo-TTY has been closed\n")); + + /* Suspend LTERM */ + lts->suspended = 1; + + return -2; + } + + LTERM_LOG(ltermReceiveData,32,("Read %d raw bytes from STDOUT\n", nReadOUT)); + + nTotalOUT = nReadOUT + lto->rawOUTBytes; + } + + n_decoded_tot = 0; + + if (lts->readERRfirst) { + /* Decode STDERR data first */ + interleavedBytes = 0; + n_decoded = ltermAppendOutput(lts, temERRBuf, nTotalERR, + LTERM_STDERR_STYLE, + lts->interleave, &interleavedBytes, + MAXRAWINCOMPLETE, + &(lto->rawERRBytes), lto->rawERRBuf); + if (n_decoded < 0) + return -1; + n_decoded_tot += n_decoded; + + /* Decode STDOUT data next */ + n_decoded = ltermAppendOutput(lts, temOUTBuf, nTotalOUT, + LTERM_STDOUT_STYLE, + 0, NULL, + MAXRAWINCOMPLETE, + &(lto->rawOUTBytes), lto->rawOUTBuf); + if (n_decoded < 0) + return -1; + n_decoded_tot += n_decoded; + + if (interleavedBytes > 0) { + /* Decode remaining STDERR data */ + n_decoded = ltermAppendOutput(lts, temERRBuf+interleavedBytes, + nTotalERR-interleavedBytes, + LTERM_STDERR_STYLE, + 0, NULL, + MAXRAWINCOMPLETE, + &(lto->rawERRBytes), lto->rawERRBuf); + if (n_decoded < 0) + return -1; + n_decoded_tot += n_decoded; + } + + } else { + /* Decode STDOUT data first */ + interleavedBytes = 0; + n_decoded = ltermAppendOutput(lts, temOUTBuf, nTotalOUT, + LTERM_STDOUT_STYLE, + lts->interleave, &interleavedBytes, + MAXRAWINCOMPLETE, + &(lto->rawOUTBytes), lto->rawOUTBuf); + if (n_decoded < 0) + return -1; + n_decoded_tot += n_decoded; + + /* Decode STDERR data next */ + n_decoded = ltermAppendOutput(lts, temERRBuf, nTotalERR, + LTERM_STDERR_STYLE, + 0, NULL, + MAXRAWINCOMPLETE, + &(lto->rawERRBytes), lto->rawERRBuf); + if (n_decoded < 0) + return -1; + n_decoded_tot += n_decoded; + + if (interleavedBytes > 0) { + /* Decode remaining STDOUT data */ + n_decoded = ltermAppendOutput(lts, temOUTBuf+interleavedBytes, + nTotalOUT-interleavedBytes, + LTERM_STDOUT_STYLE, + 0, NULL, + MAXRAWINCOMPLETE, + &(lto->rawOUTBytes), lto->rawOUTBuf); + if (n_decoded < 0) + return -1; + n_decoded_tot += n_decoded; + } + } + + if (n_decoded_tot > 0) { + /* New characters have been decoded; no longer incomplete escape seq. */ + lto->incompleteEscapeSequence = 0; + } + + return n_decoded_tot; +} + + +/** Process COUNT bytes raw data from CBUF, converting complete + * character encodings to Unicode, saving RAWINCOMPLETEBYTES in + * RAWINCOMPLETEBUF, whose maximum size is specified by RAWINCOMPLETEMAX. + * If INTERLEAVECHECK, check for starting NEWLINE and other interleavable + * characters, and if found "decode" just those characters and set + * INTERLEAVEDBYTES to the number of bytes consumed on return; + * otherwise INTERLEAVEDBYTES is set to 0. + * The decoded characters are appended to the decodedOutput buffer, + * with style STYLE. + * @return the number of characters appended (>=0) if successful, + * -1 if an error occurred during processing, or + * -2 if pseudo-TTY has been closed. + */ +static int ltermAppendOutput(struct lterms *lts, const char *cbuf, int count, + UNISTYLE style, int interleaveCheck, + int *interleavedBytes, int rawIncompleteMax, + int *rawIncompleteBytes, char *rawIncompleteBuf) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int decodeMax, n_decoded, decodeNUL, j; + + LTERM_LOG(ltermAppendOutput,30,("count=%d, style=0x%X, iCheck=%d, rawIncMax=%d\n", + count, style, interleaveCheck, rawIncompleteMax)); + + if (interleaveCheck && (count > 0) && (cbuf[0] == '\n')) { + /* Raw buffer starts with NEWLINE character; interleave */ + + assert(lto->decodedChars < MAXCOLM1); + + /* "Decode" just the NEWLINE character */ + lto->decodedOutput[lto->decodedChars] = U_LINEFEED; + lto->decodedStyle[lto->decodedChars] = LTERM_STDOUT_STYLE; + + lto->decodedChars++; + + *interleavedBytes = 1; + + LTERM_LOG(ltermAppendOutput,32,("INTERLEAVED %d bytes\n", + *interleavedBytes)); + + return 1; + } + + if (interleavedBytes != NULL) + *interleavedBytes = 0; + + if (count == 0) + return 0; + + /* Decode all complete encoded character sequences */ + decodeMax = MAXCOLM1 - lto->decodedChars; + decodeNUL = (lts->options & LTERM_NONUL_FLAG) == 0; + n_decoded = ltermDecode(cbuf, count, + lto->decodedOutput+lto->decodedChars, + decodeMax, decodeNUL, + rawIncompleteBytes); + + if (n_decoded < 0) + return -1; + + /* Save any incomplete raw byte encodings */ + if (*rawIncompleteBytes > rawIncompleteMax) { + LTERM_ERROR("ltermAppendOutput: Error - too many incomplete raw characters\n"); + return -1; + } + + for (j=0; j<*rawIncompleteBytes; j++) + rawIncompleteBuf[j] = cbuf[j+count-*rawIncompleteBytes]; + + /* Set decoded character styles */ + for (j=lto->decodedChars; jdecodedChars+n_decoded; j++) + lto->decodedStyle[j] = style; + + /* Increment decoded character count */ + lto->decodedChars += n_decoded; + + LTERM_LOG(ltermAppendOutput,32,("Appended %d bytes\n", n_decoded)); + + return n_decoded; +} + + +/** Decodes N_TOTAL bytes in RAWBUF, returning upto DECODEMAX Unicode + * characters in DECODEDBUF, leaving *RAWINCOMPLETEBYTES at the end of + * RAWBUF undecoded. + * Any NUL (zero) characters in RAWBUF are skipped, unless + * decodeNUL is true. + * If there is not enough space in DECODEDBUF for all characters to be + * decoded, an error is returned. + * @return the number of Unicoded characters decoded (>=0) or -1 on error. + */ +static int ltermDecode(const char *rawBuf, int n_total, + UNICHAR* decodedBuf, int decodeMax, + int decodeNUL, + int *rawIncompleteBytes) +{ + int n_decoded, result; + + LTERM_LOG(ltermDecode,40,("\n")); + + if (decodeMax < n_total) { + LTERM_ERROR("ltermDecode: Error - decode buffer overflow\n"); + return -1; + } + + result = utf8toucs(rawBuf, n_total, decodedBuf, decodeMax, + !decodeNUL, rawIncompleteBytes, &n_decoded); + + if (result != 0) { + LTERM_WARNING("ltermDecode: Warning - Invalid UTF8 data encountered\n"); + } + + LTERM_LOG(ltermDecode,41,("result=%d, incomplete=%d, n_decoded=%d\n", + result, rawIncompleteBytes, n_decoded)); + LTERM_LOGUNICODE(ltermDecode,42,(decodedBuf, n_decoded)); + + return n_decoded; +} + + +/** Search for prompt string in the output line buffer. + * TEMPORARY implementation: assume promptRegexp is just a list of delimiters + * @return the length of the matching prompt string, or + * 0 if there is no match. + */ +static int ltermPromptLocate(struct lterms *lts) +{ + struct LtermOutput *lto = &(lts->ltermOutput); + int prefixCount, promptLen; + + LTERM_LOG(ltermPromptLocate,49,("lto->outputChars=%d\n", + lto->outputChars)); + + /* Assert that there is at least one free character in the buffer */ + assert(lto->outputChars < MAXCOL); + + if (lto->outputChars == 0) + return 0; + + /* Insert null character at the end of the output buffer */ + lto->outputLine[lto->outputChars] = U_NUL; + + /* Determine length of initial non-delimiter prefix */ + prefixCount = ucscspn(lto->outputLine, lts->promptRegexp); + + if (prefixCount+1 >= lto->outputChars) { + promptLen = 0; + + } else { + /* Skip any spaces following the delimiter */ + const UNICHAR spaceStr[2] = {U_SPACE, U_NUL}; + int spaceCount = ucsspn(lto->outputLine+prefixCount+1, spaceStr); + + promptLen = prefixCount + 1 + spaceCount; + + LTERM_LOGUNICODE(ltermPromptLocate,41,(lto->outputLine, promptLen)); + } + + return promptLen; +} diff --git a/mozilla/extensions/xmlterm/base/ltermPrivate.h b/mozilla/extensions/xmlterm/base/ltermPrivate.h new file mode 100644 index 00000000000..0732cf4842f --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ltermPrivate.h @@ -0,0 +1,560 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ltermPrivate.h: Line terminal (LTERM) private header file + * LTERM provides a "stream" interface to an XTERM-like terminal, + * using line input/output. + * CPP options: + * LINUX: for Linux2.0/glibc + * SOLARIS: for Solaris2.6 + * DEBUG: to enable some debugging output + * NO_PTY: force use of pipes rather than PTY for process + * communication + * MOZILLA_CLIENT: set if embedded in Mozilla + * USE_NSPR_BASE: use basic NSPR API (excluding I/O and process creation) + * USE_NSPR_LOCK: use NSPR lock API instead of Unix mutex API + * USE_NSPR_IO: use NSPR I/O and process API instead of Unix API + * (current implementation of pseudo-TTY is incompatible with + * the NSPR I/O API; set the USE_NSPR_IO option only on platforms + * where PTYSTREAM is not implemented) + */ + +#ifndef _LTERMPRIVATE_H + +#define _LTERMPRIVATE_H 1 + +/* Standard C header files */ +#ifndef _STRING_H +#include +#endif + +/* public declarations */ +#include "lineterm.h" +#include "tracelog.h" + +/* private declarations */ + +/* Force use of basic NSPR API if MOZILLA_CLIENT or USE_NSPR_IO are defined */ +#if defined(MOZILLA_CLIENT) || defined(USE_NSPR_IO) +#define USE_NSPR_BASE 1 +#endif + +/* pseudo-TTY stream interface */ +#ifndef _PTYSTREAM_H +#include "ptystream.h" +#endif + +#define LTERM_ERROR TLOG_ERROR +#define LTERM_WARNING TLOG_WARNING +#define LTERM_LOG(procname,level,args) TLOG_PRINT(LTERM_TLOG_MODULE,procname,level,args) +#define LTERM_LOGUNICODE(procname,level,args) TLOG_UNICHAR(LTERM_TLOG_MODULE,procname,level,args) + +#ifdef USE_NSPR_BASE /* Use basic NSPR API (excluding I/O) */ + +#include "nspr.h" + +#define assert PR_ASSERT + +#define int32 PRInt32 + +#define getenv PR_GetEnv + +#define MALLOC(x) PR_Malloc(x) +#define REALLOC(x,y) PR_Realloc((x),(y)) +#define CALLOC(x,y) PR_Calloc((x),(y)) +#define FREE(x) PR_Free(x) + +#else /* not USE_NSPR_BASE */ + +#include + +#define int32 long + +#define MALLOC(x) malloc(x) +#define REALLOC(x,y) realloc((x),(y)) +#define CALLOC(x,y) calloc((x),(y)) +#define FREE(x) free(x) + +#endif /* not USE_NSPR_BASE */ + + +#ifdef USE_NSPR_IO /* Use NSPR I/O API (no PTY implementation) */ + +#ifdef LINUX +#include +#endif + +typedef PRFileDesc *FILEDESC; +#define NULL_FILEDESC 0 +#define VALID_FILEDESC(x) (x != 0) + +typedef PRFileDesc FILESTREAM; + +#define SIZE_T PRInt32 +#define WRITE PR_Write +#define READ PR_Read +#define CLOSE(x) (PR_Close(x) != PR_SUCCESS) +#define PIPE(x) (PR_CreatePipe((x),(x)+1) != PR_SUCCESS) + +#define POLL(x,y,z) PR_Poll((x),(y),(z)) +#define POLLFD PRPollDesc +#define POLL_EVENTS in_flags +#define POLL_REVENTS out_flags +#define POLL_READ PR_POLL_READ + +#define PROCESS PRProcess * +#define NULL_PROCESS 0 +#define VALID_PROCESS(x) (x != 0) + +#else /* not USE_NSPR_IO */ + +/* system header files */ +#include +#include + +/* Diagnostic/debugging files */ +#include +#include +#include + +#if defined(SOLARIS) +#include +#elif defined(LINUX) +#include +#endif + +typedef int FILEDESC; +#define NULL_FILEDESC -1 +#define VALID_FILEDESC(x) (x >= 0) + +typedef FILE FILESTREAM; + +#define SIZE_T size_t +#define WRITE write +#define READ read +#define CLOSE(x) close(x) +#define PIPE(x) pipe(x) + +#define POLL(x,y,z) poll((x),(y),(z)) +#define POLLFD pollfd +#define POLL_EVENTS events +#define POLL_REVENTS revents +#define POLL_READ POLLIN + +#define PROCESS long +#define NULL_PROCESS 0 +#define VALID_PROCESS(x) (x > 0) + +#endif /* not USE_NSPR_IO */ + + +#ifdef USE_NSPR_LOCK /* Use NSPR lock API */ + +#define MUTEX_DECLARE(x) PRLock *x +#define MUTEX_INITIALIZE(x) ((x=PR_NewLock()) == NULL) +#define MUTEX_LOCK(x) PR_Lock(x) +#define MUTEX_UNLOCK(x) PR_Unlock(x) +#define MUTEX_DESTROY(x) PR_DestroyLock(x) + +#define THREAD_DECLARE(x) PRThread *x +#define THREAD_CREATE ((x=PR_CreateThread(PR_USER_THREAD, (y), (z), \ + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, \ + PR_JOINABLE_THREAD, 0)) == NULL) +#define THREAD_SELF PR_GetCurrentThread +#define THREAD_EQUAL(x,y) ((x) == (y)) +#define THREAD_JOIN(x) (PR_JoinThread(x) != PR_SUCCESS) + +#else /* not USE_NSPR_LOCK */ + +#include + +#define MUTEX_DECLARE(x) pthread_mutex_t x +#define MUTEX_INITIALIZE(x) pthread_mutex_init(&(x), NULL) +#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) +#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) +#define MUTEX_DESTROY(x) pthread_mutex_destroy(&(x)) + +#define THREAD_DECLARE(x) pthread_t x +#define THREAD_CREATE(x,y,z) pthread_create(&(x),NULL,(y),(z)) +#define THREAD_SELF pthread_self +#define THREAD_EQUAL(x,y) pthread_equal(x,y) +#define THREAD_JOIN(x) pthread_join((x),NULL) + +#endif /* not USE_NSPR_LOCK */ + + +#define MAXTERM 256 /* Maximum number of LTERMs; + * affects static memory "footprint" + */ + +#define MAXCOL 4096 /* Maximum columns in line buffer; + * affects static memory "footprint"; + * the only limitation on this value is that + * it must fit into a UNICHAR, because of the + * way lterm_write and ltermWrite implement + * the input buffer pipe. + */ + +#define MAXROW 1024 /* Maximum rows in screen; + * primarily affects dynamically allocated + * memory + */ + +/* The only obvious limitation on the following is that they should be + * significantly less than MAXCOL + */ +#define MAXPROMPT 256 /* Maximum length of prompt regexp+1 */ +#define MAXRAWINCOMPLETE 5 /* Maximum incomplete raw buffer size */ +#define MAXSTREAMTERM 11 /* Maximum stream terminator buffer size */ +#define MAXCOOKIESTR 64 /* Maximum length of cookie string+1 */ +#define MAXESCAPEPARAMS 16 /* Maximum no. of numeric ESCAPE parameters */ +#define MAXSTRINGPARAM 512 /* Maximum length of string ESCAPE parameters */ + +#define MAXPTYIN 128 /* 1/2 POSIX minimum MAX_INPUT for PTY */ + +#define MAXCOLM1 (MAXCOL-1) /* Maximum columns in line buffer - 1 */ + +#define MAXTTYCONTROL 8 /* Maximum TTY control character list */ +#define TTYINTERRUPT 0 +#define TTYERASE 1 +#define TTYKILL 2 +#define TTYEOF 3 +#define TTYSUSPEND 4 +#define TTYREPRINT 5 +#define TTYDISCARD 6 +#define TTYWERASE 7 + +/* input modes */ +#define LTERM0_RAW_MODE 0 +#define LTERM1_CANONICAL_MODE 1 +#define LTERM2_EDIT_MODE 2 +#define LTERM3_COMPLETION_MODE 3 + +/* completion request codes */ +#define LTERM_NO_COMPLETION 0 +#define LTERM_TAB_COMPLETION 1 +#define LTERM_HISTORY_COMPLETION 2 + +/* output modes */ +#define LTERM0_STREAM_MODE 0 +#define LTERM1_SCREEN_MODE 1 +#define LTERM2_LINE_MODE 2 + +/* character operation codes */ +#define LTERM_INSERT_CHAR 0 +#define LTERM_DELETE_CHAR 1 +#define LTERM_ERASE_CHAR 2 + +/* List of characters escaped in XML */ +#define LTERM_AMP_ESCAPE 0 +#define LTERM_LT_ESCAPE 1 +#define LTERM_GT_ESCAPE 2 +#define LTERM_QUOT_ESCAPE 3 +#define LTERM_APOS_ESCAPE 4 + +#define LTERM_XML_ESCAPES 5 +#define LTERM_PLAIN_ESCAPES 3 + +/* input buffer pipe header "character" count */ +#define PIPEHEADER 2 + +/* input buffer pipe header components */ +#define PHDR_CHARS 0 +#define PHDR_TYPE 1 + +/* LTERM read in/out parameter structure */ +struct LtermRead { + UNICHAR *buf; /* Pointer to Unicode character buffer (IN param) */ + UNISTYLE *style; /* Pointer to character style buffer (IN param) */ + int max_count; /* max. number of characters in buffers (IN param) */ + int read_count; /* actual number of characters in buffers */ + int opcodes; /* Returned opcodes */ + int buf_row; /* row at which to display buffer data */ + int buf_col; /* starting column at which to display buffer data */ + int cursor_row; /* final cursor row position */ + int cursor_col; /* final cursor column position */ +}; + +/* LTERM input structure: managed by lterm_write */ +struct LtermInput { + + UNICHAR inputBuf[PIPEHEADER+MAXCOL]; /* holds data read from input buffer + * pipe + */ + int inputBufBytes; /* Count of bytes already read in */ + + int inputMode; /* input mode: + * 0 = raw mode + * 1 = canonical mode + * 2 = edit + canonical mode + * 3 = completion + edit + canonical mode + */ + + int escapeFlag; /* processing ESCAPE in line mode */ + int escapeCSIFlag; /* processing ESCAPE Code Sequence Introducer */ + int escapeCSIArg; /* ESCAPE Code Sequence Argument value */ + + int inputOpcodes; /* input opcodes */ + + int clearInputLine; /* true if input line buffer needs to be + * cleared (after echoing) */ + + UNICHAR inputLine[MAXCOL]; /* input line buffer: + only MAXCOL-1 characters should actually + be inserted in the buffer, to allow + one character padding if necessary */ + + int inputChars; /* length of input line (characters); + * should never exceed MAXCOL-1, + * to allow for null termination + */ + int inputCols; /* number of displayed columns in input line; + * a column corresponds to a single + * plain text character transmitted to the + * subordinate process, although it may occupy + * multiple character positions, e.g., + * e.g., < represents "<" + */ + int inputGlyphs; /* number of displayed glyphs in input line; + * a glyph corresponds to a logical column + * on the layout, i.e., a single Unicode + * character or an XML element, such as an + * iconic representiion of an URI. + */ + + unsigned short inputColCharIndex[MAXCOL]; /* starting character index of + * each column, including the + * cursor column at end of line. + * (inputCols+1 values should be + * defined) + */ + + unsigned short inputGlyphCharIndex[MAXCOL]; /* starting character index + * of each glyph, including + * empty glyph at the end of + * the line. + * (inputGlyphs+1 values + * should be defined) + */ + unsigned short inputGlyphColIndex[MAXCOL]; /* starting column index of + * each glyph + * (inputGlyphs+1 values) + */ + + int inputCursorGlyph; /* current input cursor glyph number (>=0) */ +}; + +/* LtermOutput poll structure index count and values */ +#define POLL_COUNT 3 +#define POLL_INPUTBUF 0 +#define POLL_STDOUT 1 +#define POLL_STDERR 2 + +/* LTERM output structure: managed by lterm_read */ +struct LtermOutput { + struct POLLFD pollFD[POLL_COUNT]; /* output polling structure */ + long callbackTag[POLL_COUNT]; /* GTK callback tag for each FD (0 if none) */ + int nfds; /* count of "files" to be polled */ + int outputMode; /* output mode: + * 0 = full screen mode + * 1 = line mode + * 2 = command line mode + */ + + UNICHAR streamTerminator[MAXSTREAMTERM]; /* stream terminator buffer */ + int streamOpcodes; /* Stream opcodes */ + int savedOutputMode; /* saved output mode (prior to stream mode) */ + + int insertMode; /* character insert mode */ + int automaticNewline; /* automatic newline mode */ + + UNISTYLE styleMask; /* current output style mask */ + + char rawOUTBuf[MAXRAWINCOMPLETE]; /* incomplete raw STDOUT buffer */ + int rawOUTBytes; /* incomplete raw STDOUT byte count */ + + char rawERRBuf[MAXRAWINCOMPLETE]; /* incomplete raw STDERR buffer */ + int rawERRBytes; /* incomplete raw STDERR byte count */ + + UNICHAR decodedOutput[MAXCOL]; /* decoded output buffer: + only MAXCOL-1 characters should actually + be inserted in the buffer, to allow + one character padding if necessary */ + UNISTYLE decodedStyle[MAXCOL]; /* decoded output style buffer */ + int decodedChars; /* decoded character count; + should never exceed MAXCOL-1 */ + int incompleteEscapeSequence; /* Incomplete ESCAPE sequence flag */ + + UNICHAR outputLine[MAXCOL]; /* output line buffer (processed); + only MAXCOL-1 characters should actually + be inserted in the buffer, to allow + one character padding if necessary */ + UNISTYLE outputStyle[MAXCOL]; /* output style buffer for each character */ + + int outputChars; /* length of output line (characters) + should never exceed MAXCOL-1 */ + int outputCursorChar; /* output cursor character position (>=0) */ + int promptChars; /* prompt character count */ + int outputModifiedChar; /* leftmost modified character in output line */ + + int cursorRow, cursorCol; /* screen cursor row and column */ + + int rowCols[MAXROW]; /* count of columns in each row (>=0) */ + + int modifiedCol[MAXROW]; /* first modified column in each row; + -1 if no column has been modified */ + + UNICHAR *screenChar; /* Screen character array (screenSize long) */ + UNISTYLE *screenStyle; /* Screen style array (screenSize long) */ +}; + +/* LTERM process structure: managed by lterm_create, lterm_close */ +struct LtermProcess { + PROCESS processID; /* process ID */ + FILEDESC processIN; /* process input pipe */ + FILEDESC processOUT; /* process output pipe */ + FILEDESC processERR; /* process error pipe */ +}; + +/* line terminal (LTERM) structure: managed by lterm_open, lterm_close */ +struct lterms { + int opened; /* LTERM opened status flag */ + int suspended; /* LTERM suspended flag: + * an LTERM is suspended when an error + * occurs, to prevent further I/O operations + * which have unpredictable results. + * The LTERM still needs to be closed to + * release any resources used by it. + * (a suspended LTERM is still open) + */ + + MUTEX_DECLARE(adminMutex); /* LTERM administrative mutex */ + MUTEX_DECLARE(outputMutex); /* LTERM output thread mutex */ + + int adminMutexLocked; /* administrative mutex lock status */ + int outputMutexLocked; /* output mutex lock status */ + + FILEDESC writeBUFFER, readBUFFER; /* input character BUFFER pipe */ + + int options; /* TTY options */ + int ptyMode; /* pseudo-TTY mode flag */ + int noTTYEcho; /* no TTY echo flag */ + int disabledInputEcho; /* disabled input echo flag */ + + int processType; /* Process type code */ + int maxInputMode; /* maximum allowed input mode value */ + int readERRfirst; /* Read STDERR before STDOUT */ + int interleave; /* interleave STDERR/STDOUT flag */ + UNICHAR control[MAXTTYCONTROL]; /* TTY control characters */ + + int commandNumber; /* output command number + * (0 if not command line) + */ + unsigned short lastCommandNum; /* last command number */ + int completionRequest; /* command completion request code: + * LTERM_NO_COMPLETION, or + * LTERM_TAB_COMPLETION, or + * LTERM_HISTORY_COMPLETION + */ + int completionChars; /* command completion insert count */ + + int inputBufRecord; /* True if input buffer contains record */ + + int inputLineBreak; /* True if input line was transmitted + * and plain text copy saved in echo buffer + */ + UNICHAR echoLine[MAXCOL]; /* Plain text of echo line */ + int echoChars; /* Count of echo characters */ + + int nRows; /* Number of rows */ + int nCols; /* Number of columns */ + long screenSize; /* Screen size, in characters + = nRows*nCols */ + + UNICHAR promptRegexp[MAXPROMPT]; /* prompt regular expression + JUST A LIST OF DELIMITERS AT PRESENT */ + + char cookie[MAXCOOKIESTR]; /* cookie string */ + + struct ptys pty; /* pseudo-tty (PTY) stream info for LTERM */ + struct LtermProcess ltermProcess; /* LTERM process structure */ + struct LtermInput ltermInput; /* LTERM input structure */ + struct LtermOutput ltermOutput; /* LTERM output structure */ +}; + +/* LTERM global variables */ +typedef struct { + int initialized; /* Initialization flag */ + struct lterms *termList[MAXTERM]; /* List of LTERMS */ + MUTEX_DECLARE(listMutex); /* Thread lock to access to LTERM list */ + UNICHAR metaDelimiter; /* Meta command delimiter (usually :) */ + char escapeChars[LTERM_XML_ESCAPES+1]; /* String of chars escaped in XML */ + UNICHAR* escapeSeq[LTERM_XML_ESCAPES]; /* XML character escape sequences */ + int escapeLen[LTERM_XML_ESCAPES]; /* XML char. escape sequence lengths */ +} LtermGlobal; + +extern LtermGlobal ltermGlobal; + + +/* Visible prototypes */ + +/* ltermIO.c */ +int ltermSendLine(struct lterms *lts, UNICHAR uch, + int echoControl, int completionCode); +int ltermRead(struct lterms *lts, struct LtermRead *ltr, int timeout); + +/* ltermInput.c */ +int ltermPlainTextInput(struct lterms *lts, + const UNICHAR *buf, int count, int *opcodes); +int ltermCancelCompletion(struct lterms *lts); +int ltermInsertChar(struct LtermInput *lti, UNICHAR uch); +void ltermSwitchToRawMode(struct lterms *lts); +void ltermClearInputLine(struct lterms *lts); +int ltermDeleteGlyphs(struct LtermInput *lti, int count); +int ltermSendData(struct lterms *lts, const UNICHAR *buf, int count); + +/* ltermOutput.c */ +int ltermProcessOutput(struct lterms *lts, int *opcodes); +int ltermReceiveData(struct lterms *lts, int readERR); +void ltermClearOutputLine(struct lterms *lts); +int ltermClearOutputScreen(struct lterms *lts); +int ltermSwitchToStreamMode(struct lterms *lts, int streamOpcodes, + const UNICHAR *streamTerminator); +int ltermSwitchToScreenMode(struct lterms *lts); +int ltermSwitchToLineMode(struct lterms *lts); + +/* ltermEscape.c */ +int ltermProcessEscape(struct lterms *lts, const UNICHAR *buf, + int count, const UNISTYLE *style, int *consumed, int *opcodes); +int ltermInsDelEraseChar(struct lterms *lts, int count, int action); + +#endif /* _LTERMPRIVATE_H */ diff --git a/mozilla/extensions/xmlterm/base/mozILineTerm.idl b/mozilla/extensions/xmlterm/base/mozILineTerm.idl new file mode 100644 index 00000000000..01536c2b885 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozILineTerm.idl @@ -0,0 +1,88 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +/* mozILineTerm.idl: Javascript-accessible interface to LineTerm + */ + +#include "nsISupports.idl" +#include "domstubs.idl" + +%{C++ +class nsIDOMDocument; +%} + +[scriptable, uuid(0eb82b00-43a2-11d3-8e76-006008948af5)] + +interface mozILineTerm : nsISupports +{ + attribute long cursorRow; + attribute long cursorColumn; + attribute boolean echoFlag; + + /** Opens LineTerm, a line-oriented terminal interface (without graphics) + * @param command name of command to be executed; usually a shell, + * e.g., "/bin/sh"; if set to null string, the command name is + * determined from the environment variable SHELL + * @param promptRegexp command prompt regular expression (for future use); + * at the moment, any string terminated by one of the characters + * "#$%>?", followed by a space, is assumed to be a prompt + * @param options LineTerm option bits (usually 0; see lineterm.h) + * @param processType command shell type; if set to -1, type is determined + * from the command name + * @param domDoc DOM document object associated with the LineTerm + * (document.cookie will be defined for this document on return) + */ + void Open(in wstring command, in wstring promptRegexp, + in PRInt32 options, in PRInt32 processType, + in nsIDOMDocument domDoc); + + /** Closes LineTerm + * @param aCookie document.cookie string for authentication + */ + void Close(in wstring aCookie); + + /** Writes string to LineTerm as if the user had typed it (command input) + * @param buf string to be transmitted to LineTerm + * @param aCookie document.cookie string for authentication + */ + void Write(in wstring buf, in wstring aCookie); + + /** Read output data string and parameters from LineTerm (command output) + * @param opcodes (output) output data descriptor bits (see lineterm.h) + * @param buf_row (output) row number (>=-1) + (-1 denotes line mode and 0 represents bottom row) + * @param buf_col (output) column number (>=0) + * @param aCookie document.cookie string for authentication + * @return output data string from LineTerm + */ + wstring Read(out PRInt32 opcodes, out PRInt32 buf_row, + out PRInt32 buf_col, in wstring aCookie); +}; + + +%{ C++ +#define MOZLINETERM_CID \ +{ /* 0eb82b01-43a2-11d3-8e76-006008948af5 */ \ + 0x0eb82b01, 0x43a2, 0x11d3, \ +{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} } + +extern nsresult +NS_NewLineTerm(mozILineTerm** aLineTerm); +%} diff --git a/mozilla/extensions/xmlterm/base/mozILineTermAux.h b/mozilla/extensions/xmlterm/base/mozILineTermAux.h new file mode 100644 index 00000000000..4bfb75a3d6d --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozILineTermAux.h @@ -0,0 +1,122 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozILineTermAux.h: auxiliary interface for LineTerm (not XPCONNECTed) +// This adds some XPCOM-only methods to the XPCOM/XPCONNECT interface +// mozILineTerm (unregistered) + +#ifndef mozILineTermAux_h___ +#define mozILineTermAux_h___ + +#include "nsISupports.h" + +#include "nscore.h" + +#include "nsIObserver.h" +#include "mozILineTerm.h" + +/* {0eb82b10-43a2-11d3-8e76-006008948af5} */ +#define MOZILINETERMAUX_IID_STR "0eb82b10-43a2-11d3-8e76-006008948af5" +#define MOZILINETERMAUX_IID \ + {0x0eb82b10, 0x43a2, 0x11d3, \ + { 0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5 }} + +class mozILineTermAux : public mozILineTerm { + public: + NS_DEFINE_STATIC_IID_ACCESSOR(MOZILINETERMAUX_IID) + + // mozILineTerm interface + NS_IMETHOD GetCursorRow(PRInt32 *aCursorRow) = 0; + NS_IMETHOD SetCursorRow(PRInt32 aCursorRow) = 0; + + NS_IMETHOD GetCursorColumn(PRInt32 *aCursorColumn) = 0; + NS_IMETHOD SetCursorColumn(PRInt32 aCursorColumn) = 0; + + NS_IMETHOD Open(const PRUnichar *command, + const PRUnichar *promptRegexp, + PRInt32 options, PRInt32 processType, + nsIDOMDocument *domDoc) = 0; + + NS_IMETHOD Close(const PRUnichar* aCookie) = 0; + + NS_IMETHOD Write(const PRUnichar *buf, const PRUnichar* aCookie) = 0; + + NS_IMETHOD Read(PRInt32 *opcodes, + PRInt32 *buf_row, PRInt32 *buf_col, + const PRUnichar* aCookie, + PRUnichar **_retval) = 0; + + // mozILineTermAux interface add ons + // (not scriptable, no authentication cookie required) + + /** Opens LineTerm, a line-oriented terminal interface (without graphics) + * @param command name of command to be executed; usually a shell, + * e.g., "/bin/sh"; if set to null string, the command name is + * determined from the environment variable SHELL + * @param promptRegexp command prompt regular expression (for future use); + * at the moment, any string terminated by one of the characters + * "#$%>?", followed by a space, is assumed to be a prompt + * @param options LineTerm option bits (usually 0; see lineterm.h) + * @param processType command shell type; if set to -1, type is determined + * from the command name + * @param domDoc DOM document object associated with the LineTerm + * (document.cookie will be defined for this document on return) + * @param aCookie (output) cookie associated with LineTerm + */ + NS_IMETHOD OpenAux(const PRUnichar *command, + const PRUnichar *promptRegexp, + PRInt32 options, PRInt32 processType, + nsIDOMDocument *domDoc, + nsIObserver* anObserver, + nsString& aCookie) = 0; + + /** Suspend/restores LineTerm operation + * @param aSuspend suspension state flag + */ + NS_IMETHOD SuspendAux(PRBool aSuspend) = 0; + + /** Closes LineTerm + */ + NS_IMETHOD CloseAux(void) = 0; + + /** Close all LineTerms, not just this one + */ + NS_IMETHOD CloseAllAux(void) = 0; + + /** Read output data and style strings and parameters from LineTerm + * @param opcodes (output) output data descriptor bits (see lineterm.h) + * @param buf_row (output) row number (>=-1) + (-1 denotes line mode and 0 represents bottom row) + * @param buf_col (output) column number (>=0) + * @param _retval (output) success code + * @param retstyle (output) output style string + * @return output data string from LineTerm + */ + NS_IMETHOD ReadAux(PRInt32 *opcodes, + PRInt32 *buf_row, PRInt32 *buf_col, + PRUnichar **_retval, PRUnichar **retstyle) = 0; +}; + +// Factory for mozILineTermAux + +extern nsresult +NS_NewLineTermAux(mozILineTermAux** aLineTermAux); + +#endif /* mozILineTermAux_h___ */ diff --git a/mozilla/extensions/xmlterm/base/mozIXMLTermShell.idl b/mozilla/extensions/xmlterm/base/mozIXMLTermShell.idl new file mode 100644 index 00000000000..2ae58044ca2 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozIXMLTermShell.idl @@ -0,0 +1,86 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +/* mozIXMLTermShell.idl: Javascript-accessible wrapper for mozIXMLTerminal + */ + +#include "nsISupports.idl" +#include "domstubs.idl" +#include "mozILineTerm.idl" + +%{C++ +class nsILineTerm; +class nsIDOMWindow; +%} + +[scriptable, uuid(0eb82b30-43a2-11d3-8e76-006008948af5)] + +interface mozIXMLTermShell : nsISupports +{ + readonly attribute long currentEntryNumber; /* current entry (command) no. */ + attribute long history; /* command history buffer count */ + attribute wstring prompt; /* HTML prompt string */ + + /** Initializes XMLterm in specified window + * @param contentWin content window object + * @param URL URL of document to be loaded in the window + * (set to null string if document is already loaded in window) + * @param args argument string to be passed to XMLterm + * (at the moment this just contains any initial input data) + */ + void Init(in nsIDOMWindow contentWin, in wstring URL, in wstring args); + + /** Finalizes (closes) XMLterm + */ + void Finalize(); + + /** Polls for readable data from XMLterm + */ + void Poll(); + + /** Writes string to terminal as if the user had typed it (command input) + * @param buf string to be transmitted to terminal + * @param aCookie document.cookie string for authentication + */ + void SendText(in wstring buf, in wstring cookie); + + /** Opens new XMLterm window with specified args (not yet implemented) + * @param args argument string to be passed to XMLterm + * (at the moment this just contains any initial input data) + */ + void NewXMLTermWindow(in wstring args); + + /** Exit browser, closing all windows (not yet implemented) + */ + void Exit(); +}; + + +%{C++ + +#define MOZXMLTERMSHELL_CID \ +{ /* 0eb82b31-43a2-11d3-8e76-006008948af5 */ \ + 0x0eb82b31, 0x43a2, 0x11d3, \ +{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} } + +extern nsresult +NS_NewXMLTermShell(mozIXMLTermShell** aXMLTermShell); +%} + diff --git a/mozilla/extensions/xmlterm/base/mozIXMLTermStream.h b/mozilla/extensions/xmlterm/base/mozIXMLTermStream.h new file mode 100644 index 00000000000..b61f49ed414 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozIXMLTermStream.h @@ -0,0 +1,78 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozIXMLTermStream.h: interface to display HTML/XML streams as documents +// (unregistered) + +#ifndef mozIXMLTermStream_h___ +#define mozIXMLTermStream_h___ + +#include "nscore.h" + +#include "nsISupports.h" +#include "nsIDOMDocument.h" +#include "nsIWebShell.h" +#include "nsIPresShell.h" +#include "nsIScriptContext.h" +#include "nsIInputStream.h" + +/* {0eb82b40-43a2-11d3-8e76-006008948af5} */ +#define MOZIXMLTERMSTREAM_IID_STR "0eb82b40-43a2-11d3-8e76-006008948af5" +#define MOZIXMLTERMSTREAM_IID \ + {0x0eb82b40, 0x43a2, 0x11d3, \ + { 0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5 }} + +class mozIXMLTermStream : public nsIInputStream +{ + public: + NS_DEFINE_STATIC_IID_ACCESSOR(MOZIXMLTERMSTREAM_IID); + + // mozIXMLTermStream interface + + /** Open stream in specified frame, or in current frame if frameName is null + * @param aDOMWindow parent window + * @param frameName name of child frame in which to display stream, or null + * to display in parent window + * @param contentURL URL of stream content + * @param contentType MIME type of stream content + * @param maxResizeHeight maximum resize height (0=> do not resize) + * @return NS_OK on success + */ + NS_IMETHOD Open(nsIDOMWindow* aDOMWindow, + const char* frameName, + const char* contentURL, + const char* contentType, + PRInt32 maxResizeHeight) = 0; + + /** Write Unicode string to stream (blocks until write is completed) + * @param buf string to write + * @return NS_OK on success + */ + NS_IMETHOD Write(const PRUnichar* buf) = 0; +}; + +#define MOZXMLTERMSTREAM_CID \ +{ /* 0eb82b41-43a2-11d3-8e76-006008948af5 */ \ + 0x0eb82b41, 0x43a2, 0x11d3, \ +{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} } +extern nsresult +NS_NewXMLTermStream(mozIXMLTermStream** aXMLTermStream); + +#endif /* mozIXMLTermStream_h___ */ diff --git a/mozilla/extensions/xmlterm/base/mozIXMLTerminal.h b/mozilla/extensions/xmlterm/base/mozIXMLTerminal.h new file mode 100644 index 00000000000..5747bf541da --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozIXMLTerminal.h @@ -0,0 +1,127 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozIXMLTerminal.h: primary interface for XMLterm operations +// (unregistered) + +#ifndef mozIXMLTerminal_h___ +#define mozIXMLTerminal_h___ + +#include "nscore.h" + +#include "nsISupports.h" +#include "nsIDOMDocument.h" +#include "nsIWebShell.h" +#include "nsIPresShell.h" +#include "nsIScriptContext.h" + +#include "mozIXMLTermShell.h" + +/* {0eb82b20-43a2-11d3-8e76-006008948af5} */ +#define MOZIXMLTERMINAL_IID_STR "0eb82b20-43a2-11d3-8e76-006008948af5" +#define MOZIXMLTERMINAL_IID \ + {0x0eb82b20, 0x43a2, 0x11d3, \ + { 0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5 }} + +class mozIXMLTerminal : public nsISupports { + +public: + NS_DEFINE_STATIC_IID_ACCESSOR(MOZIXMLTERMINAL_IID) + + /** Initializes XMLterm in specified web shell + * @param aWebShell web shell in which to embed XMLterm + * @param aXMLTermShell scriptable wrapper shell for XMLterm + * @param URL URL of document to be loaded in the window + * (set to null string if document is already loaded in window) + * @param args argument string to be passed to XMLterm + * (at the moment this just contains any initial input data) + */ + NS_IMETHOD Init(nsIWebShell* aWebShell, + mozIXMLTermShell* aXMLTermShell, + const PRUnichar* aURL, + const PRUnichar* args) = 0; + + /** Finalizes (closes) XMLterm + */ + NS_IMETHOD Finalize(void) = 0; + + /** Polls for readable data from XMLterm + */ + NS_IMETHOD Poll(void) = 0; + + /** Gets current entry (command) number + * @param aNumber (output) current entry number + */ + NS_IMETHOD GetCurrentEntryNumber(PRInt32 *aNumber) = 0; + + /** Gets command history buffer count + * @param aHistory (output) history buffer count + */ + NS_IMETHOD GetHistory(PRInt32 *aHistory) = 0; + + /** Sets command history buffer count + * @param aHistory history buffer count + */ + NS_IMETHOD SetHistory(PRInt32 aHistory) = 0; + + /** Gets prompt string + * @param aPrompt (output) prompt string + */ + NS_IMETHOD GetPrompt(PRUnichar **aPrompt) = 0; + + /** Sets prompt string + * @param aPrompt prompt string + */ + NS_IMETHOD SetPrompt(const PRUnichar* aPrompt) = 0; + + /** Writes string to terminal as if the user had typed it (without authenitcation) + * @param aString string to be transmitted to terminal + */ + NS_IMETHOD SendTextAux(const nsString& aString) = 0; + + /** Writes string to terminal as if the user had typed it (command input) + * @param aString string to be transmitted to terminal + * @param aCookie document.cookie string for authentication + */ + NS_IMETHOD SendText(const nsString& aString, const PRUnichar* aCookie) = 0; + + /** Paste data from clipboard into XMLterm at current input line cursor location + */ + NS_IMETHOD Paste() = 0; + + /** Gets document associated with XMLterm + * @param aDoc (output) DOM document + */ + NS_IMETHOD GetDocument(nsIDOMDocument** aDoc) = 0; + + /** Gets presentation shell with XMLterm + * @param aPresShell (output) presentation shell + */ + NS_IMETHOD GetPresShell(nsIPresShell** aPresShell) = 0; +}; + +#define MOZXMLTERMINAL_CID \ +{ /* 0eb82b21-43a2-11d3-8e76-006008948af5 */ \ + 0x0eb82b21, 0x43a2, 0x11d3, \ +{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} } +extern nsresult +NS_NewXMLTerminal(mozIXMLTerminal** aXMLTerminal); + +#endif /* mozIXMLTerminal_h___ */ diff --git a/mozilla/extensions/xmlterm/base/mozLineTerm.cpp b/mozilla/extensions/xmlterm/base/mozLineTerm.cpp new file mode 100644 index 00000000000..b8208df4d73 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozLineTerm.cpp @@ -0,0 +1,681 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozLineTerm.cpp: class implementing mozILineTerm/mozILineTermAux interfaces, +// providing an XPCOM/XPCONNECT wrapper for the LINETERM module + +#include "stdio.h" + +#include "nspr.h" +#include "nscore.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "prlog.h" +#include "nsIAllocator.h" + +#include "nsIServiceManager.h" +#include "nsIPref.h" +#include "nsIPrincipal.h" + +#include "nsIDocument.h" +#include "nsIDOMHTMLDocument.h" + +#include "mozXMLT.h" +#include "mozXMLTermUtils.h" +#include "mozLineTerm.h" +#include "lineterm.h" + +#define MAXCOL 4096 // Maximum columns in line buffer + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); + +static NS_DEFINE_IID(kILineTermIID, MOZILINETERM_IID); +static NS_DEFINE_IID(kILineTermAuxIID, MOZILINETERMAUX_IID); + +static NS_DEFINE_IID(kLineTermCID, MOZLINETERM_CID); + +///////////////////////////////////////////////////////////////////////// +// mozLineTerm, mozLineTermAux factories +///////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewLineTerm(mozILineTerm** aLineTerm) +{ + NS_PRECONDITION(aLineTerm != nsnull, "null ptr"); + if (! aLineTerm) + return NS_ERROR_NULL_POINTER; + + *aLineTerm = new mozLineTerm(); + if (! *aLineTerm) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aLineTerm); + return NS_OK; +} + +nsresult +NS_NewLineTermAux(mozILineTermAux** aLineTermAux) +{ + NS_PRECONDITION(aLineTermAux != nsnull, "null ptr"); + if (! aLineTermAux) + return NS_ERROR_NULL_POINTER; + + *aLineTermAux = new mozLineTerm(); + if (! *aLineTermAux) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aLineTermAux); + return NS_OK; +} + +///////////////////////////////////////////////////////////////////////// +// mozLineTerm implementaion +///////////////////////////////////////////////////////////////////////// +PRBool mozLineTerm::mLoggingEnabled = false; + +mozLineTerm::mozLineTerm() : + mCursorRow(0), + mCursorColumn(0), + mSuspended(false), + mEchoFlag(true), + mObserver(nsnull), + mCookie(""), + mLastTime(LL_ZERO) +{ + NS_INIT_REFCNT(); + mLTerm = lterm_new(); +} + + +mozLineTerm::~mozLineTerm() +{ + lterm_delete(mLTerm); + mObserver = nsnull; +} + + +// Implement AddRef and Release +NS_IMPL_ADDREF(mozLineTerm) +NS_IMPL_RELEASE(mozLineTerm) + + +NS_IMETHODIMP +mozLineTerm::QueryInterface(REFNSIID aIID,void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + //XMLT_LOG(mozLineTerm::QueryInterface,30,("0x%x\n",aIID)); + + if ( aIID.Equals(kISupportsIID)) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(mozILineTermAux*,this)); + + } else if ( aIID.Equals(mozILineTerm::GetIID()) ) { + *aInstancePtr = NS_STATIC_CAST(mozILineTerm*, + NS_STATIC_CAST(mozILineTermAux*,this)); + + } else if ( aIID.Equals(mozILineTermAux::GetIID()) ) { + *aInstancePtr = NS_STATIC_CAST(mozILineTermAux*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +/** Checks if preference settings are secure for LineTerm creation and use + */ +NS_IMETHODIMP mozLineTerm::ArePrefsSecure(PRBool *_retval) +{ + nsresult result; + + XMLT_LOG(mozLineTerm::ArePrefsSecure,30,("\n")); + + if (!_retval) + return NS_ERROR_FAILURE; + + *_retval = false; + + nsIPref* prefService; + nsServiceManager::GetService(kPrefServiceCID, NS_GET_IID(nsIPref), + (nsISupports**) &prefService); + if (!prefService) + return NS_ERROR_FAILURE; + + // Check if Components JS object is secure + PRBool checkXPC; + result = prefService->GetBoolPref("security.checkxpconnect", &checkXPC); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + if (!checkXPC) { + XMLT_ERROR("mozLineTerm::ArePrefsSecure: Error - Please add the line\n" + " pref(\"security.checkxpcconnect\",true);\n" + "to your preferences file (.mozilla/prefs.js)\n"); + *_retval = false; +#if 0 // Temporarily comented out + return NS_OK; +#endif + } + + nsCAutoString secString ("security.policy."); + /* Get global policy name. */ + char *policyStr; + + result = prefService->CopyCharPref("javascript.security_policy", &policyStr); + if (NS_SUCCEEDED(result) && policyStr) { + secString.Append(policyStr); + nsAllocator::Free(policyStr); + } else { + secString.Append("default"); + } + + secString.Append(".htmldocument.cookie"); + + char* prefStr = secString.ToNewCString(); + XMLT_LOG(mozLineTerm::ArePrefsSecure,32, ("prefStr=%s\n", prefStr)); + + char *secLevelString; + result = prefService->CopyCharPref(prefStr, &secLevelString); + nsAllocator::Free(prefStr); + + if (NS_FAILED(result) || !secLevelString) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozLineTerm::ArePrefsSecure,32, + ("secLevelString=%s\n", secLevelString)); + + *_retval = (PL_strcmp(secLevelString, "sameOrigin") == 0); + nsAllocator::Free(secLevelString); + + if (!(*_retval)) { + XMLT_ERROR("mozLineTerm::ArePrefsSecure: Error - Please add the line\n" + " pref(\"security.policy.default.htmldocument.cookie\",\"sameOrigin\");\n" + "to your preferences file (.mozilla/prefs.js)\n"); + } + + return NS_OK; +} + + +/** Checks document principal to ensure it has LineTerm creation privileges. + * Returns the principal string if the principal is secure, + * and a (zero length) null string if the principal is insecure. + */ +NS_IMETHODIMP mozLineTerm::GetSecurePrincipal(nsIDOMDocument *domDoc, + char** aPrincipalStr) +{ + XMLT_LOG(mozLineTerm::GetSecurePrincipal,30,("\n")); + + if (!aPrincipalStr) + return NS_ERROR_FAILURE; + + *aPrincipalStr = nsnull; + + // Get principal string + nsCOMPtr doc = do_QueryInterface(domDoc); + if (!doc) + return NS_ERROR_FAILURE; + + nsCOMPtr principal=dont_AddRef(doc->GetDocumentPrincipal()); + +#if 0 // Temporarily comented out, because ToString is not immplemented + result = principal->ToString(aPrincipalStr); + if (NS_FAILED(result) || !*aPrincipalStr) + return NS_ERROR_FAILURE; +#else + const char temStr[] = "unknown"; + PRInt32 temLen = strlen(temStr); + *aPrincipalStr = strncpy((char*) nsAllocator::Alloc(temLen+1), + temStr, temLen+1); +#endif + + XMLT_LOG(mozLineTerm::GetSecurePrincipal,32,("aPrincipalStr=%s\n", + *aPrincipalStr)); + + // Check if principal is secure + PRBool insecure = false; + if (insecure) { + // Return null string + XMLT_ERROR("mozLineTerm::GetSecurePrincipal: Error - " + "Insecure document principal %s\n", *aPrincipalStr); + nsAllocator::Free(*aPrincipalStr); + *aPrincipalStr = (char*) nsAllocator::Alloc(1); + **aPrincipalStr = '\0'; + } + + return NS_OK; +} + + +/** Open LineTerm without callback + */ +NS_IMETHODIMP mozLineTerm::Open(const PRUnichar *command, + const PRUnichar *promptRegexp, + PRInt32 options, PRInt32 processType, + nsIDOMDocument *domDoc) +{ + if (mSuspended) { + XMLT_ERROR("mozLineTerm::Open: Error - LineTerm %d is suspended\n", + mLTerm); + return NS_ERROR_FAILURE; + } + + nsAutoString aCookie; + return OpenAux(command, promptRegexp, options, processType, domDoc, + nsnull, aCookie); +} + + +/** Open LineTerm, with an Observer for callback to process new input/output + */ +NS_IMETHODIMP mozLineTerm::OpenAux(const PRUnichar *command, + const PRUnichar *promptRegexp, + PRInt32 options, PRInt32 processType, + nsIDOMDocument *domDoc, + nsIObserver* anObserver, + nsString& aCookie) +{ + nsresult result; + + XMLT_LOG(mozLineTerm::Open,20,("\n")); + + // Ensure that preferences are secure for LineTerm creation and use + PRBool arePrefsSecure; + result = ArePrefsSecure(&arePrefsSecure); +#if 0 // Temporarily comented out + if (NS_FAILED(result) || !arePrefsSecure) + return NS_ERROR_FAILURE; +#endif + + // Ensure that document principal is secure for LineTerm creation + char* securePrincipal; + result = GetSecurePrincipal(domDoc, &securePrincipal); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + if (strlen(securePrincipal) == 0) { + nsAllocator::Free(securePrincipal); + XMLT_ERROR("mozLineTerm::OpenAux: Error - " + "Failed to create LineTerm for insecure document principal\n"); + return NS_ERROR_FAILURE; + } + + nsCOMPtr domHTMLDoc = do_QueryInterface(domDoc); + if (!domHTMLDoc) + return NS_ERROR_FAILURE; + + // Ensure that cookie attribute of document is defined + nsAutoString cookiePrefix ( "xmlterm=" ); + nsAutoString cookieStr; + result = domHTMLDoc->GetCookie(cookieStr); + + if (NS_SUCCEEDED(result) && + (cookieStr.Length() > cookiePrefix.Length()) && + (cookieStr.Find(cookiePrefix) == 0)) { + // Cookie value already defined for document; simply copy it + mCookie = cookieStr; + + } else { + // Create random session cookie + nsAutoString cookieValue; + result = mozXMLTermUtils::RandomCookie(cookieValue); + if (NS_FAILED(result)) + return result; + + mCookie = cookiePrefix; + mCookie += cookieValue; + + // Set new cookie value + result = domHTMLDoc->SetCookie(mCookie); + if (NS_FAILED(result)) + return result; + } + + // Return copy of cookie to caller + aCookie = mCookie; + + mObserver = anObserver; // non-owning reference + + // Convert cookie to CString + char* cookieCStr = mCookie.ToNewCString(); + XMLT_LOG(mozLineTerm::Open,22, ("mCookie=%s\n", cookieCStr)); + + if (anObserver != nsnull) { + result = lterm_open(mLTerm, NULL, cookieCStr, L"#$%>?", options, + processType, mozLineTerm::Callback, (void *) this); + } else { + result = lterm_open(mLTerm, NULL, cookieCStr, L"#$%>?", options, + processType, NULL, NULL); + } + + // Free cookie CString + nsAllocator::Free(cookieCStr); + + if (mLoggingEnabled) { + // Log time stamp for LineTerm open operation + nsAutoString timeStamp; + result = mozXMLTermUtils::TimeStamp(0, mLastTime, timeStamp); + if (NS_SUCCEEDED(result)) { + char* temStr = timeStamp.ToNewCString(); + fprintf(stderr, " LineTerm %d opened by principal %s\n", + temStr, mLTerm, securePrincipal); + nsAllocator::Free(temStr); + } + } + + if (result == 0) { + return NS_OK; + } else { + return NS_ERROR_FAILURE; + } +} + + +/** GTK-style callback funtion for mozLineTerm object + */ +void mozLineTerm::Callback(gpointer data, + gint source, + GdkInputCondition condition) +{ + mozLineTerm* lineTerm = (mozLineTerm*) data; + + //XMLT_LOG(mozLineTerm::Callback,50,("\n")); + + PR_ASSERT(lineTerm != nsnull); + PR_ASSERT(lineTerm->mObserver != nsnull); + + lineTerm->mObserver->Observe((nsISupports*) lineTerm, nsnull, nsnull); + return; +} + +/** Suspends (or restores) LineTerm activity depending upon aSuspend + */ +NS_IMETHODIMP mozLineTerm::SuspendAux(PRBool aSuspend) +{ + mSuspended = aSuspend; + return NS_OK; +} + + +/** Close LineTerm (a Finalize method) + */ +NS_IMETHODIMP mozLineTerm::Close(const PRUnichar* aCookie) +{ + if (!mCookie.Equals(aCookie)) { + XMLT_ERROR("mozLineTerm::Close: Error - Cookie mismatch\n"); + return NS_ERROR_FAILURE; + } + + if (mSuspended) { + XMLT_ERROR("mozLineTerm::Close: Error - LineTerm %d is suspended\n", + mLTerm); + return NS_ERROR_FAILURE; + } + + if (lterm_close(mLTerm) == 0) { + return NS_OK; + } else { + return NS_ERROR_FAILURE; + } + + mObserver = nsnull; +} + + +/** Close LineTerm (a Finalize method) + */ +NS_IMETHODIMP mozLineTerm::CloseAux(void) +{ + if (lterm_close(mLTerm) == 0) { + return NS_OK; + } else { + return NS_ERROR_FAILURE; + } + + mObserver = nsnull; +} + + +/** Close all LineTerm instances + */ +NS_IMETHODIMP mozLineTerm::CloseAllAux(void) +{ + lterm_close_all(); + return NS_OK; +} + + +/** Writes a string to LTERM + */ +NS_IMETHODIMP mozLineTerm::Write(const PRUnichar *buf, + const PRUnichar* aCookie) +{ + if (!mCookie.Equals(aCookie)) { + XMLT_ERROR("mozLineTerm::Write: Error - Cookie mismatch\n"); + return NS_ERROR_FAILURE; + } + + if (mSuspended) { + XMLT_ERROR("mozLineTerm::Write: Error - LineTerm %d is suspended\n", + mLTerm); + return NS_ERROR_FAILURE; + } + + XMLT_LOG(mozLineTerm::Write,30,("\n")); + + nsresult result; + UNICHAR ubuf[MAXCOL]; + int jLen, retCode; + PRBool newline = false; + + jLen = 0; + while ((jLen < MAXCOL-1) && (buf[jLen] != 0)) { + if (buf[jLen] == U_LINEFEED) + newline = true; + + ubuf[jLen++] = (UNICHAR) buf[jLen]; + } + + if (jLen >= MAXCOL-1) { + XMLT_ERROR("mozLineTerm::Write: Error - Buffer overflow\n"); + return NS_ERROR_FAILURE; + } + + if (mLoggingEnabled && (jLen > 0)) { + /* Log all input to STDERR */ + ucsprint(stderr, ubuf, jLen); + + nsAutoString timeStamp; + result = mozXMLTermUtils::TimeStamp(60, mLastTime, timeStamp); + + if (NS_SUCCEEDED(result) && (timeStamp.Length() > 0)) { + char* temStr = timeStamp.ToNewCString(); + fprintf(stderr, "\n", temStr); + nsAllocator::Free(temStr); + + } else if (newline) { + fprintf(stderr, "\n"); + } + } + + retCode = lterm_write(mLTerm, ubuf, jLen, LTERM_WRITE_PLAIN_INPUT); + if (retCode < 0) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +NS_IMETHODIMP mozLineTerm::Read(PRInt32 *opcodes, + PRInt32 *buf_row, PRInt32 *buf_col, + const PRUnichar* aCookie, + PRUnichar **_retval) +{ + if (!mCookie.Equals(aCookie)) { + XMLT_ERROR("mozLineTerm::Read: Error - Cookie mismatch\n"); + return NS_ERROR_FAILURE; + } + + if (mSuspended) { + XMLT_ERROR("mozLineTerm::Read: Error - LineTerm %d is suspended\n", + mLTerm); + return NS_ERROR_FAILURE; + } + + return ReadAux(opcodes, buf_row, buf_col, _retval, nsnull); +} + + +/** Reads a line from LTERM and returns it as a string (may be null string) + */ +NS_IMETHODIMP mozLineTerm::ReadAux(PRInt32 *opcodes, + PRInt32 *buf_row, PRInt32 *buf_col, + PRUnichar **_retval, PRUnichar **retstyle) +{ + UNICHAR ubuf[MAXCOL]; + UNISTYLE ustyle[MAXCOL]; + int cursor_row, cursor_col; + int retCode, j; + + XMLT_LOG(mozLineTerm::ReadAux,30,("\n")); + + retCode = lterm_read(mLTerm, 0, ubuf, MAXCOL-1, + ustyle, opcodes, + buf_row, buf_col, &cursor_row, &cursor_col); + if (retCode < 0) + return NS_ERROR_FAILURE; + + if (*opcodes == 0) { + // Return null pointer(s) + *_retval = nsnull; + + if (retstyle != nsnull) + *retstyle = nsnull; + + } else { + // Return output string + mCursorRow = cursor_row; + mCursorColumn = cursor_col; + + XMLT_LOG(mozLineTerm::Read,72,("cursor_col=%d\n", cursor_col)); + + int allocBytes = sizeof(PRUnichar)*(retCode + 1); + *_retval = (PRUnichar*) nsAllocator::Alloc(allocBytes); + + for (j=0; j are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozLineTerm.h: Declaration of mozLineTerm class +// which implements the LineTerm and LineTermAux interfaces. +// and provides an XPCOM/XPCONNECT wrapper to the LINETERM module + +#include "nspr.h" +#include "nscore.h" +#include "nsString.h" + +#include "nsIServiceManager.h" + +#include "nsIDocument.h" +#include "nsIDOMHTMLDocument.h" + +#include "mozILineTermAux.h" + +#define MAXCOL 4096 // Maximum columns in line buffer + +class mozLineTerm : public mozILineTermAux +{ +public: + mozLineTerm(); + virtual ~mozLineTerm(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // mozILineTerm interface + NS_IMETHOD GetCursorRow(PRInt32 *aCursorRow); + NS_IMETHOD SetCursorRow(PRInt32 aCursorRow); + + NS_IMETHOD GetCursorColumn(PRInt32 *aCursorColumn); + NS_IMETHOD SetCursorColumn(PRInt32 aCursorColumn); + + NS_IMETHOD GetEchoFlag(PRBool *aEchoFlag); + NS_IMETHOD SetEchoFlag(PRBool aEchoFlag); + + NS_IMETHOD Open(const PRUnichar *command, + const PRUnichar *promptRegexp, + PRInt32 options, PRInt32 processType, + nsIDOMDocument *domDoc); + + NS_IMETHOD Close(const PRUnichar* aCookie); + + NS_IMETHOD Write(const PRUnichar *buf, const PRUnichar* aCookie); + + NS_IMETHOD Read(PRInt32 *opcodes, + PRInt32 *buf_row, PRInt32 *buf_col, + const PRUnichar* aCookie, + PRUnichar **_retval); + + // mozILineTermAux interface add ons + // (not scriptable, no authentication cookie required) + NS_IMETHOD OpenAux(const PRUnichar *command, + const PRUnichar *promptRegexp, + PRInt32 options, PRInt32 processType, + nsIDOMDocument *domDoc, + nsIObserver* anObserver, + nsString& aCookie); + + NS_IMETHOD SuspendAux(PRBool aSuspend); + + NS_IMETHOD CloseAux(void); + + NS_IMETHOD CloseAllAux(void); + + NS_IMETHOD ReadAux(PRInt32 *opcodes, + PRInt32 *buf_row, PRInt32 *buf_col, + PRUnichar **_retval, PRUnichar **retstyle); + // others + + /** GTK event callback function + */ + static void Callback(gpointer data, + gint source, + GdkInputCondition condition); + + /** Flag controlling logging of user input to STDERR */ + static PRBool mLoggingEnabled; + +protected: + /** Checks if Mozilla preference settings are secure + * @param _retval (output) true if settings are secure + */ + NS_IMETHOD ArePrefsSecure(PRBool *_retval); + + /** Checks if document principal is secure and returns principal string + * @param domDOC DOM document object + * @param aPrincipalStr (output) document principal string + */ + NS_IMETHOD GetSecurePrincipal(nsIDOMDocument *domDoc, + char** aPrincipalStr); + + /** lineterm descriptor index returned by lterm_new (>= 0) */ + int mLTerm; + + /** current cursor row position */ + int mCursorRow; + + /** current cursor column position */ + int mCursorColumn; + + /** flag controlling whether is LineTerm is suspended */ + PRBool mSuspended; + + /** flag controlling input echo in LineTerm */ + PRBool mEchoFlag; + + /** non-owning reference to Observer to be notified when data is available + * for reading from LineTerm + */ + nsIObserver* mObserver; + + /** cookie string used for authentication (stored in document.cookie) */ + nsString mCookie; + + /** record of last time when timestamp was displayed in user input log */ + PRTime mLastTime; + +}; diff --git a/mozilla/extensions/xmlterm/base/mozXMLT.h b/mozilla/extensions/xmlterm/base/mozXMLT.h new file mode 100644 index 00000000000..a2ecd9bbe4d --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLT.h @@ -0,0 +1,67 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLT.h: XMLTerm common header + +#ifndef _MOZXMLT_H + +#define _MOZXMLT_H 1 + +// Standard C header files +#ifndef _STRING_H +#include +#endif + +// public declarations +#include "lineterm.h" +#include "tracelog.h" + +// private declarations + +#define XMLT_TLOG_MODULE 2 +#define XMLT_ERROR TLOG_ERROR +#define XMLT_WARNING TLOG_WARNING +#define XMLT_LOG(procname,level,args) TLOG_PRINT(XMLT_TLOG_MODULE,procname,level,args) + +// Tracing versions of NS_IMPL_ADDREF and NS_IMPL_RELEASE + +#define XMLT_IMPL_ADDREF(_class) \ +NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \ +{ \ + NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \ + ++mRefCnt; \ + XMLT_WARNING(#_class ":AddRef, mRefCnt=%d\n", mRefCnt); \ + return mRefCnt; \ +} + +#define XMLT_IMPL_RELEASE(_class) \ +NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \ +{ \ + NS_PRECONDITION(0 != mRefCnt, "dup release"); \ + --mRefCnt; \ + XMLT_WARNING(#_class ":Release, mRefCnt=%d\n", mRefCnt); \ + if (mRefCnt == 0) { \ + NS_DELETEXPCOM(this); \ + return 0; \ + } \ + return mRefCnt; \ +} + +#endif /* _MOZXMLT_H */ diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermFactory.cpp b/mozilla/extensions/xmlterm/base/mozXMLTermFactory.cpp new file mode 100644 index 00000000000..5481c6d7477 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermFactory.cpp @@ -0,0 +1,298 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermFactory.cpp: XPCOM factory for mozIXMLTermShell, mozILineTerm + +#include "nsCOMPtr.h" +#include "nscore.h" +#include "nspr.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsXPComFactory.h" + +#include "mozXMLT.h" +#include "mozLineTerm.h" +#include "mozIXMLTermShell.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); +static NS_DEFINE_CID(kXMLTermShellCID, MOZXMLTERMSHELL_CID); +static NS_DEFINE_CID(kLineTermCID, MOZLINETERM_CID); + +class XMLTermFactory : public nsIFactory +{ +public: + XMLTermFactory(const nsCID &aClass, const char* className, const char* progID); + + // nsISupports methods + NS_DECL_ISUPPORTS + + // nsIFactory methods + NS_IMETHOD CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + +protected: + virtual ~XMLTermFactory(); + +protected: + nsCID mClassID; + const char* mClassName; + const char* mProgID; +}; + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermFactory implementation +///////////////////////////////////////////////////////////////////////// + +// Globals, useful to check if safe to unload module +static PRInt32 gLockCnt = 0; +static PRInt32 gInstanceCnt = 0; + +XMLTermFactory::XMLTermFactory(const nsCID &aClass, + const char* className, + const char* progID): + mClassID(aClass), + mClassName(className), + mProgID(progID) +{ + // Zero reference counter + NS_INIT_REFCNT(); + PR_AtomicIncrement(&gInstanceCnt); +} + + +XMLTermFactory::~XMLTermFactory() +{ + NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction"); + PR_AtomicDecrement(&gInstanceCnt); +} + + +NS_IMETHODIMP +XMLTermFactory::QueryInterface(const nsIID &aIID, void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + // Always NULL result, in case of failure + *aResult = nsnull; + + if (aIID.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsISupports*, this); + + } else if (aIID.Equals(kIFactoryIID)) { + *aResult = NS_STATIC_CAST(nsIFactory*, this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +NS_IMPL_ADDREF(XMLTermFactory); +NS_IMPL_RELEASE(XMLTermFactory); + + +NS_IMETHODIMP +XMLTermFactory::CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) +{ + if (!aResult) + return NS_ERROR_NULL_POINTER; + + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + *aResult = nsnull; + + nsresult rv; + + nsISupports *inst = nsnull; + if (mClassID.Equals(kXMLTermShellCID)) { + if (NS_FAILED(rv = NS_NewXMLTermShell((mozIXMLTermShell**) &inst))) + return rv; + + } else if (mClassID.Equals(kLineTermCID)) { + if (NS_FAILED(rv = NS_NewLineTerm((mozILineTerm**) &inst))) + return rv; + + } else { + return NS_ERROR_NO_INTERFACE; + } + + if (! inst) + return NS_ERROR_OUT_OF_MEMORY; + + if (NS_FAILED(rv = inst->QueryInterface(aIID, aResult))) { + // We didn't get the right interface. + NS_ERROR("didn't support the interface you wanted"); + } + + NS_IF_RELEASE(inst); + return rv; +} + + +NS_IMETHODIMP +XMLTermFactory::LockFactory(PRBool aLock) +{ + if (aLock) { + PR_AtomicIncrement(&gLockCnt); + } else { + PR_AtomicDecrement(&gLockCnt); + } + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////// +// Exported functions for loading, registering, unregistering, and unloading +//////////////////////////////////////////////////////////////////////////// + +// Return approptiate factory to the caller +extern "C" NS_EXPORT nsresult +NSGetFactory(nsISupports* aServMgr, + const nsCID &aClass, + const char *aClassName, + const char *aProgID, + nsIFactory **aFactory) +{ + static PRBool ltermInitialized = false; + static PRBool xmltermInitialized = false; + + if (!ltermInitialized) { + // Initialize all LINETERM operations + // (This initialization needs to be done at factory creation time; + // trying to do it earlier, i.e., at registration time, + // does not work ... something to do with loading of static global + // variables.) + + int messageLevel = 8; + char* debugStr = (char*) PR_GetEnv("LTERM_DEBUG"); + + if (debugStr && (strlen(debugStr) == 1)) { + messageLevel = 98; + debugStr = nsnull; + } + + int result = lterm_init(0); + if (result == 0) { + tlog_set_level(LTERM_TLOG_MODULE, messageLevel, debugStr); + } + ltermInitialized = true; + + char* logStr = (char*) PR_GetEnv("LTERM_LOG"); + if (logStr && (strlen(logStr) > 0)) { + // Enable LineTerm logging + mozLineTerm::mLoggingEnabled = true; + } + } + + if (aClass.Equals(kXMLTermShellCID) && !xmltermInitialized) { + // Set initial debugging message level for XMLterm + int messageLevel = 8; + char* debugStr = (char*) PR_GetEnv("XMLT_DEBUG"); + + if (debugStr && (strlen(debugStr) == 1)) { + messageLevel = 98; + debugStr = nsnull; + } + + tlog_set_level(XMLT_TLOG_MODULE, messageLevel, debugStr); + xmltermInitialized = true; + } + + if (!aFactory) + return NS_ERROR_NULL_POINTER; + + *aFactory = nsnull; + + XMLTermFactory* factory = new XMLTermFactory(aClass, aClassName, + aProgID); + if (factory == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(factory); + *aFactory = factory; + return NS_OK; +} + + +extern "C" NS_EXPORT nsresult +NSRegisterSelf(nsISupports* aServMgr , const char* aPath) +{ + nsresult result; + + nsCOMPtr servMgr(do_QueryInterface(aServMgr, &result)); + if (NS_FAILED(result)) return result; + + NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &result); + if (NS_FAILED(result)) return result; + + printf("Registering lineterm interface\n"); + + result = compMgr->RegisterComponent(kLineTermCID, + "LineTerm Component", + "component://mozilla/xmlterm/lineterm", + aPath, PR_TRUE, PR_TRUE); + + if (NS_FAILED(result)) return result; + + printf("Registering xmlterm shell interface\n"); + + result = compMgr->RegisterComponent(kXMLTermShellCID, + "XMLTerm Shell Component", + "component://mozilla/xmlterm/xmltermshell", + aPath, PR_TRUE, PR_TRUE); + + if (NS_FAILED(result)) return result; + + return NS_OK; +} + + +extern "C" NS_EXPORT nsresult +NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) +{ + nsresult result; + + nsCOMPtr servMgr(do_QueryInterface(aServMgr, &result)); + if (NS_FAILED(result)) return result; + + NS_WITH_SERVICE(nsIComponentManager, compMgr, kComponentManagerCID, &result); + if (NS_FAILED(result)) return result; + + result = compMgr->UnregisterComponent(kLineTermCID, aPath); + if (NS_FAILED(result)) return result; + + result = compMgr->UnregisterComponent(kXMLTermShellCID, aPath); + if (NS_FAILED(result)) return result; + + return NS_OK; +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermListeners.cpp b/mozilla/extensions/xmlterm/base/mozXMLTermListeners.cpp new file mode 100644 index 00000000000..2465330b4a2 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermListeners.cpp @@ -0,0 +1,604 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermListeners.cpp: implementation of classes in mozXMLTermListeners.h + +#include "nsIServiceManager.h" + +#include "mozXMLT.h" +#include "mozXMLTermListeners.h" + +#include "nsIDOMKeyEvent.h" +#include "nsIDOMMouseEvent.h" +#include "nsIDOMNSUIEvent.h" +#include "nsIPrivateTextEvent.h" + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermKeyListener factory +///////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewXMLTermKeyListener(nsIDOMEventListener ** aInstancePtrResult, + mozIXMLTerminal *aXMLTerminal) +{ + mozXMLTermKeyListener* listener = new mozXMLTermKeyListener(); + if (listener == nsnull) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // Save non-owning reference to embedding XMLTerminal object + listener->SetXMLTerminal(aXMLTerminal); + + return listener->QueryInterface(nsIDOMEventListener::GetIID(), + (void **) aInstancePtrResult); +} + +nsresult +NS_NewXMLTermTextListener(nsIDOMEventListener ** aInstancePtrResult, + mozIXMLTerminal *aXMLTerminal) +{ + mozXMLTermTextListener* listener = new mozXMLTermTextListener(); + if (listener == nsnull) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // Save non-owning reference to embedding XMLTerminal object + listener->SetXMLTerminal(aXMLTerminal); + + return listener->QueryInterface(nsIDOMEventListener::GetIID(), + (void **) aInstancePtrResult); +} + +nsresult +NS_NewXMLTermMouseListener(nsIDOMEventListener ** aInstancePtrResult, + mozIXMLTerminal *aXMLTerminal) +{ + mozXMLTermMouseListener* listener = new mozXMLTermMouseListener(); + if (listener == nsnull) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // Save non-owning reference to embedding XMLTerminal object + listener->SetXMLTerminal(aXMLTerminal); + + return listener->QueryInterface(nsIDOMEventListener::GetIID(), + (void **) aInstancePtrResult); +} + +nsresult +NS_NewXMLTermDragListener(nsIDOMEventListener ** aInstancePtrResult, + mozIXMLTerminal *aXMLTerminal) +{ + mozXMLTermDragListener* listener = new mozXMLTermDragListener(); + if (listener == nsnull) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // Save non-owning reference to embedding XMLTerminal object + listener->SetXMLTerminal(aXMLTerminal); + + return listener->QueryInterface(nsIDOMEventListener::GetIID(), + (void **) aInstancePtrResult); +} + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermKeyListener implementation +///////////////////////////////////////////////////////////////////////// + +mozXMLTermKeyListener::mozXMLTermKeyListener() +{ + NS_INIT_REFCNT(); +} + + +mozXMLTermKeyListener::~mozXMLTermKeyListener() +{ +} + + +NS_IMPL_ADDREF(mozXMLTermKeyListener) + +NS_IMPL_RELEASE(mozXMLTermKeyListener) + + +NS_IMETHODIMP +mozXMLTermKeyListener::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if (aIID.Equals(nsCOMTypeInfo::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIDOMKeyListener*,this)); + + } else if (aIID.Equals(nsIDOMEventListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMEventListener*,this); + + } else if (aIID.Equals(nsIDOMKeyListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMKeyListener*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +// Individual key handlers return NS_OK to indicate NOT consumed +// by default, an error is returned indicating event is consumed + +NS_IMETHODIMP +mozXMLTermKeyListener::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +// Process KeyDown events (handles control/alt modified key events) +NS_IMETHODIMP +mozXMLTermKeyListener::KeyDown(nsIDOMEvent* aKeyEvent) +{ + nsresult result; + + nsCOMPtr keyEvent; + keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { + // Non-key event passed to keydown, do not consume it + return NS_OK; + } + + PRBool isShift, ctrlKey, altKey; + PRUint32 keyCode; + + XMLT_LOG(mozXMLTermKeyListener::KeyDown,50,("\n")); + + if (NS_SUCCEEDED(keyEvent->GetKeyCode(&keyCode)) && + NS_SUCCEEDED(keyEvent->GetShiftKey(&isShift)) && + NS_SUCCEEDED(keyEvent->GetCtrlKey(&ctrlKey)) && + NS_SUCCEEDED(keyEvent->GetAltKey(&altKey)) ) { + + XMLT_LOG(mozXMLTermKeyListener::KeyDown,52, + ("keyCode=0x%x, ctrlKey=%d, altKey=%d\n", keyCode, ctrlKey, altKey)); + + PRUint32 keyChar = 0; + + if (!ctrlKey && !altKey) { + // Not control/alt key event + switch (keyCode) { + case nsIDOMKeyEvent::DOM_VK_LEFT: + keyChar = U_CTL_B; + break; + case nsIDOMKeyEvent::DOM_VK_RIGHT: + keyChar = U_CTL_F; + break; + case nsIDOMKeyEvent::DOM_VK_UP: + keyChar = U_CTL_P; + break; + case nsIDOMKeyEvent::DOM_VK_DOWN: + keyChar = U_CTL_N; + break; + case nsIDOMKeyEvent::DOM_VK_TAB: // Consume TAB to avoid scroll problems + keyChar = 0; + break; + default: // ignore event without consuming + return NS_OK; + } + + } else if (ctrlKey == PR_TRUE) { + keyChar = keyCode - 0x40U; // Is this portable? + } + + XMLT_LOG(mozXMLTermKeyListener::KeyDown,52,("keyChar=0x%x\n", keyChar)); + + if ((keyChar > 0) && (keyChar < U_SPACE)) { + // Transmit valid non-null control character + const PRUnichar temUString[] = {keyChar,0}; + nsAutoString keyString(temUString); + result = mXMLTerminal->SendTextAux(keyString); + } + } + + // Consume key down event + return NS_ERROR_BASE; +} + + +NS_IMETHODIMP +mozXMLTermKeyListener::KeyUp(nsIDOMEvent* aKeyEvent) +{ + return NS_OK; +} + + +// Handle KeyPress events (non control/alt modified key events) +NS_IMETHODIMP +mozXMLTermKeyListener::KeyPress(nsIDOMEvent* aKeyEvent) +{ + nsresult result; + + XMLT_LOG(mozXMLTermKeyListener::KeyPress,50,("\n")); + + nsCOMPtr keyEvent; + keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { + // Non-key event passed to keydown, do not consume it + return NS_OK; + } + + PRUint32 keyCode; + PRBool isShift, ctrlKey, altKey; + if (NS_SUCCEEDED(keyEvent->GetKeyCode(&keyCode)) && + NS_SUCCEEDED(keyEvent->GetShiftKey(&isShift)) && + NS_SUCCEEDED(keyEvent->GetCtrlKey(&ctrlKey)) && + NS_SUCCEEDED(keyEvent->GetAltKey(&altKey)) ) { + + PRUint32 keyChar = 0; + result = keyEvent->GetCharCode(&keyChar); + + XMLT_LOG(mozXMLTermKeyListener::KeyPress,52, + ("keyChar=0x%x, ctrlKey=%d, altKey=%d\n", keyChar, ctrlKey, altKey)); + + if (ctrlKey == PR_TRUE) { + // Do nothing for Ctrl-Alt key events; just consume then + + if (altKey == PR_FALSE) { + // Control character, without Alt + + if ((keyChar > 0) && (keyChar < U_SPACE)) { + // Transmit valid non-null control character + const PRUnichar temUString[] = {keyChar,0}; + nsAutoString keyString(temUString); + result = mXMLTerminal->SendTextAux(keyString); + } + } + + } else { + // Unmodified key event (including TAB/BACKSPACE/RETURN/LINEFEED) + + if (keyChar == 0) { + // Key that hasn't been mapped to a character code + switch (keyCode) { + case nsIDOMKeyEvent::DOM_VK_BACK_SPACE: + case nsIDOMKeyEvent::DOM_VK_DELETE: + keyChar = U_BACKSPACE; + break; + case nsIDOMKeyEvent::DOM_VK_TAB: + keyChar = U_TAB; + break; + case nsIDOMKeyEvent::DOM_VK_RETURN: + keyChar = U_LINEFEED; + break; + default: // ignore event without consuming + return NS_OK; + } + } + + // Translate Carriage Return to LineFeed (may not be portable??) + if (keyChar == U_CRETURN) keyChar = U_LINEFEED; + + if ((keyChar > 0) && (keyChar <= 0xFFFDU)) { + // Transmit valid non-null Unicode character + const PRUnichar temUString[] = {keyChar,0}; + nsAutoString keyString(temUString); + result = mXMLTerminal->SendTextAux(keyString); + } + } + } + + // Consume key press event + return NS_ERROR_BASE; +} + + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermTextListener implementation +///////////////////////////////////////////////////////////////////////// + +mozXMLTermTextListener::mozXMLTermTextListener() +{ + NS_INIT_REFCNT(); +} + + +mozXMLTermTextListener::~mozXMLTermTextListener() +{ +} + + +NS_IMPL_ADDREF(mozXMLTermTextListener) + +NS_IMPL_RELEASE(mozXMLTermTextListener) + + +NS_IMETHODIMP +mozXMLTermTextListener::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if (aIID.Equals(nsCOMTypeInfo::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIDOMTextListener*,this)); + + } else if (aIID.Equals(nsIDOMEventListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMEventListener*,this); + + } else if (aIID.Equals(nsIDOMTextListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMTextListener*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermTextListener::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermTextListener::HandleText(nsIDOMEvent* aTextEvent) +{ + nsCOMPtr textEvent (do_QueryInterface(aTextEvent)); + if (!textEvent) { + // Soft failure + return NS_OK; + } + + XMLT_LOG(mozXMLTermTextListener::HandleText,50,("\n")); + + nsAutoString textStr; + textEvent->GetText(textStr); + + // Transmit text to terminal + mXMLTerminal->SendTextAux(textStr); + + return NS_OK; +} + + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermMouseListener implementation +///////////////////////////////////////////////////////////////////////// + +mozXMLTermMouseListener::mozXMLTermMouseListener() +{ + NS_INIT_REFCNT(); +} + + +mozXMLTermMouseListener::~mozXMLTermMouseListener() +{ +} + + +NS_IMPL_ADDREF(mozXMLTermMouseListener) + +NS_IMPL_RELEASE(mozXMLTermMouseListener) + + +NS_IMETHODIMP +mozXMLTermMouseListener::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if (aIID.Equals(nsCOMTypeInfo::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIDOMMouseListener*,this)); + + } else if (aIID.Equals(nsIDOMEventListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMEventListener*,this); + + } else if (aIID.Equals(nsIDOMMouseListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMMouseListener*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::MouseDown(nsIDOMEvent* aMouseEvent) +{ + if (!aMouseEvent) + return NS_OK; + + nsCOMPtr mouseEvent; + mouseEvent = do_QueryInterface(aMouseEvent); + if (!mouseEvent) { + // Non-mouse event passed; do not consume it + return NS_OK; + } + + PRUint16 buttonCode = 0; + mouseEvent->GetButton(&buttonCode); + + XMLT_LOG(mozXMLTermMouseListener::MouseDown,50,("buttonCode=%d\n", + buttonCode)); + + if (buttonCode == 2) { + // Middle-mouse button pressed; initiate paste + mXMLTerminal->Paste(); + } + + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::MouseUp(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::MouseClick(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::MouseDblClick(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::MouseOver(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermMouseListener::MouseOut(nsIDOMEvent* aMouseEvent) +{ + return NS_OK; +} + + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermDragListener implementation +///////////////////////////////////////////////////////////////////////// + +mozXMLTermDragListener::mozXMLTermDragListener() +{ + NS_INIT_REFCNT(); +} + + +mozXMLTermDragListener::~mozXMLTermDragListener() +{ +} + + +NS_IMPL_ADDREF(mozXMLTermDragListener) + +NS_IMPL_RELEASE(mozXMLTermDragListener) + + +NS_IMETHODIMP +mozXMLTermDragListener::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if (aIID.Equals(nsCOMTypeInfo::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(nsIDOMDragListener*,this)); + + } else if (aIID.Equals(nsIDOMEventListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMEventListener*,this); + + } else if (aIID.Equals(nsIDOMDragListener::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDOMDragListener*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermDragListener::HandleEvent(nsIDOMEvent* aEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermDragListener::DragEnter(nsIDOMEvent* aDragEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermDragListener::DragOver(nsIDOMEvent* aDragEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermDragListener::DragExit(nsIDOMEvent* aDragEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermDragListener::DragDrop(nsIDOMEvent* aDragEvent) +{ + return NS_OK; +} + + +NS_IMETHODIMP +mozXMLTermDragListener::DragGesture(nsIDOMEvent* aDragEvent) +{ + return NS_OK; +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermListeners.h b/mozilla/extensions/xmlterm/base/mozXMLTermListeners.h new file mode 100644 index 00000000000..4a39707d22b --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermListeners.h @@ -0,0 +1,172 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermListeners.h: classes for key/text/mouse/drag event listeners +// used by mozXMLTerminal: +// mozXMLTermKeyListener +// mozXMLTermTextListener +// mozXMLTermMouseListener +// mozXMLTermDragListener + + +#ifndef mozXMLTermListeners_h__ +#define mozXMLTermListeners_h__ + +#include "nsIDOMEvent.h" +#include "nsIDOMKeyListener.h" +#include "nsIDOMTextListener.h" +#include "nsIDOMMouseListener.h" +#include "nsIDOMDragListener.h" +#include "nsCOMPtr.h" + +#include "mozIXMLTerminal.h" + +/* XMLTerm Key Listener */ +class mozXMLTermKeyListener : public nsIDOMKeyListener { +public: + mozXMLTermKeyListener(); + virtual ~mozXMLTermKeyListener(); + + /** Save non-owning reference to containing XMLTerminal object + * @param aXMLTerminal the XMLTerm instance + */ + void SetXMLTerminal(mozIXMLTerminal *aXMLTerminal) + {mXMLTerminal = aXMLTerminal;} + + // Interfaces for addref and release and queryinterface + NS_DECL_ISUPPORTS + + // nsIDOMEventListener interface + virtual nsresult HandleEvent(nsIDOMEvent* aEvent); + + // nsIDOMKeyListener interface + virtual nsresult KeyDown(nsIDOMEvent* aKeyEvent); + virtual nsresult KeyUp(nsIDOMEvent* aKeyEvent); + virtual nsresult KeyPress(nsIDOMEvent* aKeyEvent); + +protected: + /** non-owning reference to containing XMLTerminal object (for callback) */ + mozIXMLTerminal* mXMLTerminal; +}; + + +/* XMLTerm Text Listener */ +class mozXMLTermTextListener : public nsIDOMTextListener { +public: + mozXMLTermTextListener(); + virtual ~mozXMLTermTextListener(); + + /** Save non-owning reference to containing XMLTerminal object + * @param aXMLTerminal the XMLTerm instance + */ + void SetXMLTerminal(mozIXMLTerminal *aXMLTerminal) + {mXMLTerminal = aXMLTerminal;} + + // Interfaces for addref and release and queryinterface + NS_DECL_ISUPPORTS + + // nsIDOMEventListener interface + virtual nsresult HandleEvent(nsIDOMEvent* aEvent); + + // nsIDOMTextListener interface + virtual nsresult HandleText(nsIDOMEvent* aTextEvent); + +protected: + /** non-owning reference to containing XMLTerminal object (for callback) */ + mozIXMLTerminal* mXMLTerminal; +}; + + +/* XMLTerm Mouse Listener */ +class mozXMLTermMouseListener : public nsIDOMMouseListener { +public: + mozXMLTermMouseListener(); + virtual ~mozXMLTermMouseListener(); + + /** Save non-owning reference to containing XMLTerminal object + * @param aXMLTerminal the XMLTerm instance + */ + void SetXMLTerminal(mozIXMLTerminal *aXMLTerminal) + {mXMLTerminal = aXMLTerminal;} + + // Interfaces for addref and release and queryinterface + NS_DECL_ISUPPORTS + + // nsIDOMEventListener interface + virtual nsresult HandleEvent(nsIDOMEvent* aEvent); + + // nsIDOMMouseListener interface + virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); + virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent); + virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent); + virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent); + virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent); + virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent); + +protected: + /** non-owning reference to containing XMLTerminal object (for callback) */ + mozIXMLTerminal* mXMLTerminal; +}; + + +/* XMLTerm Drag Listener */ +class mozXMLTermDragListener : public nsIDOMDragListener { +public: + mozXMLTermDragListener(); + virtual ~mozXMLTermDragListener(); + + /** Save non-owning reference to containing XMLTerminal object + * @param aXMLTerminal the XMLTerm instance + */ + void SetXMLTerminal(mozIXMLTerminal *aXMLTerminal) + {mXMLTerminal = aXMLTerminal;} + + // Interfaces for addref and release and queryinterface + NS_DECL_ISUPPORTS + + // nsIDOMEventListener interface + virtual nsresult HandleEvent(nsIDOMEvent* aEvent); + + // nsIDOMDragListener interface + virtual nsresult DragEnter(nsIDOMEvent* aDragEvent); + virtual nsresult DragOver(nsIDOMEvent* aDragEvent); + virtual nsresult DragExit(nsIDOMEvent* aDragEvent); + virtual nsresult DragDrop(nsIDOMEvent* aDragEvent); + virtual nsresult DragGesture(nsIDOMEvent* aDragEvent); + +protected: + /** non-owning reference to containing XMLTerminal object (for callback) */ + mozIXMLTerminal* mXMLTerminal; +}; + + +// Factory for XMLTermKeyListener +extern nsresult NS_NewXMLTermKeyListener(nsIDOMEventListener** aInstancePtrResult, mozIXMLTerminal *aXMLTerminal); + +// Factory for XMLTermTextListener +extern nsresult NS_NewXMLTermTextListener(nsIDOMEventListener** aInstancePtrResult, mozIXMLTerminal *aXMLTerminal); + +// Factory for XMLTermMouseListener +extern nsresult NS_NewXMLTermMouseListener(nsIDOMEventListener** aInstancePtrResult, mozIXMLTerminal *aXMLTerminal); + +// Factory for XMLTermDragListener +extern nsresult NS_NewXMLTermDragListener(nsIDOMEventListener** aInstancePtrResult, mozIXMLTerminal *aXMLTerminal); + +#endif //mozXMLTermListeners_h__ diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermSession.cpp b/mozilla/extensions/xmlterm/base/mozXMLTermSession.cpp new file mode 100644 index 00000000000..43d62966154 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermSession.cpp @@ -0,0 +1,2515 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermSession.cpp: implementation of mozXMLTermSession class + +#include "nscore.h" +#include "prlog.h" + +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "nsIAllocator.h" + +#include "nsIDocumentViewer.h" + +#include "nsICaret.h" +#include "nsITextContent.h" + +#include "nsIDOMElement.h" +#include "nsIDOMSelection.h" +#include "nsIDOMText.h" +#include "nsIDOMAttr.h" +#include "nsIDOMNamedNodeMap.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMRange.h" +#include "nsIDOMCharacterData.h" + +#include "nsIDOMHTMLDocument.h" +#include "nsIDOMDocumentFragment.h" +#include "nsIDOMNSRange.h" + +#include "nsIHTMLContent.h" + +#include "mozXMLT.h" +#include "mozILineTermAux.h" +#include "mozIXMLTerminal.h" +#include "mozXMLTermSession.h" + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermSession definition +///////////////////////////////////////////////////////////////////////// +const char* const mozXMLTermSession::sessionElementNames[] = { + "session", + "entry", + "input", + "output", + "prompt", + "command", + "stdin", + "stdout", + "stderr" +}; + +const char* const mozXMLTermSession::sessionEventNames[] = { + "click", + "dblclick" +}; + +const char* const mozXMLTermSession::metaCommandNames[] = { + "", + "", + "http", + "ls", + "tree" +}; + +const char* const mozXMLTermSession::fileTypeNames[] = { + "plainfile", + "directory", + "executable" +}; + +const char* const mozXMLTermSession::treeActionNames[] = { + "^", + "v", + "<", + ">", + "A", + "H" +}; + +mozXMLTermSession::mozXMLTermSession() : + mInitialized(PR_FALSE), + mXMLTerminal(nsnull), + mPresShell(nsnull), + mDOMDocument(nsnull), + + mBodyNode(nsnull), + mSessionNode(nsnull), + mCurrentDebugNode(nsnull), + + mStartEntryNode(nsnull), + mCurrentEntryNode(nsnull), + + mMaxHistory(50), + mStartEntryNumber(0), + mCurrentEntryNumber(0), + + mEntryHasOutput(false), + + mPromptSpanNode(nsnull), + mCommandSpanNode(nsnull), + mInputTextNode(nsnull), + + mOutputBlockNode(nsnull), + mOutputDisplayNode(nsnull), + mOutputTextNode(nsnull), + + mMetaCommandType(NO_META_COMMAND), + + mOutputDisplayType(NO_NODE), + mOutputMarkupType(PLAIN_TEXT), + + mAutoDetect(FIRST_LINE), + + mLineBreakNeeded(false), + mFirstOutputLine(false), + + mPreTextIncomplete(""), + mPreTextBuffered(""), + mPreTextDisplayed(""), + + mPromptHTML(""), + mFragmentBuffer("") + +{ +} + + +mozXMLTermSession::~mozXMLTermSession() +{ + if (mInitialized) { + Finalize(); + } +} + + +// Initialize XMLTermSession +NS_IMETHODIMP mozXMLTermSession::Init(mozIXMLTerminal* aXMLTerminal, + nsIPresShell* aPresShell, + nsIDOMDocument* aDOMDocument) +{ + XMLT_LOG(mozXMLTermSession::Init,30,("\n")); + + if (mInitialized) + return NS_ERROR_ALREADY_INITIALIZED; + + if (!aXMLTerminal || !aPresShell || !aDOMDocument) + return NS_ERROR_NULL_POINTER; + + mXMLTerminal = aXMLTerminal; // containing XMLTerminal; no addref + mPresShell = aPresShell; // presentation shell; no addref + mDOMDocument = aDOMDocument; // DOM document; no addref + + nsresult result = NS_OK; + + // Show the caret + nsCOMPtr caret; + if (NS_SUCCEEDED(mPresShell->GetCaret(getter_AddRefs(caret)))) { + caret->SetCaretVisible(PR_TRUE); + caret->SetCaretReadOnly(PR_FALSE); + } + + mPresShell->SetCaretEnabled(PR_TRUE); + + nsCOMPtr vDOMHTMLDocument + (do_QueryInterface(mDOMDocument)); + if (!vDOMHTMLDocument) + return NS_ERROR_FAILURE; + + // Locate document body node + nsCOMPtr nodeList; + nsAutoString bodyTag = "body"; + result = vDOMHTMLDocument->GetElementsByTagName(bodyTag, + getter_AddRefs(nodeList)); + if (NS_FAILED(result) || !nodeList) + return NS_ERROR_FAILURE; + + PRUint32 count; + nodeList->GetLength(&count); + PR_ASSERT(count==1); + + result = nodeList->Item(0, getter_AddRefs(mBodyNode)); + if (NS_FAILED(result) || !mBodyNode) + return NS_ERROR_FAILURE; + + // Use body node as session node by default + mSessionNode = mBodyNode; + + nsCOMPtr sessionElement; + nsAutoString sessionID = sessionElementNames[SESSION_ELEMENT]; + result = vDOMHTMLDocument->GetElementById(sessionID, + getter_AddRefs(sessionElement)); + + if (NS_SUCCEEDED(result) && sessionElement) { + // Specific session node + mSessionNode = do_QueryInterface(sessionElement); + } + + mCurrentDebugNode = mSessionNode; + + // Create preface element to display initial output + result = NewPreface(); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + +#if 0 + nsAutoString prefaceText ("Preface"); + nsAutoString nullStyle (""); + result = AppendOutput(prefaceText, nullStyle, true); +#endif + + mInitialized = PR_TRUE; + + XMLT_LOG(mozXMLTermSession::Init,31,("exiting\n")); + return result; +} + + +// De-initialize XMLTermSession +NS_IMETHODIMP mozXMLTermSession::Finalize(void) +{ + + mOutputBlockNode = nsnull; + mOutputDisplayNode = nsnull; + mOutputTextNode = nsnull; + + mPromptSpanNode = nsnull; + mCommandSpanNode = nsnull; + mInputTextNode = nsnull; + + mStartEntryNode = nsnull; + mCurrentEntryNode = nsnull; + + mBodyNode = nsnull; + mSessionNode = nsnull; + mCurrentDebugNode = nsnull; + + mXMLTerminal = nsnull; + mPresShell = nsnull; + mDOMDocument = nsnull; + + mInitialized = PR_FALSE; + + return NS_OK; +} + + +/** Preprocesses user input before it is transmitted to LineTerm + * @param aString (inout) input data to be preprocessed + * @param consumed (output) true if input data has been consumed + */ +NS_IMETHODIMP mozXMLTermSession::Preprocess(const nsString& aString, + PRBool& consumed) +{ + + consumed = false; + + if (mMetaCommandType == TREE_META_COMMAND) { + if (aString.Length() == 1) { + // Navigate the DOM tree from keyboard + PRUnichar uch = aString.CharAt(0); + + XMLT_LOG(mozXMLTermSession::Preprocess,60,("char=0x%x\n", uch)); + + consumed = true; + switch (uch) { + case U_CTL_B: + TraverseDOMTree(stderr, mBodyNode, mCurrentDebugNode, + TREE_MOVE_LEFT); + break; + + case U_CTL_F: + TraverseDOMTree(stderr, mBodyNode, mCurrentDebugNode, + TREE_MOVE_RIGHT); + break; + + case U_CTL_N: + TraverseDOMTree(stderr, mBodyNode, mCurrentDebugNode, + TREE_MOVE_DOWN); + break; + + case U_CTL_P: + TraverseDOMTree(stderr, mBodyNode, mCurrentDebugNode, + TREE_MOVE_UP); + break; + + case U_A_CHAR: + case U_a_CHAR: + TraverseDOMTree(stderr, mBodyNode, mCurrentDebugNode, + TREE_PRINT_ATTS); + break; + + case U_H_CHAR: + case U_h_CHAR: + TraverseDOMTree(stderr, mBodyNode, mCurrentDebugNode, + TREE_PRINT_HTML); + break; + + case U_Q_CHAR: + case U_q_CHAR: + case U_CTL_C: + // End of keyboard command sequence; reset debug node to session node + mCurrentDebugNode = mSessionNode; + mMetaCommandType = NO_META_COMMAND; + break; + + default: + break; + } + } + } + + return NS_OK; +} + + +/** Reads all available data from LineTerm and displays it; + * returns when no more data is available. + * @param lineTermAux LineTermAux object to read data from + */ +NS_IMETHODIMP mozXMLTermSession::ReadAll(mozILineTermAux* lineTermAux) +{ + PRInt32 opcodes, buf_row, buf_col; + PRUnichar *buf_str, *buf_style; + PRBool newline, streamData, promptLine, inputLine, metaCommand; + nsAutoString bufString, bufStyle; + + XMLT_LOG(mozXMLTermSession::ReadAll,60,("\n")); + + if (lineTermAux == nsnull) + return NS_ERROR_FAILURE; + + nsresult result = NS_OK; + PRBool flushOutput = false; + + PRBool metaNextCommand = false; + for (;;) { + // NOTE: Remember to de-allocate buf_str and buf_style + // using nsAllocator::Free, if opcodes != 0 + result = lineTermAux->ReadAux(&opcodes, &buf_row, &buf_col, &buf_str, + &buf_style); + if (NS_FAILED(result)) + break; + + XMLT_LOG(mozXMLTermSession::ReadAll,62, + ("opcodes=0x%x, mMetaCommandType=%d, mEntryHasOutput=%d\n", + opcodes, mMetaCommandType, mEntryHasOutput)); + + if (opcodes == 0) break; + + streamData = (opcodes & LTERM_STREAMDATA_CODE); + newline = (opcodes & LTERM_NEWLINE_CODE); + + // Copy character/style strings + bufString = buf_str; + bufStyle = buf_style; + + // De-allocate buf_str, buf_style using nsAllocator::Free + nsAllocator::Free(buf_str); + nsAllocator::Free(buf_style); + + if (streamData) { + // Process stream data + if (mMetaCommandType == NO_META_COMMAND) { + mMetaCommandType = STREAM_META_COMMAND; + + // Disable input echo + lineTermAux->SetEchoFlag(false); + + // Determine stream markup type + OutputMarkupType streamMarkupType = HTML_FRAGMENT; + + if (opcodes & LTERM_DOCSTREAM_CODE) { + if (opcodes & LTERM_XMLSTREAM_CODE) { + streamMarkupType = XML_DOCUMENT; + } else { + streamMarkupType = HTML_DOCUMENT; + } + } + + // Initialize stream output + nsAutoString streamURL = ""; + result = InitStream(streamURL, streamMarkupType); + if (NS_FAILED(result)) + return result; + } + + // Process stream output + bufStyle = ""; + result = ProcessOutput(bufString, bufStyle, true, true); + if (NS_FAILED(result)) + return result; + + if (newline) { + if (!mEntryHasOutput) { + // Start of command output + mEntryHasOutput = true; + } + + // Break stream output display + result = BreakOutput(); + if (NS_FAILED(result)) + return result; + + mMetaCommandType = NO_META_COMMAND; + flushOutput = true; + + // Enable input echo + lineTermAux->SetEchoFlag(false); + } + + } else { + // Process non-stream data + flushOutput = true; + + inputLine = (opcodes & LTERM_INPUT_CODE); + promptLine = (opcodes & LTERM_PROMPT_CODE); + metaCommand = (opcodes & LTERM_META_CODE); + + nsAutoString promptStr (""); + PRInt32 promptLength = 0; + + if (promptLine) { + // Process prompt + const PRUnichar *styleVals = bufStyle.GetUnicode(); + const PRInt32 bufLength = bufStyle.Length(); + + for (promptLength=0; promptLength 0); + + // Extract prompt string + bufString.Left(promptStr, promptLength); + + // Remove prompt chars/style from buffer strings + bufString.Cut(0, promptLength); + bufStyle.Cut(0, promptLength); + } + + if (!metaCommand && inputLine) { + if (metaNextCommand) { + // Echo of transmitted meta command + metaNextCommand = false; + } else { + // No meta command; enable input echo + mMetaCommandType = NO_META_COMMAND; + lineTermAux->SetEchoFlag(true); + } + } + + if (metaCommand) { + // Identify meta command type + + // Eliminate leading spaces/TABs + nsAutoString metaLine = bufString; + metaLine.Trim(" \t", PR_TRUE, PR_FALSE); + + int delimOffset = metaLine.FindChar((PRUnichar) ':'); + PR_ASSERT(delimOffset >= 0); + + XMLT_LOG(mozXMLTermSession::ReadAll,62, ("delimOffset=%d\n", delimOffset)); + + if (delimOffset == 0) { + // Default to HTTP protocol + mMetaCommandType = HTTP_META_COMMAND; + + } else { + // Identify meta command type + mMetaCommandType = NO_META_COMMAND; + + nsAutoString temString; + metaLine.Left(temString, delimOffset); + + PRInt32 j; + for (j=NO_META_COMMAND+1; jSetEchoFlag(false); + nsAutoString lsCommand (""); + + if (commandArgs.Length() > 0) { + lsCommand += "cd "; + lsCommand += commandArgs; + lsCommand += ";"; + } + + lsCommand += "ls -dF `pwd`/*\n"; + + //mXMLTerminal->SendText(lsCommand); + + /* Set flag to recognize transmitted command */ + metaNextCommand = true; + } + break; + + case TREE_META_COMMAND: + XMLT_WARNING("\nTraverseDOMTree: use arrow keys; A for attributes; H for HTML; Q to quit\n"); + + default: + break; + } + } + } + + if (!promptLine) { + // Not prompt line + if (!mEntryHasOutput) { + // Start of command output + mEntryHasOutput = true; + mFirstOutputLine = true; + } + + if (newline) { + // Complete line; check for markup + result = AutoDetectMarkup(bufString, bufStyle, mFirstOutputLine); + if (NS_FAILED(result)) + return result; + + // Not first output line anymore + mFirstOutputLine = false; + } + + // Display output + result = ProcessOutput(bufString, bufStyle, newline, false); + if (NS_FAILED(result)) + return result; + + } else { + // Prompt line + if (mEntryHasOutput) { + // Break previous output display + result = BreakOutput(); + + // Create new entry block + result = NewEntry(promptStr); + if (NS_FAILED(result)) + return result; + } + + // Display input and position cursor + PRInt32 cursorCol = 0; + result = lineTermAux->GetCursorColumn(&cursorCol); + + // Remove prompt offset + cursorCol -= promptLength; + if (cursorCol < 0) cursorCol = 0; + + XMLT_LOG(mozXMLTermSession::ReadAll,62,("cursorCol=%d\n", cursorCol)); + + result = DisplayInput(bufString, bufStyle, cursorCol); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + if (newline) { + // Start of command output + // (this is needed to properly handle commands with no output!) + mEntryHasOutput = true; + mFirstOutputLine = true; + } + } + } + } + + XMLT_LOG(mozXMLTermSession::ReadAll,62,(" result=%d\n", result)); + + if (NS_FAILED(result)) { + // Close LineTerm + lineTermAux->CloseAux(); + return NS_ERROR_FAILURE; + } + + if (flushOutput) { + // Flush output, splitting off incomplete line + result = FlushOutput(SPLIT_INCOMPLETE_FLUSH); + + // printf("mozXMLTermSession::ReadAll (flush)\n"); + result = mPresShell->ScrollSelectionIntoView(SELECTION_NORMAL, + SELECTION_FOCUS_REGION); + + // Scroll frame (ignore result) + // result = ScrollBottomLeft(); + } + + return NS_OK; +} + + +/** Displays ("echoes") input text string with style and positions cursor + * @param aString string to be displayed + * @param aStyle style values for string (see lineterm.h) + * @param cursorCol cursor column + */ +NS_IMETHODIMP mozXMLTermSession::DisplayInput(const nsString& aString, + const nsString& aStyle, + PRInt32 cursorCol) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::DisplayInput,70,("cursorCol=%d\n", cursorCol)); + + result = SetDOMText(mInputTextNode, aString); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + char* temCString = aString.ToNewCString(); + XMLT_LOG(mozXMLTermSession::DisplayInput,72, + ("aString=%s\n", temCString)); + nsCRT::free(temCString); + + // Collapse selection and position cursor + nsCOMPtr selection; + + result = mPresShell->GetSelection(SELECTION_NORMAL, + getter_AddRefs(selection)); + if (NS_FAILED(result) || !selection) + return NS_ERROR_FAILURE; + + if ((cursorCol > 0) || (mPromptHTML.Length() > 0)) { + result = selection->Collapse(mInputTextNode, cursorCol); + + } else { + // WORKAROUND for cursor positioning at end of prompt + nsCOMPtr promptTextNode; + result = mPromptSpanNode->GetFirstChild(getter_AddRefs(promptTextNode)); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr domText (do_QueryInterface(promptTextNode)); + + if (domText) { + PRUint32 promptLength; + result = domText->GetLength(&promptLength); + if (NS_SUCCEEDED(result)) { + XMLT_LOG(mozXMLTermSession::DisplayInput,72, + ("promptLength=%d\n", promptLength)); + result = selection->Collapse(promptTextNode, promptLength); + } + } + } + } + + NS_ASSERTION((NS_SUCCEEDED(result)), + "selection could not be collapsed after insert."); + + return NS_OK; +} + + +/** Autodetects markup in current output line + * @param firstOutputLine true if this is the first output line + */ +NS_IMETHODIMP mozXMLTermSession::AutoDetectMarkup(const nsString& aString, + const nsString& aStyle, + PRBool firstOutputLine) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::AutoDetectMarkup,70,("\n")); + + // If autodetect disabled or not plain text, do nothing + if ((mAutoDetect == NO_MARKUP) || + ((mAutoDetect == FIRST_LINE) && !firstOutputLine) || + (mOutputMarkupType != PLAIN_TEXT)) + return NS_OK; + + OutputMarkupType newMarkupType = PLAIN_TEXT; + + if (newMarkupType != PLAIN_TEXT) { + // Markup found; initialize stream + nsAutoString streamURL = ""; + result = InitStream(streamURL, newMarkupType); + if (NS_FAILED(result)) + return result; + + } else { + // No markup found; assume rest of output is plain text + mOutputMarkupType = PLAIN_TEXT; + } + + return NS_OK; +} + + +/** Initializes display of stream output with specified markup type + * @param streamURL effective URL of stream output + * @param streamMarkupType stream markup stype + */ +NS_IMETHODIMP mozXMLTermSession::InitStream(const nsString& streamURL, + OutputMarkupType streamMarkupType) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::InitStream,70,("streamMarkupType=%d\n", + streamMarkupType)); + + // Break previous output display + result = BreakOutput(); + if (NS_FAILED(result)) + return result; + + // Initialize markup handling + switch (mOutputMarkupType) { + + case HTML_FRAGMENT: + // Initialize fragment buffer + mFragmentBuffer = ""; + break; + + default: + PR_ASSERT(0); + break; + } + + mOutputMarkupType = streamMarkupType; + + return NS_OK; +} + + +/** Breaks output display by flushing and deleting incomplete lines */ +NS_IMETHODIMP mozXMLTermSession::BreakOutput(void) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::BreakOutput,70,("mOutputMarkupType=%d\n", + mOutputMarkupType)); + + switch (mOutputMarkupType) { + + case HTML_FRAGMENT: + // Display HTML fragment + result = InsertFragment(mFragmentBuffer, mOutputBlockNode, + mCurrentEntryNumber); + if (NS_FAILED(result)) + return result; + + mFragmentBuffer = ""; + break; + + case HTML_DOCUMENT: + // Close HTML document + break; + + default: + // Flush plain text output, clearing any incomplete input line + result = FlushOutput(CLEAR_INCOMPLETE_FLUSH); + if (NS_FAILED(result)) + return result; + + mPreTextBuffered = ""; + mPreTextDisplayed = ""; + mOutputDisplayNode = nsnull; + mOutputDisplayType = NO_NODE; + mOutputTextNode = nsnull; + break; + } + + // Revert to plain text type + mOutputMarkupType = PLAIN_TEXT; + + return NS_OK; +} + + +/** Processes output string with specified style + * @param aString string to be processed + * @param aStyle style values for string (see lineterm.h) + * (if it is a null string, STDOUT style is assumed) + * @param newline true if this is a complete line of output + * @param streamOutput true if string represents stream output + */ +NS_IMETHODIMP mozXMLTermSession::ProcessOutput(const nsString& aString, + const nsString& aStyle, + PRBool newline, + PRBool streamOutput) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::ProcessOutput,70, + ("newline=%d, streamOutput=%d\n", newline, streamOutput)); + + if ((mMetaCommandType == LS_META_COMMAND) && newline) { + // Display hypertext directory listing + result = AppendLineLS(aString, aStyle); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + return NS_OK; + + } else { + // Not meta command + + switch (mOutputMarkupType) { + + case HTML_FRAGMENT: + // Append complete lines to HTML fragment buffer + if (newline || streamOutput) { + mFragmentBuffer += aString; + if (!streamOutput) + mFragmentBuffer += '\n'; + } + + break; + + case HTML_DOCUMENT: + // Write complete lines to document stream + if (newline || streamOutput) { + // ********** streamWrite(aString.GetUnicode()); + if (!streamOutput) { + static const PRUnichar lineFeed[] = {U_LINEFEED, U_NUL}; + // ************ streamWrite(lineFeed); + } + } + break; + + default: + // Display plain text output, complete or incomplete lines + PR_ASSERT(!streamOutput); + result = AppendOutput(aString, aStyle, newline); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + break; + } + + return NS_OK; + } +} + + +/** Appends text string to output buffer + * (appended text may need to be flushed for it to be actually displayed) + * @param aString string to be processed + * @param aStyle style values for string (see lineterm.h) + * (if it is a null string, STDOUT style is assumed) + * @param newline true if this is a complete line of output + */ +NS_IMETHODIMP mozXMLTermSession::AppendOutput(const nsString& aString, + const nsString& aStyle, + PRBool newline) +{ + nsresult result; + + const PRInt32 strLength = aString.Length(); + const PRInt32 styleLength = aStyle.Length(); + const PRUnichar *strStyle = aStyle.GetUnicode(); + + XMLT_LOG(mozXMLTermSession::AppendOutput,70,("\n")); + + // Check if line has uniform style + PRUnichar allStyles = LTERM_STDOUT_STYLE; + PRUnichar uniformStyle = LTERM_STDOUT_STYLE; + + if (styleLength > 0) { + PRInt32 j; + allStyles = strStyle[0]; + uniformStyle = strStyle[0]; + + for (j=1; j preNode, textNode; + nsAutoString tagName = "pre"; + + result = NewElementWithText(tagName, elementName, -1, + mOutputBlockNode, preNode, textNode); + + if (NS_FAILED(result) || !preNode || !textNode) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozXMLTermSession::AppendOutput,72, + ("Creating new PRE node\n")); + + // Append node + nsCOMPtr resultNode; + result = mOutputBlockNode->AppendChild(preNode, + getter_AddRefs(resultNode)); + + mOutputDisplayType = preDisplayType; + mOutputDisplayNode = preNode; + mOutputTextNode = textNode; + + // Display incomplete line + result = SetDOMText(mOutputTextNode, aString); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + // Initialize PRE text string buffers + mPreTextDisplayed = aString; + mPreTextBuffered = ""; + } + + // Save incomplete line + mPreTextIncomplete = aString; + + if (newline) { + // Complete line; append to buffer + if (mPreTextBuffered.Length() > 0) { + mPreTextBuffered += '\n'; + } + mPreTextBuffered += mPreTextIncomplete; + mPreTextIncomplete = ""; + } + + mLineBreakNeeded = false; + + XMLT_LOG(mozXMLTermSession::AppendOutput,72, + ("mPreTextDisplayed.Length()=%d, mPreTextBuffered.Length()=%d\n", + mPreTextDisplayed.Length(), mPreTextBuffered.Length())); + + } else { + // Create uniform style SPAN display node + OutputDisplayType spanDisplayType; + nsAutoString elementName = ""; + + if (uniformStyle == LTERM_STDERR_STYLE) { + // STDERR style + spanDisplayType = SPAN_STDERR_NODE; + elementName = sessionElementNames[STDERR_ELEMENT]; + XMLT_LOG(mozXMLTermSession::AppendOutput,72,("SPAN_STDERR_NODE\n")); + + } else { + // STDOUT style (the default output style) + spanDisplayType = SPAN_STDOUT_NODE; + elementName = sessionElementNames[STDOUT_ELEMENT]; + XMLT_LOG(mozXMLTermSession::AppendOutput,72,("SPAN_STDOUT_NODE\n")); + } + + PRBool preDisplay = (mOutputDisplayType == PRE_STDOUT_NODE) || + (mOutputDisplayType == PRE_STDERR_NODE); + + if (preDisplay) { + // Flush buffer, clearing incomplete line + result = FlushOutput(CLEAR_INCOMPLETE_FLUSH); + } + + if (mLineBreakNeeded) { + // Insert line break element + result = NewBreak(mOutputBlockNode); + mLineBreakNeeded = false; + } + + if (elementName.Length() > 0) { + // Create new SPAN node + nsCOMPtr spanNode, textNode; + nsAutoString tagName = "span"; + result = NewElementWithText(tagName, elementName, -1, + mOutputBlockNode, spanNode, textNode); + + if (NS_FAILED(result) || !spanNode || !textNode) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozXMLTermSession::AppendOutput,72, + ("Creating new SPAN node\n")); + + if (mOutputDisplayNode != nsnull) { + // Replace node + nsCOMPtr resultNode; + result = mOutputBlockNode->ReplaceChild(spanNode, mOutputDisplayNode, + getter_AddRefs(resultNode)); + } else { + // Append node + nsCOMPtr resultNode; + result = mOutputBlockNode->AppendChild(spanNode, + getter_AddRefs(resultNode)); + } + + mOutputDisplayType = spanDisplayType; + mOutputDisplayNode = spanNode; + mOutputTextNode = textNode; + } + + // Display line + result = SetDOMText(mOutputTextNode, aString); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + if (newline) { + mOutputDisplayType = NO_NODE; + mOutputDisplayNode = nsnull; + mOutputTextNode = nsnull; + + mLineBreakNeeded = true; + } + } + + return NS_OK; +} + + +/** Adds markup to LS output (TEMPORARY) + * @param aString string to be processed + * @param aStyle style values for string (see lineterm.h) + * (if it is a null string, STDOUT style is assumed) + */ +NS_IMETHODIMP mozXMLTermSession::AppendLineLS(const nsString& aString, + const nsString& aStyle) +{ + nsresult result; + + const PRInt32 strLength = aString.Length(); + const PRInt32 styleLength = aStyle.Length(); + const PRUnichar *strStyle = aStyle.GetUnicode(); + + // Check if line has uniform style + PRUnichar allStyles = LTERM_STDOUT_STYLE; + PRUnichar uniformStyle = LTERM_STDOUT_STYLE; + + if (styleLength > 0) { + PRInt32 j; + allStyles = strStyle[0]; + uniformStyle = strStyle[0]; + + for (j=1; j= lineLength) break; + + // Locate end of word (non-space character) + PRInt32 wordEnd = aString.FindCharInSet(" \t", wordBegin); + if (wordEnd < 0) { + wordEnd = lineLength-1; + } else { + wordEnd--; + } + + PR_ASSERT(wordEnd >= wordBegin); + + // Locate pure filename, with possible type suffix + PRInt32 nameBegin; + if (wordEnd > wordBegin) { + nameBegin = aString.RFindChar(U_SLASH, PR_FALSE, wordEnd-1); + if (nameBegin >= wordBegin) { + nameBegin++; + } else { + nameBegin = wordBegin; + } + } else { + nameBegin = wordBegin; + } + + nsAutoString filename; + aString.Mid(filename, nameBegin, wordEnd-nameBegin+1); + + FileType fileType = PLAIN_FILE; + PRUint32 dropSuffix = 0; + + if (wordEnd > wordBegin) { + // Determine file type from suffix character + switch (aString[wordEnd]) { + case U_SLASH: + fileType = DIRECTORY_FILE; + break; + case U_STAR: + fileType = EXECUTABLE_FILE; + break; + default: + break; + } + + // Discard any type suffix + if (fileType != PLAIN_FILE) + dropSuffix = 1; + } + + // Extract full pathname (minus any type suffix) + nsAutoString pathname; + aString.Mid(pathname, wordBegin, wordEnd-wordBegin+1-dropSuffix); + + // Append to markup string + markupString += " newText; + nsAutoString newlineStr ("\n"); + result = mDOMDocument->CreateTextNode(newlineStr, getter_AddRefs(newText)); + if (NS_FAILED(result) || !newText) + return NS_ERROR_FAILURE; + + nsCOMPtr newTextNode = do_QueryInterface(newText); + nsCOMPtr resultNode; + result = mOutputDisplayNode->InsertBefore(newTextNode, mOutputTextNode, + getter_AddRefs(resultNode)); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozXMLTermSession::AppendLineLS,61,("exiting\n")); + +#if 0 + mCurrentDebugNode = mOutputDisplayNode; + mMetaCommandType = TREE_META_COMMAND; + XMLT_LOG(mozXMLTermSession::AppendLineLS,0,("tree:\n")); +#endif /* 0 */ + + return NS_OK; +} + + +/** Inserts HTML fragment string as child of parentNode, before specified + * child node, or after the last child node + * @param aString HTML fragment string to be inserted + * @param parentNode parent node for HTML fragment + * @param entryNumber entry number (default value = -1) + * (if entryNumber >= 0, all '#' characters in aString + * are substituted by entryNumber) + * @param beforeNode child node before which to insert fragment; + * if null, insert after last child node + * (default value is null) + * @param replace if true, replace beforeNode with inserted fragment + * (default value is false) + */ +NS_IMETHODIMP mozXMLTermSession::InsertFragment(const nsString& aString, + nsCOMPtr& parentNode, + PRInt32 entryNumber, + nsIDOMNode* beforeNode, + PRBool replace) +{ + nsresult result; + + char* temCString = aString.ToNewCString(); + XMLT_LOG(mozXMLTermSession::InsertFragment,70,("aString=%s\n", temCString)); + nsCRT::free(temCString); + + // Get selection + nsCOMPtr selection; + + result = mPresShell->GetSelection(SELECTION_NORMAL, + getter_AddRefs(selection)); + if (NS_FAILED(result) || !selection) + return NS_ERROR_FAILURE; + + PRUint32 insertOffset = 0; + + nsCOMPtr childNodes; + result = parentNode->GetChildNodes(getter_AddRefs(childNodes)); + + if (NS_SUCCEEDED(result) && childNodes) { + PRUint32 nChildren = 0; + childNodes->GetLength(&nChildren); + + if(!beforeNode) { + // Append child + insertOffset = nChildren; + + } else { + // Determine offset of before node + int j; + PRInt32 nNodes = nChildren; + + for (j=0; j childNode; + result = childNodes->Item(j, getter_AddRefs(childNode)); + if ((NS_SUCCEEDED(result)) && childNode) { + if (childNode.get() == beforeNode) { + insertOffset = j; + break; + } + } + } + } + } + + // Collapse selection to insertion point + result = selection->Collapse(parentNode, insertOffset); + if (NS_FAILED(result)) + return result; + + // Get the first range in the selection + nsCOMPtr firstRange; + result = selection->GetRangeAt(0, getter_AddRefs(firstRange)); + if (NS_FAILED(result) || !firstRange) + return NS_ERROR_FAILURE; + + nsCOMPtr nsrange (do_QueryInterface(firstRange)); + if (!nsrange) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozXMLTermSession::InsertFragment,62,("Creating Fragment\n")); + + nsCOMPtr docfrag; + result = nsrange->CreateContextualFragment(aString, getter_AddRefs(docfrag)); + if (NS_FAILED(result) || !docfrag) + return NS_ERROR_FAILURE; + + nsCOMPtr docfragNode (do_QueryInterface(docfrag)); + if (!docfragNode) + return NS_ERROR_FAILURE; + + // Insert child nodes of document fragment before PRE text node + nsCOMPtr childNode; + result = docfragNode->GetFirstChild(getter_AddRefs(childNode)); + if (NS_FAILED(result) || !childNode) + return NS_ERROR_FAILURE; + + while (childNode) { + // Get next sibling prior to insertion + nsCOMPtr nextChild; + result = childNode->GetNextSibling(getter_AddRefs(nextChild)); + + XMLT_LOG(mozXMLTermSession::InsertFragment,72,("Inserting child node ...\n")); + + // nsCOMPtr childContent (do_QueryInterface(childNode)); + // if (childContent) childContent->List(stderr); + + // Insert child node + nsCOMPtr resultNode; + + PRBool replaceTem = replace; + if (beforeNode) { + if (replaceTem) { + // Replace before node + result = parentNode->ReplaceChild(childNode, beforeNode, + getter_AddRefs(resultNode)); + + beforeNode = nsnull; + + nsCOMPtr newBeforeNode; + result = resultNode->GetNextSibling(getter_AddRefs(newBeforeNode)); + + if (NS_SUCCEEDED(result) && newBeforeNode) { + beforeNode = newBeforeNode.get(); + replaceTem = false; + } + + } else { + // Insert before specified node + result = parentNode->InsertBefore(childNode, beforeNode, + getter_AddRefs(resultNode)); + } + } else { + // Append child + result = parentNode->AppendChild(childNode, getter_AddRefs(resultNode)); + } + if (NS_FAILED(result)) + return result; + + // Refresh attributes of inserted child node (deep) + DeepRefreshAttributes(resultNode, entryNumber); + + childNode = nextChild; + } + + return NS_OK; + +} + + +/** Deep refresh of selected attributes for DOM elements + * (WORKAROUND for inserting HTML fragments properly) + * @param domNode DOM node of branch to be refreshed + * @param entryNumber entry number (default value = -1) + * (if entryNumber >= 0, all '#' characters in event + * handler scripts are substituted by entryNumber) + */ +NS_IMETHODIMP mozXMLTermSession::DeepRefreshAttributes( + nsCOMPtr& domNode, + PRInt32 entryNumber) +{ + static const PRInt32 REFRESH_ATTRIBUTE_NAMES = 3; + static const char* const refreshAttributeNames[] = { + "id", + "onclick", + "ondblclick" + }; + + nsresult result; + nsAutoString numberString = ""; + + if (entryNumber >= 0) + numberString.Append(entryNumber,10); + + nsCOMPtr domElement = do_QueryInterface(domNode); + if (!domElement) + return NS_OK; + + int j; + for (j=0; jGetAttribute(attName, attValue); + if (NS_SUCCEEDED(result) && (attValue.Length() > 0)) { + + if (entryNumber >= 0) { + // Search for number character + PRInt32 numberOffset = attValue.FindChar((PRUnichar) '#'); + + if (numberOffset >= 0) { + // Substitute number sign with supplied number + attValue.Cut(numberOffset,1); + attValue.Insert(numberString, numberOffset); + } + } + + // Refresh attribute value + domElement->SetAttribute(attName, attValue); + + XMLT_LOG(mozXMLTermSession::DeepRefreshEventAttributes,82, + ("Refreshing on%s attribute\n",sessionEventNames[j] )); + } + } + + // Iterate over all child nodes for deep refresh + nsCOMPtr child; + result = domNode->GetFirstChild(getter_AddRefs(child)); + if (NS_FAILED(result)) + return NS_OK; + + while (child) { + DeepRefreshAttributes(child, entryNumber); + + nsCOMPtr temp = child; + result = temp->GetNextSibling(getter_AddRefs(child)); + if (NS_FAILED(result)) + break; + } + + return NS_OK; +} + + +/** Forces display of data in output buffer + * @param flushAction type of flush action: display, split-off, clear, or + * close incomplete lines + */ +NS_IMETHODIMP mozXMLTermSession::FlushOutput(FlushActionType flushAction) +{ + nsresult result; + + if (!mEntryHasOutput) + return NS_OK; + + XMLT_LOG(mozXMLTermSession::FlushOutput,70, + ("flushAction=%d, mOutputDisplayType=%d\n", + flushAction, mOutputDisplayType)); + + PRBool preDisplay = (mOutputDisplayType == PRE_STDOUT_NODE) || + (mOutputDisplayType == PRE_STDERR_NODE); + + if (preDisplay) { + // PRE text display + OutputDisplayType preDisplayType = mOutputDisplayType; + nsAutoString preTextSplit = ""; + + if (flushAction != DISPLAY_INCOMPLETE_FLUSH) { + // Split/clear/close incomplete line + + if (flushAction == SPLIT_INCOMPLETE_FLUSH) { + // Move incomplete text to new PRE element + preTextSplit = mPreTextIncomplete; + + } else if (flushAction == CLOSE_INCOMPLETE_FLUSH) { + // Move incomplete text into buffer + mPreTextBuffered += mPreTextIncomplete; + } + + // Clear incomplete PRE text + mPreTextIncomplete = ""; + + if (mPreTextBuffered.Length() == 0) { + // Remove last text node + nsCOMPtr resultNode; + result = mOutputDisplayNode->RemoveChild(mOutputTextNode, + getter_AddRefs(resultNode)); + + // Check if PRE node has any child nodes + PRBool hasChildNodes = true; + result = mOutputDisplayNode->HasChildNodes(&hasChildNodes); + + if (!hasChildNodes) { + // No child nodes left; Delete PRE node itself + nsCOMPtr resultNode2; + result = mOutputBlockNode->RemoveChild(mOutputDisplayNode, + getter_AddRefs(resultNode)); + } + + mOutputDisplayNode = nsnull; + mOutputDisplayType = NO_NODE; + mOutputTextNode = nsnull; + } + } + + if (mOutputDisplayNode != nsnull) { + // Update displayed PRE text + nsAutoString outString = mPreTextBuffered; + outString += mPreTextIncomplete; + + if (outString != mPreTextDisplayed) { + // Display updated buffer + mPreTextDisplayed = outString; + + XMLT_LOG(mozXMLTermSession::FlushOutput,72, + ("mOutputTextNode=%d\n", (mOutputTextNode != nsnull))); + + result = SetDOMText(mOutputTextNode, mPreTextDisplayed); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + } + + if (flushAction != DISPLAY_INCOMPLETE_FLUSH) { + // Split/clear/close incomplete line + mOutputDisplayNode = nsnull; + mOutputDisplayType = NO_NODE; + mOutputTextNode = nsnull; + + if ( (flushAction == SPLIT_INCOMPLETE_FLUSH) && + (preTextSplit.Length() > 0) ) { + // Create new PRE element with incomplete text + nsAutoString styleStr = ""; + + if (preDisplayType == PRE_STDERR_NODE) { + styleStr += (PRUnichar) LTERM_STDERR_STYLE; + } else { + styleStr += (PRUnichar) LTERM_STDOUT_STYLE; + } + + XMLT_LOG(mozXMLTermSession::FlushOutput,72,("splitting\n")); + + AppendOutput(preTextSplit, styleStr, false); + } + } + } + + } else if (mOutputDisplayNode != nsnull) { + // Non-PRE node + if (flushAction == CLEAR_INCOMPLETE_FLUSH) { + // Clear incomplete line info + nsCOMPtr resultNode; + result = mOutputBlockNode->RemoveChild(mOutputDisplayNode, + getter_AddRefs(resultNode)); + mOutputDisplayNode = nsnull; + mOutputDisplayType = NO_NODE; + mOutputTextNode = nsnull; + + } else if (flushAction == CLOSE_INCOMPLETE_FLUSH) { + mOutputDisplayNode = nsnull; + mOutputDisplayType = NO_NODE; + mOutputTextNode = nsnull; + } + } + + XMLT_LOG(mozXMLTermSession::FlushOutput,71,("returning\n")); + + return NS_OK; +} + + +/** Scrolls document to align bottom and left margin with screen */ +NS_IMETHODIMP mozXMLTermSession::ScrollBottomLeft(void) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::ScrollBottomLeft,70,("\n")); + + if (!mCurrentEntryNode) + return NS_ERROR_FAILURE; + + // Scroll primary frame to bottom of view + nsCOMPtr blockContent (do_QueryInterface(mCurrentEntryNode)); + if (!blockContent) + return NS_ERROR_FAILURE; + + nsIFrame* primaryFrame; + + result = mPresShell->GetPrimaryFrameFor(blockContent, &primaryFrame); + if (NS_FAILED(result)) { + return NS_ERROR_FAILURE; + } + + result = mPresShell->ScrollFrameIntoView(primaryFrame, + NS_PRESSHELL_SCROLL_BOTTOM, + NS_PRESSHELL_SCROLL_LEFT); + if (NS_FAILED(result)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + + +/** Gets current entry (command) number + * @param aNumber (output) current entry number + */ +NS_IMETHODIMP mozXMLTermSession::GetCurrentEntryNumber(PRInt32 *aNumber) +{ + *aNumber = mCurrentEntryNumber; + return NS_OK; +} + + +// Get size of entry history buffer +NS_IMETHODIMP mozXMLTermSession::GetHistory(PRInt32 *aHistory) +{ + *aHistory = mMaxHistory; + return NS_OK; +} + + +// Set size of entry history buffer +NS_IMETHODIMP mozXMLTermSession::SetHistory(PRInt32 aHistory) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::SetHistory,30,("\n")); + + if (aHistory < 1) + aHistory = 1; + + if (mInitialized && mStartEntryNode && (aHistory < mMaxHistory)) { + // Delete any extra entry blocks + PRInt32 delEntries = (mCurrentEntryNumber-mStartEntryNumber) + - aHistory; + PRInt32 j; + for (j=0; j newStartNode; + result = mStartEntryNode->GetNextSibling(getter_AddRefs(newStartNode)); + if (NS_FAILED(result) || !newStartNode) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr resultNode; + result = mSessionNode->RemoveChild(mStartEntryNode, + getter_AddRefs(resultNode)); + + if (NS_FAILED(result)) { + return NS_ERROR_FAILURE; + } + + mStartEntryNode = newStartNode; + mStartEntryNumber++; + } + } + + mMaxHistory = aHistory; + + return NS_OK; +} + + +// Get HTML prompt string +NS_IMETHODIMP mozXMLTermSession::GetPrompt(PRUnichar **_aPrompt) +{ + // NOTE: Need to be sure that this may be freed by nsAllocator::Free + *_aPrompt = mPromptHTML.ToNewUnicode(); + return NS_OK; +} + + +// Set HTML prompt string +NS_IMETHODIMP mozXMLTermSession::SetPrompt(const PRUnichar* aPrompt) +{ + mPromptHTML = aPrompt; + return NS_OK; +} + + +/** Create a DIV element with attributes NAME="preface", CLASS="preface", + * and ID="preface0", containing an empty text node, and append it as a + * child of the main BODY element. Also make it the current display element. + */ +NS_IMETHODIMP mozXMLTermSession::NewPreface(void) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::NewPreface,40,("\n")); + + // Create preface element and append as child of session element + nsCOMPtr divNode; + nsAutoString tagName = "div"; + nsAutoString name = "preface"; + result = NewElement(tagName, name, 0, + mSessionNode, divNode); + + if (NS_FAILED(result) || !divNode) + return NS_ERROR_FAILURE; + + mOutputBlockNode = divNode; + + mOutputDisplayType = NO_NODE; + mOutputDisplayNode = nsnull; + mOutputTextNode = nsnull; + + // Command output being processed + mEntryHasOutput = true; + + return NS_OK; +} + + +/** Create and append a new DIV element with attributes NAME="entry", + * CLASS="entry", and ID="entry#" as the last child of the main BODY element, + * where "#" denotes the new entry number obtained by incrementing the + * current entry number. + * Inside the entry element, create a DIV element with attributes + * NAME="input", CLASS="input", and ID="input#" containing two elements, + * named "prompt" and "command", each containing a text node. + * Insert the supplied prompt string into the prompt element's text node. + * @param aPrompt prompt string to be inserted into prompt element + */ +NS_IMETHODIMP mozXMLTermSession::NewEntry(const nsString& aPrompt) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::NewEntry,50,("\n")); + + if (mCurrentEntryNumber == 0) { + // First entry + mCurrentEntryNumber = 1; + mStartEntryNumber = 1; + + } else { + // Not first entry + + // Add event attributes to current command element + result = SetEventAttributes(sessionElementNames[COMMAND_ELEMENT], + mCurrentEntryNumber, + mCommandSpanNode); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + // Increment entry number + mCurrentEntryNumber++; + + if ((mCurrentEntryNumber - mStartEntryNumber) > mMaxHistory) { + // Delete oldest displayed entry element + + nsCOMPtr newStartNode; + result = mStartEntryNode->GetNextSibling(getter_AddRefs(newStartNode)); + if (NS_FAILED(result) || !newStartNode) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr resultNode; + result = mSessionNode->RemoveChild(mStartEntryNode, + getter_AddRefs(resultNode)); + + if (NS_FAILED(result)) { + return NS_ERROR_FAILURE; + } + + mStartEntryNode = newStartNode; + mStartEntryNumber++; + } + } + + XMLT_LOG(mozXMLTermSession::NewEntry,50, + ("%d (start=%d)\n", mCurrentEntryNumber, mStartEntryNumber)); + + nsAutoString tagName, name; + + // Create "entry" element + nsCOMPtr entryNode; + tagName = "div"; + name = sessionElementNames[ENTRY_ELEMENT]; + result = NewElement(tagName, name, mCurrentEntryNumber, + mSessionNode, entryNode); + if (NS_FAILED(result) || !entryNode) { + return NS_ERROR_FAILURE; + } + + mCurrentEntryNode = entryNode; + + if (mCurrentEntryNumber == 1) { + mStartEntryNode = mCurrentEntryNode; + } + + // Create "input" element containing "prompt" and "command" elements + nsCOMPtr inputNode; + tagName = "div"; + name = sessionElementNames[INPUT_ELEMENT]; + result = NewElement(tagName, name, mCurrentEntryNumber, + mCurrentEntryNode, inputNode); + if (NS_FAILED(result) || !inputNode) { + return NS_ERROR_FAILURE; + } + + nsAutoString classAttribute; + + // Create prompt element + nsCOMPtr newPromptSpanNode; + tagName = "span"; + name = sessionElementNames[PROMPT_ELEMENT]; + result = NewElement(tagName, name, mCurrentEntryNumber, + inputNode, newPromptSpanNode); + if (NS_FAILED(result) || !newPromptSpanNode) { + return NS_ERROR_FAILURE; + } + + mPromptSpanNode = newPromptSpanNode; + + // Add event attributes to prompt element + result = SetEventAttributes(name, mCurrentEntryNumber, + mPromptSpanNode); + + if (mPromptHTML.Length() == 0) { + // Create text node as child of prompt element + nsCOMPtr textNode; + result = NewTextNode(mPromptSpanNode, textNode); + + if (NS_FAILED(result) || !textNode) + return NS_ERROR_FAILURE; + + // Set prompt text + result = SetDOMText(textNode, aPrompt); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + } else { + // User-specified HTML prompt + result = InsertFragment(mPromptHTML, mPromptSpanNode, + mCurrentEntryNumber); + } + + // Create command element + nsCOMPtr newCommandSpanNode; + tagName = "span"; + name = sessionElementNames[COMMAND_ELEMENT]; + result = NewElement(tagName, name, mCurrentEntryNumber, + inputNode, newCommandSpanNode); + if (NS_FAILED(result) || !newCommandSpanNode) { + return NS_ERROR_FAILURE; + } + + mCommandSpanNode = newCommandSpanNode; + + // Create text node as child of command element + nsCOMPtr textNode2; + result = NewTextNode(mCommandSpanNode, textNode2); + + if (NS_FAILED(result) || !textNode2) + return NS_ERROR_FAILURE; + + mInputTextNode = textNode2; + + // Create output element and append as child of current entry element + nsCOMPtr divNode; + tagName = "div"; + name = sessionElementNames[OUTPUT_ELEMENT]; + result = NewElement(tagName, name, mCurrentEntryNumber, + mCurrentEntryNode, divNode); + + if (NS_FAILED(result) || !divNode) + return NS_ERROR_FAILURE; + + mOutputBlockNode = divNode; + + mOutputDisplayType = NO_NODE; + mOutputDisplayNode = nsnull; + mOutputTextNode = nsnull; + + // No command output processed yet + mEntryHasOutput = false; + + return NS_OK; +} + + +/** Append a BR element as the next child of specified parent. + * @param parentNode parent node for BR element + */ +NS_IMETHODIMP mozXMLTermSession::NewBreak(nsIDOMNode* parentNode) +{ + nsresult result; + nsAutoString tagName = "br"; + + XMLT_LOG(mozXMLTermSession::NewBreak,60,("\n")); + + // Create "br" element and append as child of specified parent + nsCOMPtr brNode; + nsAutoString name = ""; + result = NewElement(tagName, name, -1, parentNode, brNode); + + if (NS_FAILED(result) || !brNode) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Create an empty block element with tag name tagName with attributes + * NAME="name", CLASS="name", and ID="name#", and appends it as a child of + * the specified parent. ("#" denotes the specified number) + * Also create an empty text node inside the new block element. + * @param tagName tag name of element + * @param name name and class of element + * (If zero-length string, then no attributes are set) + * @param number numeric suffix for element ID + * (If < 0, no ID attribute is defined) + * @param parentNode parent node for element + * @param blockNode (output) block-level DOM node for created element + * @param textNode (output) child text DOM node of element + */ +NS_IMETHODIMP mozXMLTermSession::NewElementWithText(const nsString& tagName, + const nsString& name, PRInt32 number, + nsIDOMNode* parentNode, + nsCOMPtr& blockNode, + nsCOMPtr& textNode) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::NewElementWithText,80,("\n")); + + // Create block element + result = NewElement(tagName, name, number, parentNode, blockNode); + if (NS_FAILED(result) || !blockNode) + return NS_ERROR_FAILURE; + + // Create text node as child of block element + result = NewTextNode(blockNode, textNode); + + if (NS_FAILED(result) || !textNode) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Creates an empty anchor (A) element with tag name tagName with attributes + * CLASS="classAttribute", and ID="classAttribute#", and appends it as a + * child of the specified parent. ("#" denotes the specified number) + * @param classAttribute class attribute of anchor element + * (If zero-length string, then no attributes are set) + * @param number numeric suffix for element ID + * (If < 0, no ID attribute is defined) + * @param parentNode parent node for element + * @param anchorNode (output) DOM node for created anchor element + */ +NS_IMETHODIMP mozXMLTermSession::NewAnchor(const nsString& classAttribute, + PRInt32 number, + nsIDOMNode* parentNode, + nsCOMPtr& anchorNode) +{ + nsresult result; + nsAutoString tagName("a"); + + XMLT_LOG(mozXMLTermSession::NewAnchor,80,("\n")); + + // Create anchor + nsCOMPtr newElement; + result = mDOMDocument->CreateElement(tagName, getter_AddRefs(newElement)); + if (NS_FAILED(result) || !newElement) + return NS_ERROR_FAILURE; + + // Set element attributes + nsAutoString hrefAtt("href"); + nsAutoString hrefVal("#"); + newElement->SetAttribute(hrefAtt, hrefVal); + + if (classAttribute.Length() > 0) { + nsAutoString classStr("class"); + newElement->SetAttribute(classStr, classAttribute); + + if (number >= 0) { + nsAutoString idAtt("id"); + nsAutoString idVal(classAttribute); + idVal.Append(number,10); + newElement->SetAttribute(idAtt, idVal); + } + } + + // Append child to parent + nsCOMPtr newBlockNode = do_QueryInterface(newElement); + result = parentNode->AppendChild(newBlockNode, getter_AddRefs(anchorNode)); + if (NS_FAILED(result) || !anchorNode) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Creates an empty block element with tag name tagName with attributes + * NAME="name", CLASS="name", and ID="name#", and appends it as a child of + * the specified parent. ("#" denotes the specified number) + * @param tagName tag name of element + * @param name name and class of element + * (If zero-length string, then no attributes are set) + * @param number numeric suffix for element ID + * (If < 0, no ID attribute is defined) + * @param parentNode parent node for element + * @param blockNode (output) block-level DOM node for created element + */ +NS_IMETHODIMP mozXMLTermSession::NewElement(const nsString& tagName, + const nsString& name, PRInt32 number, + nsIDOMNode* parentNode, + nsCOMPtr& blockNode) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::NewElement,80,("\n")); + + // Create element + nsCOMPtr newElement; + result = mDOMDocument->CreateElement(tagName, getter_AddRefs(newElement)); + if (NS_FAILED(result) || !newElement) + return NS_ERROR_FAILURE; + + if (name.Length() > 0) { + // Set attributes + nsAutoString classAtt("class"); + nsAutoString classVal(name); + newElement->SetAttribute(classAtt, classVal); + + nsAutoString nameAtt("name"); + nsAutoString nameVal(name); + newElement->SetAttribute(nameAtt, nameVal); + + if (number >= 0) { + nsAutoString idAtt("id"); + nsAutoString idVal(name); + idVal.Append(number,10); + newElement->SetAttribute(idAtt, idVal); + } + } + + // Append child to parent + nsCOMPtr newBlockNode = do_QueryInterface(newElement); + result = parentNode->AppendChild(newBlockNode, getter_AddRefs(blockNode)); + if (NS_FAILED(result) || !blockNode) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Creates a new DOM text node, and appends it as a child of the + * specified parent. + * @param parentNode parent node for element + * @param textNode (output) created text DOM node + */ +NS_IMETHODIMP mozXMLTermSession::NewTextNode( nsIDOMNode* parentNode, + nsCOMPtr& textNode) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::NewTextNode,80,("\n")); + + // Create text node + nsCOMPtr newText; + nsAutoString nullStr(""); + result = mDOMDocument->CreateTextNode(nullStr, getter_AddRefs(newText)); + if (NS_FAILED(result) || !newText) + return NS_ERROR_FAILURE; + + // Append child to parent + nsCOMPtr newTextNode = do_QueryInterface(newText); + result = parentNode->AppendChild(newTextNode, getter_AddRefs(textNode)); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Add event attributes (onclick, ondblclick, ...) to DOM node + * @param name name of DOM node (supplied as argument to the event handler) + * @param number entry number (supplied as argument to the event handler) + * @param domNode DOM node to be modified + */ +NS_IMETHODIMP mozXMLTermSession::SetEventAttributes(const nsString& name, + PRInt32 number, + nsCOMPtr& domNode) +{ + nsresult result; + + nsCOMPtr domElement = do_QueryInterface(domNode); + if (!domElement) + return NS_ERROR_FAILURE; + + int j; + for (j=0; jSetAttribute(attName, attValue); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + + +/** Sets text content of a DOM node to supplied string + * @param textNode DOM text node to be modified + * @param aString string to be inserted + */ +NS_IMETHODIMP mozXMLTermSession::SetDOMText(nsCOMPtr& textNode, + const nsString& aString) +{ + nsresult result; + + nsCOMPtr domText (do_QueryInterface(textNode)); + if (!domText) + return NS_ERROR_FAILURE; + + result = domText->SetData(aString); + + return result; +} + + +/** Checks if node is a text node + * @param aNode DOM node to be checked + * @return true if node is a text node + */ +PRBool mozXMLTermSession::IsTextNode(nsIDOMNode *aNode) +{ + if (!aNode) { + NS_NOTREACHED("null node passed to IsTextNode()"); + return PR_FALSE; + } + + XMLT_LOG(mozXMLTermSession::IsTextNode,90,("\n")); + + PRUint16 nodeType; + aNode->GetNodeType(&nodeType); + if (nodeType == nsIDOMNode::TEXT_NODE) + return PR_TRUE; + + return PR_FALSE; +} + + +/** Checks if node is a text, span, or anchor node + * (i.e., allowed inside a PRE element) + * @param aNode DOM node to be checked + * @return true if node is a text, span or anchor node + */ +PRBool mozXMLTermSession::IsPREInlineNode(nsIDOMNode* aNode) +{ + nsresult result; + PRBool isPREInlineNode = false; + + nsCOMPtr domText = do_QueryInterface(aNode); + + if (domText) { + isPREInlineNode = true; + + } else { + nsCOMPtr domElement = do_QueryInterface(aNode); + + if (domElement) { + nsAutoString tagName = ""; + result = domElement->GetTagName(tagName); + if (NS_SUCCEEDED(result)) { + isPREInlineNode = tagName.EqualsIgnoreCase("span") || + tagName.EqualsIgnoreCase("a"); + } + } + } + + return isPREInlineNode; +} + + +/** Serializes DOM node and its content as an HTML fragment string + * @param aNode DOM node to be serialized + * @param indentString indentation prefix string + * @param htmlString (output) serialized HTML fragment + * @param deepContent if true, serialize children of node as well + * (defaults to false) + * @param insidePREnode set to true if aNode is embedded inside a PRE node + * control formatting + * (defaults to false) + */ +NS_IMETHODIMP mozXMLTermSession::ToHTMLString(nsIDOMNode* aNode, + nsString& indentString, + nsString& htmlString, + PRBool deepContent, + PRBool insidePRENode) +{ + nsresult result; + + XMLT_LOG(mozXMLTermSession::ToHTMLString,80,("\n")); + + nsAutoString newIndentString (indentString); + newIndentString += " "; + + htmlString = ""; + + nsCOMPtr domText( do_QueryInterface(aNode) ); + + if (domText) { + // Text node + nsCOMPtr htmlContent ( do_QueryInterface(aNode) ); + + if (htmlContent) { + htmlContent->ToHTMLString(htmlString); + XMLT_LOG(mozXMLTermSession::ToHTMLString,82,("htmlContent\n")); + } else { + domText->GetData(htmlString); + } + + } else { + nsCOMPtr domElement = do_QueryInterface(aNode); + + if (domElement) { + nsAutoString tagName = ""; + domElement->GetTagName(tagName); + + if (!insidePRENode) { + htmlString += indentString; + } + htmlString += "<"; + htmlString += tagName; + + PRBool isPRENode = tagName.EqualsIgnoreCase("pre"); + + nsCOMPtr namedNodeMap(nsnull); + result = aNode->GetAttributes(getter_AddRefs(namedNodeMap)); + + if (NS_SUCCEEDED(result) && namedNodeMap) { + // Print all attributes + PRUint32 nodeCount, j; + result = namedNodeMap->GetLength(&nodeCount); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr attrNode; + + for (j=0; jItem(j, getter_AddRefs(attrNode)); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr attr = do_QueryInterface(attrNode); + + if (attr) { + nsAutoString attrName = ""; + nsAutoString attrValue = ""; + + result = attr->GetName(attrName); + if (NS_SUCCEEDED(result)) { + htmlString += " "; + htmlString += attrName; + } + + result = attr->GetValue(attrValue); + if (NS_SUCCEEDED(result) && (attrName.Length() > 0)) { + htmlString += "=\""; + htmlString += attrValue; + htmlString += "\""; + } + } + } + } + } + } + + if (!deepContent) { + htmlString += ">"; + + } else { + // Iterate over all child nodes to generate deep content + nsCOMPtr child; + result = aNode->GetFirstChild(getter_AddRefs(child)); + + nsAutoString htmlInner (""); + while (child) { + nsAutoString innerString; + ToHTMLString(child, newIndentString, innerString, deepContent, + isPRENode); + + htmlInner += innerString; + + nsCOMPtr temp = child; + result = temp->GetNextSibling(getter_AddRefs(child)); + if (NS_FAILED(result)) + break; + } + + if (htmlInner.Length() > 0) { + if (insidePRENode) + htmlString += "\n>"; + else + htmlString += ">\n"; + + htmlString += htmlInner; + + if (!insidePRENode) + htmlString += indentString; + } else { + htmlString += ">"; + } + + htmlString += ""; + + if (!insidePRENode) + htmlString += "\n"; + } + } + } + + return NS_OK; +} + + +/** Implements the "tree:" meta command to traverse DOM tree + * @param fileStream file stream for displaying tree traversal output + * @param rootNode root node of DOM tree + * @param currentNode current node for traversal + * @param treeActionCode traversal action type + */ +void mozXMLTermSession::TraverseDOMTree(FILE* fileStream, + nsIDOMNode* rootNode, + nsCOMPtr& currentNode, + TreeActionCode treeActionCode) +{ + static const PRInt32 NODE_TYPE_NAMES = 12; + + static const char* const nodeTypeNames[NODE_TYPE_NAMES] = { + "ELEMENT", + "ATTRIBUTE", + "TEXT", + "CDATA_SECTION", + "ENTITY_REFERENCE", + "ENTITY_NODE", + "PROCESSING_INSTRUCTION", + "COMMENT", + "DOCUMENT", + "DOCUMENT_TYPE", + "DOCUMENT_FRAGMENT", + "NOTATION_NODE" + }; + + static const PRInt32 PRINT_ATTRIBUTE_NAMES = 2; + + static const char* const printAttributeNames[PRINT_ATTRIBUTE_NAMES] = { + "class", + "id" + }; + + nsresult result = NS_ERROR_FAILURE; + nsCOMPtr moveNode(nsnull); + nsCOMPtr namedNodeMap(nsnull); + + switch (treeActionCode) { + case TREE_MOVE_UP: + if (currentNode.get() != rootNode) { + result = currentNode->GetParentNode(getter_AddRefs(moveNode)); + + if (NS_SUCCEEDED(result) && moveNode) { + // Move up to parent node + currentNode = moveNode; + } + + } else { + fprintf(fileStream, "TraverseDOMTree: already at the root node \n"); + } + break; + + case TREE_MOVE_DOWN: + result = currentNode->GetFirstChild(getter_AddRefs(moveNode)); + + if (NS_SUCCEEDED(result) && moveNode) { + // Move down to child node + currentNode = moveNode; + } else { + fprintf(fileStream, "TraverseDOMTree: already at a leaf node\n"); + } + break; + + case TREE_MOVE_LEFT: + if (currentNode.get() != rootNode) { + result = currentNode->GetPreviousSibling(getter_AddRefs(moveNode)); + + if (NS_SUCCEEDED(result) && moveNode) { + // Move to previous sibling node + currentNode = moveNode; + } else { + fprintf(fileStream, "TraverseDOMTree: already at leftmost node\n"); + } + } else { + fprintf(fileStream, "TraverseDOMTree: already at the root node \n"); + } + break; + + case TREE_MOVE_RIGHT: + if (currentNode.get() != rootNode) { + result = currentNode->GetNextSibling(getter_AddRefs(moveNode)); + + if (NS_SUCCEEDED(result) && moveNode) { + // Move to next sibling node + currentNode = moveNode; + } else { + fprintf(fileStream, "TraverseDOMTree: already at rightmost node\n"); + } + } else { + fprintf(fileStream, "TraverseDOMTree: already at the root node \n"); + } + break; + + case TREE_PRINT_ATTS: + case TREE_PRINT_HTML: + if (true) { + nsAutoString indentString (""); + nsAutoString htmlString; + ToHTMLString(currentNode, indentString, htmlString, + (PRBool) (treeActionCode == TREE_PRINT_HTML) ); + + fprintf(fileStream, "%s:\n", treeActionNames[treeActionCode-1]); + + char* htmlCString = htmlString.ToNewCString(); + fprintf(fileStream, "%s", htmlCString); + nsCRT::free(htmlCString); + + fprintf(fileStream, "\n"); + } + break; + + default: + fprintf(fileStream, "mozXMLTermSession::TraverseDOMTree - unknown action %d\n", + treeActionCode); + } + + if (NS_SUCCEEDED(result) && moveNode) { + PRUint16 nodeType = 0; + + moveNode->GetNodeType(&nodeType); + fprintf(fileStream, "%s%s: ", treeActionNames[treeActionCode-1], + nodeTypeNames[nodeType-1]); + + nsCOMPtr domElement; + domElement = do_QueryInterface(moveNode); + if (domElement) { + nsAutoString tagName = ""; + + result = domElement->GetTagName(tagName); + if (NS_SUCCEEDED(result)) { + char* tagCString = tagName.ToNewCString(); + fprintf(fileStream, "%s", tagCString); + nsCRT::free(tagCString); + + // Print selected attribute values + int j; + for (j=0; jGetAttribute(attName, attValue); + if (NS_SUCCEEDED(result) && (attValue.Length() > 0)) { + // Print attribute value + char* tagCString2 = attValue.ToNewCString(); + fprintf(fileStream, " %s=%s", printAttributeNames[j], tagCString2); + nsCRT::free(tagCString2); + } + } + } + } + fprintf(fileStream, "\n"); + } +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermSession.h b/mozilla/extensions/xmlterm/base/mozXMLTermSession.h new file mode 100644 index 00000000000..e369aa96690 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermSession.h @@ -0,0 +1,537 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermSession.h: class to manage session input/output display +// NOTE: This class is getting too unwieldy. It should be modularized, +// using a separate class for entries, for example, once the dust +// settles. + +#include "nscore.h" +#include "prlog.h" + +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "nsIPresShell.h" +#include "nsIDOMNode.h" +#include "nsIDOMDocument.h" + +#include "nsIContent.h" + +#include "mozXMLT.h" +#include "mozILineTermAux.h" +#include "mozIXMLTerminal.h" + + +class mozXMLTermSession +{ + public: + + mozXMLTermSession(); + virtual ~mozXMLTermSession(); + + /** Initializes XMLterm session + * @param aXMLTerminal containing XMLTerminal object + * @param aPresShell presentation shell associated with XMLterm + * @param aDOMDocument DOM document associated with XMLterm + */ + NS_IMETHOD Init(mozIXMLTerminal* aXMLTerminal, + nsIPresShell* aPresShell, + nsIDOMDocument* aDOMDocument); + + /** Finalizes (closes) session + */ + NS_IMETHOD Finalize(void); + + /** Preprocesses user input before it is transmitted to LineTerm + * @param aString (inout) input data to be preprocessed + * @param consumed (output) true if input data has been consumed + */ + NS_IMETHOD Preprocess(const nsString& aString, PRBool& consumed); + + /** Reads all available data from LineTerm and displays it; + * returns when no more data is available. + * @param lineTermAux LineTermAux object to read data from + */ + NS_IMETHOD ReadAll(mozILineTermAux* lineTermAux); + + /** Gets current entry (command) number + * @param aNumber (output) current entry number + */ + NS_IMETHOD GetCurrentEntryNumber(PRInt32 *aNumber); + + /** Gets command history buffer count + * @param aHistory (output) history buffer count + */ + NS_IMETHOD GetHistory(PRInt32 *aHistory); + + /** Sets command history buffer count + * @param aHistory history buffer count + */ + NS_IMETHOD SetHistory(PRInt32 aHistory); + + /** Gets prompt string + * @param aPrompt (output) prompt string + */ + NS_IMETHOD GetPrompt(PRUnichar **aPrompt); + + /** Sets prompt string + * @param aPrompt prompt string + */ + NS_IMETHOD SetPrompt(const PRUnichar* aPrompt); + +protected: + + /** ShellML element type (see ShellML documentation), + * implemented as CLASS attribute of HTML elements + */ + enum SessionElementType { + SESSION_ELEMENT = 0, + ENTRY_ELEMENT, + INPUT_ELEMENT, + OUTPUT_ELEMENT, + PROMPT_ELEMENT, + COMMAND_ELEMENT, + STDIN_ELEMENT, + STDOUT_ELEMENT, + STDERR_ELEMENT, + SESSION_ELEMENT_TYPES + }; + + /** user-generated input event type */ + enum SessionEventType { + CLICK_EVENT = 0, + DBLCLICK_EVENT, + SESSION_EVENT_TYPES + }; + + /** display style of output */ + enum OutputDisplayType { + NO_NODE = 0, + PRE_STDOUT_NODE, + PRE_STDERR_NODE, + SPAN_STDOUT_NODE, + SPAN_STDERR_NODE, + SPAN_MIXED_NODE, + OUTPUT_DISPLAY_TYPES + }; + + /** markup style of output */ + enum OutputMarkupType { + PLAIN_TEXT = 0, + HTML_FRAGMENT, + HTML_DOCUMENT, + XML_DOCUMENT + }; + + /** settings for automatic markup detection */ + enum AutoDetectOption { + NO_MARKUP = 0, + FIRST_LINE, + ANY_LINE + }; + + /** type of output flush action */ + enum FlushActionType { + DISPLAY_INCOMPLETE_FLUSH = 0, + SPLIT_INCOMPLETE_FLUSH, + CLEAR_INCOMPLETE_FLUSH, + CLOSE_INCOMPLETE_FLUSH + }; + + /** type of currently active meta command */ + enum MetaCommandType { + NO_META_COMMAND = 0, + STREAM_META_COMMAND, + HTTP_META_COMMAND, + LS_META_COMMAND, + TREE_META_COMMAND, + META_COMMAND_TYPES + }; + + /** file type for directory display (TEMPORARY) */ + enum FileType { + PLAIN_FILE = 0, + DIRECTORY_FILE, + EXECUTABLE_FILE, + FILE_TYPES + }; + + /** action code for navigating XMLterm DOM document */ + enum TreeActionCode { + TREE_MOVE_UP = 1, + TREE_MOVE_DOWN = 2, + TREE_MOVE_LEFT = 3, + TREE_MOVE_RIGHT = 4, + TREE_PRINT_ATTS = 5, + TREE_PRINT_HTML = 6, + TREE_ACTION_CODES = 7 + }; + + /** Displays ("echoes") input text string with style and positions cursor + * @param aString string to be displayed + * @param aStyle style values for string (see lineterm.h) + * @param cursorCol cursor column + */ + NS_IMETHOD DisplayInput(const nsString& aString, + const nsString& aStyle, + PRInt32 cursorCol); + + /** Autodetects markup in current output line + * @param aString string to be displayed + * @param aStyle style values for string (see lineterm.h) + * @param firstOutputLine true if this is the first output line + */ + NS_IMETHOD AutoDetectMarkup(const nsString& aString, + const nsString& aStyle, + PRBool firstOutputLine); + + /** Initializes display of stream output with specified markup type + * @param streamURL effective URL of stream output + * @param streamMarkupType stream markup stype + */ + NS_IMETHOD InitStream(const nsString& streamURL, + OutputMarkupType streamMarkupType); + + /** Breaks output display by flushing and deleting incomplete lines */ + NS_IMETHOD BreakOutput(void); + + /** Processes output string with specified style + * @param aString string to be processed + * @param aStyle style values for string (see lineterm.h) + * (if it is a null string, STDOUT style is assumed) + * @param newline true if this is a complete line of output + * @param streamOutput true if string represents stream output + */ + NS_IMETHOD ProcessOutput(const nsString& aString, + const nsString& aStyle, + PRBool newline, + PRBool streamOutput); + + /** Appends text string to output buffer + * (appended text may need to be flushed for it to be actually displayed) + * @param aString string to be processed + * @param aStyle style values for string (see lineterm.h) + * (if it is a null string, STDOUT style is assumed) + * @param newline true if this is a complete line of output + */ + NS_IMETHOD AppendOutput(const nsString& aString, + const nsString& aStyle, + PRBool newline); + + /** Adds markup to LS output (TEMPORARY) + * @param aString string to be processed + * @param aStyle style values for string (see lineterm.h) + * (if it is a null string, STDOUT style is assumed) + */ + NS_IMETHOD AppendLineLS(const nsString& aString, + const nsString& aStyle); + + /** Inserts HTML fragment string as child of parentNode, before specified + * child node, or after the last child node + * @param aString HTML fragment string to be inserted + * @param parentNode parent node for HTML fragment + * @param entryNumber entry number (default value = -1) + * (if entryNumber >= 0, all '#' characters in aString + * are substituted by entryNumber) + * @param beforeNode child node before which to insert fragment; + * if null, insert after last child node + * (default value is null) + * @param replace if true, replace beforeNode with inserted fragment + * (default value is false) + */ + NS_IMETHOD InsertFragment(const nsString& aString, + nsCOMPtr& parentNode, + PRInt32 entryNumber = -1, + nsIDOMNode* beforeNode = nsnull, + PRBool replace = false); + + /** Deep refresh of selected attributes for DOM elements + * (WORKAROUND for inserting HTML fragments properly) + * @param domNode DOM node of branch to be refreshed + * @param entryNumber entry number (default value = -1) + * (if entryNumber >= 0, all '#' characters in event + * handler scripts are substituted by entryNumber) + */ + NS_IMETHOD DeepRefreshAttributes(nsCOMPtr& domNode, + PRInt32 entryNumber = -1); + + /** Forces display of data in output buffer + * @param flushAction type of flush action: display, split-off, clear, or + * close incomplete lines + */ + NS_IMETHOD FlushOutput(FlushActionType flushAction); + + /** Scrolls document to align bottom and left margin with screen */ + NS_IMETHOD ScrollBottomLeft(void); + + /** Create a DIV element with attributes NAME="preface", CLASS="preface", + * and ID="preface0", containing an empty text node, and append it as a + * child of the main BODY element. Also make it the current display element. + */ + NS_IMETHOD NewPreface(void); + + /** Create and append a new DIV element with attributes NAME="entry", + * CLASS="entry", and ID="entry#" as the last child of the main BODY element, + * where "#" denotes the new entry number obtained by incrementing the + * current entry number. + * Inside the entry element, create a DIV element with attributes + * NAME="input", CLASS="input", and ID="input#" containing two elements, + * named "prompt" and "command", each containing a text node. + * Insert the supplied prompt string into the prompt element's text node. + * @param aPrompt prompt string to be inserted into prompt element + */ + NS_IMETHOD NewEntry(const nsString& aPrompt); + + /** Append a BR element as the next child of specified parent. + * @param parentNode parent node for BR element + */ + NS_IMETHOD NewBreak(nsIDOMNode* parentNode); + + /** Creates an empty block element with tag name tagName with attributes + * NAME="name", CLASS="name", and ID="name#", and appends it as a child of + * the specified parent. ("#" denotes the specified number) + * Also create an empty text node inside the new block element. + * @param tagName tag name of element + * @param name name and class of element + * (If zero-length string, then no attributes are set) + * @param number numeric suffix for element ID + * (If < 0, no ID attribute is defined) + * @param parentNode parent node for element + * @param blockNode (output) block-level DOM node for created element + * @param textNode (output) child text DOM node of element + */ + NS_IMETHOD NewElementWithText(const nsString& tagName, + const nsString& name, PRInt32 number, + nsIDOMNode* parentNode, + nsCOMPtr& blockNode, + nsCOMPtr& textNode); + + /** Creates an empty anchor (A) element with tag name tagName with attributes + * CLASS="classAttribute", and ID="classAttribute#", and appends it as a + * child of the specified parent. ("#" denotes the specified number) + * @param classAttribute class attribute of anchor element + * (If zero-length string, then no attributes are set) + * @param number numeric suffix for element ID + * (If < 0, no ID attribute is defined) + * @param parentNode parent node for element + * @param anchorNode (output) DOM node for created anchor element + */ + NS_IMETHOD NewAnchor(const nsString& classAttribute, + PRInt32 number, + nsIDOMNode* parentNode, + nsCOMPtr& anchorNode); + + /** Creates an empty block element with tag name tagName with attributes + * NAME="name", CLASS="name", and ID="name#", and appends it as a child of + * the specified parent. ("#" denotes the specified number) + * @param tagName tag name of element + * @param name name and class of element + * (If zero-length string, then no attributes are set) + * @param number numeric suffix for element ID + * (If < 0, no ID attribute is defined) + * @param parentNode parent node for element + * @param blockNode (output) block-level DOM node for created element + */ + NS_IMETHOD NewElement(const nsString& tagName, + const nsString& name, PRInt32 number, + nsIDOMNode* parentNode, + nsCOMPtr& blockNode); + + /** Creates a new DOM text node, and appends it as a child of the + * specified parent. + * @param parentNode parent node for element + * @param textNode (output) created text DOM node + */ + NS_IMETHOD NewTextNode( nsIDOMNode* parentNode, + nsCOMPtr& textNode); + + /** Add event attributes (onclick, ondblclick, ...) to DOM node + * @param name name of DOM node (supplied as argument to the event handler) + * @param number entry number (supplied as argument to the event handler) + * @param domNode DOM node to be modified + */ + NS_IMETHOD SetEventAttributes(const nsString& name, + PRInt32 number, + nsCOMPtr& domNode); + + /** Sets text content of a DOM node to supplied string + * @param textNode DOM text node to be modified + * @param aString string to be inserted + */ + NS_IMETHOD SetDOMText(nsCOMPtr& textNode, + const nsString& aString); + + /** Checks if node is a text node + * @param aNode DOM node to be checked + * @return true if node is a text node + */ + PRBool IsTextNode(nsIDOMNode *aNode); + + /** Checks if node is a text, span, or anchor node + * (i.e., allowed inside a PRE element) + * @param aNode DOM node to be checked + * @return true if node is a text, span or anchor node + */ + PRBool IsPREInlineNode(nsIDOMNode* aNode); + + /** Serializes DOM node and its content as an HTML fragment string + * @param aNode DOM node to be serialized + * @param indentString indentation prefix string + * @param htmlString (output) serialized HTML fragment + * @param deepContent if true, serialize children of node as well + * (defaults to false) + * @param insidePREnode set to true if aNode is embedded inside a PRE node + * control formatting + * (defaults to false) + */ + NS_IMETHOD ToHTMLString(nsIDOMNode* aNode, + nsString& indentString, + nsString& htmlString, + PRBool deepContent = false, + PRBool insidePRENode = false); + + /** Implements the "tree:" meta command to traverse DOM tree + * @param fileStream file stream for displaying tree traversal output + * @param rootNode root node of DOM tree + * @param currentNode current node for traversal + * @param treeActionCode traversal action type + */ + void TraverseDOMTree(FILE* fileStream, + nsIDOMNode* rootNode, + nsCOMPtr& currentNode, + TreeActionCode treeActionCode); + + /** names of session elements */ + static const char* const sessionElementNames[SESSION_ELEMENT_TYPES]; + + /** names of session events */ + static const char* const sessionEventNames[SESSION_EVENT_TYPES]; + + /** names of meta commands */ + static const char* const metaCommandNames[META_COMMAND_TYPES]; + + /** names of file types (TEMPORARY) */ + static const char* const fileTypeNames[FILE_TYPES]; + + /** names of tree traversal action types */ + static const char* const treeActionNames[TREE_ACTION_CODES]; + + /** object initialization flag */ + PRBool mInitialized; + + + /** non-owning reference to containing XMLTerminal object */ + mozIXMLTerminal* mXMLTerminal; // non-owning reference + + /** non-owning reference to presentation shell associated with XMLterm */ + nsIPresShell* mPresShell; // non-owning reference (??) + + /** non-owning reference to DOM document containing XMLterm */ + nsIDOMDocument* mDOMDocument; // non-owning reference (??) + + + /** BODY node of document containing XMLterm */ + nsCOMPtr mBodyNode; + + /** XMLterm session node */ + nsCOMPtr mSessionNode; + + /** current debug node (TEMPORARY; used for tree traversal) */ + nsCOMPtr mCurrentDebugNode; + + + /** starting entry node in the history list */ + nsCOMPtr mStartEntryNode; + + /** current (and last) entry node in the history list */ + nsCOMPtr mCurrentEntryNode; + + /** maximum number of commands allowed to be saved in history list */ + PRInt32 mMaxHistory; + + /** entry number of first entry in history list */ + PRInt32 mStartEntryNumber; + + /** entry number of current entry */ + PRInt32 mCurrentEntryNumber; + + /** flag indicating whether current entry has output data */ + PRBool mEntryHasOutput; + + /** span node for current command prompt (is this necessary?) */ + nsCOMPtr mPromptSpanNode; + + /** span node for current command input (is this necessary?) */ + nsCOMPtr mCommandSpanNode; + + /** text node for current command input (is this necessary?) */ + nsCOMPtr mInputTextNode; + + + /** block-level node for current command output */ + nsCOMPtr mOutputBlockNode; + + /** current display element node for command output */ + nsCOMPtr mOutputDisplayNode; + + /** current text node for command output */ + nsCOMPtr mOutputTextNode; + + + /** currently active meta command (if any) */ + MetaCommandType mMetaCommandType; + + + /** currently active display style of output */ + OutputDisplayType mOutputDisplayType; + + + /** currently active markup style of output */ + OutputMarkupType mOutputMarkupType; + + /** currently active setting for automatic markup detection */ + AutoDetectOption mAutoDetect; + + + /** flag indicating whether a line break needs to be output */ + PRBool mLineBreakNeeded; + + /** flag marking the first line of output */ + PRBool mFirstOutputLine; + + + /** buffer for incomplete line of PRE text */ + nsString mPreTextIncomplete; + + /** buffer for complete lines of PRE text */ + nsString mPreTextBuffered; + + /** copy of PRE text already displayed */ + nsString mPreTextDisplayed; + + + /** prompt string (HTML) */ + nsString mPromptHTML; + + /** buffer for HTML/XML fragment streams */ + nsString mFragmentBuffer; + +}; diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermShell.cpp b/mozilla/extensions/xmlterm/base/mozXMLTermShell.cpp new file mode 100644 index 00000000000..aa5edfb3d05 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermShell.cpp @@ -0,0 +1,326 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermShell.cpp: implementation of mozIXMLTermShell +// providing an XPCONNECT wrapper to the XMLTerminal interface, +// thus allowing easy (and controlled) access from scripts + +#include + +#include "nscore.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "nsIDocumentViewer.h" +#include "nsIDocument.h" + +#include "nsIWebShell.h" +#include "nsIWebShellWindow.h" +#include "nsIPresShell.h" +#include "nsIPresContext.h" +#include "nsIScriptGlobalObject.h" + +#include "nsIServiceManager.h" + +#include "nsIAppShellService.h" +#include "nsAppShellCIDs.h" +#include "nsAppCoresCIDs.h" + +#include "nsIDOMToolkitCore.h" +#include "nsIDOMDocument.h" +#include "nsIDOMSelection.h" +#include "nsIDOMWindow.h" + +#include "mozXMLT.h" +#include "mozXMLTermShell.h" + +// Define Class IDs +static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID); +static NS_DEFINE_CID(kToolkitCoreCID, NS_TOOLKITCORE_CID); + +// Define Interface IDs +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermShell factory +///////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewXMLTermShell(mozIXMLTermShell** aXMLTermShell) +{ + NS_PRECONDITION(aXMLTermShell != nsnull, "null ptr"); + if (! aXMLTermShell) + return NS_ERROR_NULL_POINTER; + + *aXMLTermShell = new mozXMLTermShell(); + if (! *aXMLTermShell) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aXMLTermShell); + return NS_OK; +} + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermShell implementation +///////////////////////////////////////////////////////////////////////// + +mozXMLTermShell::mozXMLTermShell() : + mInitialized(PR_FALSE), + mContentWindow(nsnull), + mContentAreaWebShell(nsnull), + mXMLTerminal(nsnull) +{ + NS_INIT_REFCNT(); +} + +mozXMLTermShell::~mozXMLTermShell() +{ + if (mInitialized) { + Finalize(); + } +} + + +// Implement AddRef and Release +NS_IMPL_ADDREF(mozXMLTermShell) +NS_IMPL_RELEASE(mozXMLTermShell) + + +NS_IMETHODIMP +mozXMLTermShell::QueryInterface(REFNSIID aIID,void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if ( aIID.Equals(kISupportsIID)) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(mozIXMLTermShell*,this)); + + } else if ( aIID.Equals(mozIXMLTermShell::GetIID()) ) { + *aInstancePtr = NS_STATIC_CAST(mozIXMLTermShell*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + return NS_OK; +} + + +NS_IMETHODIMP mozXMLTermShell::GetCurrentEntryNumber(PRInt32 *aNumber) +{ + if (mXMLTerminal) { + return mXMLTerminal->GetCurrentEntryNumber(aNumber); + } else { + return NS_ERROR_NOT_INITIALIZED; + } +} + + +NS_IMETHODIMP mozXMLTermShell::GetHistory(PRInt32 *aHistory) +{ + if (mXMLTerminal) { + return mXMLTerminal->GetHistory(aHistory); + } else { + return NS_ERROR_NOT_INITIALIZED; + } +} + + +NS_IMETHODIMP mozXMLTermShell::SetHistory(PRInt32 aHistory) +{ + if (mXMLTerminal) { + return mXMLTerminal->SetHistory(aHistory); + } else { + return NS_ERROR_NOT_INITIALIZED; + } +} + + +NS_IMETHODIMP mozXMLTermShell::GetPrompt(PRUnichar **aPrompt) +{ + if (mXMLTerminal) { + return mXMLTerminal->GetPrompt(aPrompt); + } else { + return NS_ERROR_NOT_INITIALIZED; + } +} + + +NS_IMETHODIMP mozXMLTermShell::SetPrompt(const PRUnichar* aPrompt) +{ + if (mXMLTerminal) { + return mXMLTerminal->SetPrompt(aPrompt); + } else { + return NS_ERROR_NOT_INITIALIZED; + } +} + + +// Initialize XMLTermShell +NS_IMETHODIMP +mozXMLTermShell::Init(nsIDOMWindow* aContentWin, + const PRUnichar* URL, + const PRUnichar* args) +{ + nsresult result; + + XMLT_LOG(mozXMLTermShell::Init,10,("\n")); + + if (mInitialized) + return NS_ERROR_ALREADY_INITIALIZED; + + if (!aContentWin) + return NS_ERROR_NULL_POINTER; + + mContentWindow = aContentWin; // no addref + + nsCOMPtr globalObj = do_QueryInterface(mContentWindow, + &result); + if (NS_FAILED(result) || !globalObj) + return NS_ERROR_FAILURE; + + nsCOMPtr webShell; + globalObj->GetWebShell(getter_AddRefs(webShell)); + if (!webShell) + return NS_ERROR_FAILURE; + + mContentAreaWebShell = webShell; // SVN: does this assignment addref? + + // Create XMLTerminal + nsCOMPtr newXMLTerminal; + result = NS_NewXMLTerminal(getter_AddRefs(newXMLTerminal)); + + if(!newXMLTerminal) + result = NS_ERROR_OUT_OF_MEMORY; + + if (NS_SUCCEEDED(result)) { + // Initialize XMLTerminal with non-owning reference to us + result = newXMLTerminal->Init(mContentAreaWebShell, this, URL, args); + + if (NS_SUCCEEDED(result)) { + mXMLTerminal = newXMLTerminal; + } + } + + return result; +} + + +// De-initialize XMLTermShell and free resources +NS_IMETHODIMP +mozXMLTermShell::Finalize(void) +{ + XMLT_LOG(mozXMLTermShell::Finalize,10,("\n")); + + if (mXMLTerminal) { + // Finalize and release reference to XMLTerm object owned by us + mXMLTerminal->Finalize(); + mXMLTerminal = nsnull; + } + + mContentAreaWebShell = nsnull; + mContentWindow = nsnull; + + mInitialized = PR_FALSE; + + return NS_OK; +} + + +// Poll for readable data from XMLTerminal +NS_IMETHODIMP mozXMLTermShell::Poll(void) +{ + if (!mXMLTerminal) + return NS_ERROR_NOT_INITIALIZED; + + return mXMLTerminal->Poll(); +} + + +// Send string to LineTerm as if the user had typed it +NS_IMETHODIMP mozXMLTermShell::SendText(const PRUnichar* buf, + const PRUnichar* cookie) +{ + if (!mXMLTerminal) + return NS_ERROR_FAILURE; + + nsAutoString sendStr (buf); + + XMLT_LOG(mozXMLTermShell::SendText,10,("length=%d\n", sendStr.Length())); + + return mXMLTerminal->SendText(sendStr, cookie); +} + + +// Create new XMLTerm window with specified argument string +NS_IMETHODIMP +mozXMLTermShell::NewXMLTermWindow(const PRUnichar* args) +{ + nsresult result = NS_OK; + + XMLT_LOG(mozXMLTermShell::NewXMLTermWindow,10,("\n")); + + // Create the toolkit core instance... + nsIDOMToolkitCore* toolkit = nsnull; + result = nsServiceManager::GetService(kToolkitCoreCID, + nsIDOMToolkitCore::GetIID(), + (nsISupports**)&toolkit); + if (NS_FAILED(result)) + return result; + + nsAutoString argStr (args); + toolkit->ShowWindowWithArgs( "chrome://xmlterm/content/XMLTermFrame.xul", + nsnull, argStr ); + + /* Release the toolkit... */ + if (nsnull != toolkit) { + nsServiceManager::ReleaseService(kToolkitCoreCID, toolkit); + } + + return result; +} + + +// Exit XMLTerm window +NS_IMETHODIMP +mozXMLTermShell::Exit() +{ + nsIAppShellService* appShell = nsnull; + + XMLT_LOG(mozXMLTermShell::Exit,10,("\n")); + + // Create the Application Shell instance... + nsresult result = nsServiceManager::GetService(kAppShellServiceCID, + nsIAppShellService::GetIID(), + (nsISupports**)&appShell); + if (NS_SUCCEEDED(result)) { + appShell->Shutdown(); + nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); + } + return NS_OK; +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermShell.h b/mozilla/extensions/xmlterm/base/mozXMLTermShell.h new file mode 100644 index 00000000000..e1b72da5238 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermShell.h @@ -0,0 +1,81 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermShell.h: declaration of mozXMLTermShell +// which implements mozIXMLTermShell, providing an XPCONNECT wrapper +// to the XMLTerminal interface, thus allowing easy (and controlled) +// access from scripts + +#include + +#include "nscore.h" +#include "nspr.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "mozXMLT.h" +#include "mozIXMLTerminal.h" +#include "mozIXMLTermShell.h" + + +class mozXMLTermShell : public mozIXMLTermShell { + public: + + mozXMLTermShell(); + virtual ~mozXMLTermShell(); + + NS_DECL_ISUPPORTS + + // mozIXMLTermShell interface + + NS_IMETHOD GetCurrentEntryNumber(PRInt32 *aNumber); + + NS_IMETHOD GetHistory(PRInt32 *aHistory); + NS_IMETHOD SetHistory(PRInt32 aHistory); + NS_IMETHOD GetPrompt(PRUnichar **aPrompt); + NS_IMETHOD SetPrompt(const PRUnichar* aPrompt); + + NS_IMETHOD Init(nsIDOMWindow* aContentWin, + const PRUnichar* URL, + const PRUnichar* args); + + NS_IMETHOD Finalize(void); + NS_IMETHOD Poll(void); + + NS_IMETHOD SendText(const PRUnichar* buf, const PRUnichar* cookie); + + NS_IMETHOD NewXMLTermWindow(const PRUnichar* args); + + NS_IMETHOD Exit(void); + +protected: + + /** object initialization flag */ + PRBool mInitialized; + + /** non-owning reference to content window for XMLterm */ + nsIDOMWindow* mContentWindow; + + /** non-owning reference (??) to web shell for content window */ + nsIWebShell* mContentAreaWebShell; + + /** owning reference to XMLTerminal object created by us */ + nsCOMPtr mXMLTerminal; +}; diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermStream.cpp b/mozilla/extensions/xmlterm/base/mozXMLTermStream.cpp new file mode 100644 index 00000000000..04265e6362e --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermStream.cpp @@ -0,0 +1,568 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermStream.cpp: implementation of mozIXMLTermStream +// to display HTML/XML streams as documents + +#include "nscore.h" +#include "prlog.h" + +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "nsIAllocator.h" + +#include "nsIServiceManager.h" +#include "nsIIOService.h" +#include "nsIDocumentLoader.h" +#include "nsIContentViewer.h" +#include "nsIDocumentViewer.h" +#include "nsIPresContext.h" +#include "nsIPresShell.h" + +#include "nsIViewManager.h" +#include "nsIScrollableView.h" +#include "nsIDeviceContext.h" +#include "nsIFrame.h" + +#include "nsIScriptContextOwner.h" +#include "nsIScriptGlobalObject.h" + +#include "nsIDOMWindow.h" +#include "nsIDOMWindowCollection.h" +#include "nsIDOMElement.h" +#include "nsIDOMNode.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMDocument.h" +#include "nsIDOMHTMLDocument.h" +#include "nsIDocument.h" + +#include "nsIURL.h" +#include "nsNeckoUtil.h" + +#include "mozXMLT.h" +#include "mozXMLTermUtils.h" +#include "mozXMLTermStream.h" + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermStream factory +///////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewXMLTermStream(mozIXMLTermStream** aXMLTermStream) +{ + NS_PRECONDITION(aXMLTermStream != nsnull, "null ptr"); + if (!aXMLTermStream) + return NS_ERROR_NULL_POINTER; + + *aXMLTermStream = new mozXMLTermStream(); + if (! *aXMLTermStream) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aXMLTermStream); + return NS_OK; +} + + +///////////////////////////////////////////////////////////////////////// +// mozXMLTermStream implementation +///////////////////////////////////////////////////////////////////////// + +static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); + +mozXMLTermStream::mozXMLTermStream() : + mUTF8Buffer(""), + mUTF8Offset(0), + mMaxResizeHeight(0), + mDOMWindow( nsnull ), + mDOMIFrameElement( nsnull ), + mContext( nsnull ), + mLoadGroup( nsnull ), + mChannel( nsnull ), + mStreamListener( nsnull ) +{ + NS_INIT_REFCNT(); +} + + +mozXMLTermStream::~mozXMLTermStream() +{ +} + + +// Implement AddRef and Release +NS_IMPL_ADDREF(mozXMLTermStream) +NS_IMPL_RELEASE(mozXMLTermStream) + +NS_IMETHODIMP +mozXMLTermStream::QueryInterface(REFNSIID aIID,void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if ( aIID.Equals(NS_GET_IID(nsISupports))) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(mozIXMLTermStream*,this)); + + } else if(aIID.Equals(NS_GET_IID(nsIBaseStream))) { + *aInstancePtr = NS_STATIC_CAST(nsIBaseStream*,this); + + } else if(aIID.Equals(NS_GET_IID(nsIInputStream))) { + *aInstancePtr = NS_STATIC_CAST(nsIInputStream*,this); + + } else if(aIID.Equals(NS_GET_IID(mozIXMLTermStream))) { + *aInstancePtr = NS_STATIC_CAST(mozIXMLTermStream*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + XMLT_LOG(mozXMLTermStream::QueryInterface,20,("mRefCnt = %d\n", mRefCnt)); + + return NS_OK; +} + + +// mozIXMLTermStream interface + +/** Open stream in specified frame, or in current frame if frameName is null + * @param aDOMWindow parent window + * @param frameName name of child frame in which to display stream, or null + * to display in parent window + * @param contentURL URL of stream content + * @param contentType MIME type of stream content + * @param maxResizeHeight maximum resize height (0=> do not resize) + * @return NS_OK on success + */ +NS_IMETHODIMP mozXMLTermStream::Open(nsIDOMWindow* aDOMWindow, + const char* frameName, + const char* contentURL, + const char* contentType, + PRInt32 maxResizeHeight) +{ + nsresult result; + + XMLT_LOG(mozXMLTermStream::Open,20,("contentURL=%s, contentType=%s\n", + contentURL, contentType)); + + mMaxResizeHeight = maxResizeHeight; + + if (frameName && (strlen(frameName) > 0)) { + // Open stream in named subframe of current frame + XMLT_LOG(mozXMLTermStream::Open,22,("frameName=%s\n", frameName)); + + nsAutoString innerFrameName = frameName; + + // Get DOM IFRAME element + nsCOMPtr domDoc; + result = aDOMWindow->GetDocument(getter_AddRefs(domDoc)); + if (NS_FAILED(result) || !domDoc) + return NS_ERROR_FAILURE; + + nsCOMPtr domHTMLDoc = do_QueryInterface(domDoc); + if (!domHTMLDoc) + return NS_ERROR_FAILURE; + + nsCOMPtr nodeList; + result = domHTMLDoc->GetElementsByName(innerFrameName, + getter_AddRefs(nodeList)); + if (NS_FAILED(result) || !nodeList) + return NS_ERROR_FAILURE; + + PRUint32 count; + nodeList->GetLength(&count); + PR_ASSERT(count==1); + + nsCOMPtr domNode; + result = nodeList->Item(0, getter_AddRefs(domNode)); + if (NS_FAILED(result) || !domNode) + return NS_ERROR_FAILURE; + + mDOMIFrameElement = do_QueryInterface(domNode); + if (!mDOMIFrameElement) + return NS_ERROR_FAILURE; + + // Ensure that it is indeed an IFRAME element + nsAutoString tagName; + result = mDOMIFrameElement->GetTagName(tagName); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + if (!tagName.EqualsIgnoreCase("iframe")) + return NS_ERROR_FAILURE; + + if (mMaxResizeHeight > 0) { + // Set initial IFRAME size to be as wide as the window, but very short + nsAutoString attWidth = "width"; + nsAutoString valWidth = "100%"; + mDOMIFrameElement->SetAttribute(attWidth,valWidth); + + nsAutoString attHeight = "height"; + nsAutoString valHeight = "10"; + mDOMIFrameElement->SetAttribute(attHeight,valHeight); + } + + // Get inner DOM window by looking up the frames list + nsCOMPtr innerDOMWindow; + result = mozXMLTermUtils::GetInnerDOMWindow(aDOMWindow, innerFrameName, + getter_AddRefs(innerDOMWindow)); + if (NS_FAILED(result) || !innerDOMWindow) + return NS_ERROR_FAILURE; + + mDOMWindow = innerDOMWindow; + + } else { + // Open stream in current frame + mDOMIFrameElement = nsnull; + mDOMWindow = aDOMWindow; + } + + // Get webshell for DOM window + nsCOMPtr webShell; + result = mozXMLTermUtils::ConvertDOMWindowToWebShell(mDOMWindow, + getter_AddRefs(webShell)); + if (NS_FAILED(result) || !webShell) + return NS_ERROR_FAILURE; + + NS_WITH_SERVICE(nsIIOService, ioService, kIOServiceCID, &result); + if (NS_FAILED(result)) + return result; + + nsCOMPtr inputStream = this; + + nsCOMPtr uri; + result = NS_NewURI(getter_AddRefs(uri), contentURL, nsnull); + if (NS_FAILED(result)) + return result; + + result = NS_NewLoadGroup(nsnull, nsnull, nsnull, getter_AddRefs(mLoadGroup)); + if (NS_FAILED(result)) + return result; + + PRInt32 contentLength = 1024; // ??? What's this length + result = ioService->NewInputStreamChannel(uri, contentType, contentLength, + inputStream, mLoadGroup, nsnull, + getter_AddRefs(mChannel)); + if (NS_FAILED(result)) + return result; + + // Determine Class ID for viewing specified mimetype + nsCID classID; + static const char command[] = "view"; + nsCAutoString progID = NS_DOCUMENT_LOADER_FACTORY_PROGID_PREFIX; + progID += command; + progID += "/"; + progID += contentType; + + result = nsComponentManager::ProgIDToCLSID(progID.GetBuffer(), + &classID); + if (NS_FAILED(result)) + return result; + + nsCOMPtr docLoaderFactory; + result = nsComponentManager::CreateInstance(classID, nsnull, + NS_GET_IID(nsIDocumentLoaderFactory), + getter_AddRefs(docLoaderFactory)); + if (NS_FAILED(result)) + return result; + + nsCOMPtr contentViewer; + result = docLoaderFactory->CreateInstance(command, + mChannel, + mLoadGroup, + contentType, + webShell, + nsnull, + getter_AddRefs(mStreamListener), + getter_AddRefs(contentViewer) ); + if (NS_FAILED(result)) + return result; + + nsCOMPtr contViewContainer = + do_QueryInterface(webShell); + result = contentViewer->SetContainer(contViewContainer); + if (NS_FAILED(result)) + return result; + + result = webShell->Embed(contentViewer, command, (nsISupports*) nsnull); + if (NS_FAILED(result)) + return result; + + result = mStreamListener->OnStartRequest(mChannel, mContext); + if (NS_FAILED(result)) + return result; + + XMLT_LOG(mozXMLTermStream::Open,21,("returning\n")); + + return NS_OK; +} + + +// nsIBaseStream interface +NS_IMETHODIMP mozXMLTermStream::Close(void) +{ + nsresult result; + + XMLT_LOG(mozXMLTermStream::Close,20,("\n")); + + mUTF8Buffer = ""; + mUTF8Offset = 0; + + PRUint32 sourceOffset = 0; + PRUint32 count = 0; + result = mStreamListener->OnDataAvailable(mChannel, mContext, + this, sourceOffset, count); + if (NS_FAILED(result)) + return result; + + nsresult status = NS_OK; + nsAutoString errorMsg = ""; + result = mStreamListener->OnStopRequest(mChannel, mContext, + status, errorMsg.GetUnicode()); + if (NS_FAILED(result)) + return result; + + if (mMaxResizeHeight && mDOMIFrameElement) { + // Size frame to content + result = SizeToContentHeight(mMaxResizeHeight); + } + mMaxResizeHeight = 0; + + // Release interfaces etc + mDOMWindow = nsnull; + mDOMIFrameElement = nsnull; + mContext = nsnull; + mLoadGroup = nsnull; + mChannel = nsnull; + mStreamListener = nsnull; + + return NS_OK; +} + + +/** Adjusts height of frame displaying stream to fit content + * @param maxHeight maximum height of resized frame (pixels) + * (zero value implies no maximum) + */ +NS_IMETHODIMP mozXMLTermStream::SizeToContentHeight(PRInt32 maxHeight) +{ + nsresult result; + + // Get webshell + nsCOMPtr webShell; + result = mozXMLTermUtils::ConvertDOMWindowToWebShell(mDOMWindow, + getter_AddRefs(webShell)); + if (NS_FAILED(result) || !webShell) + return NS_ERROR_FAILURE; + + // Get pres context + nsCOMPtr presContext; + result = mozXMLTermUtils::GetWebShellPresContext(webShell, + getter_AddRefs(presContext)); + if (NS_FAILED(result) || !presContext) + return NS_ERROR_FAILURE; + + // Get scrollable view + nsCOMPtr scrollableView; + result = mozXMLTermUtils::GetPresContextScrollableView(presContext, + getter_AddRefs(scrollableView)); + if (NS_FAILED(result) || !scrollableView) + return NS_ERROR_FAILURE; + + // Get device context + nsCOMPtr deviceContext; + result = mozXMLTermUtils::GetPresContextDeviceContext(presContext, + getter_AddRefs(deviceContext)); + if (NS_FAILED(result) || !deviceContext) + return NS_ERROR_FAILURE; + + // Determine twips to pixels conversion factor + float pixelScale; + presContext->GetTwipsToPixels(&pixelScale); + + // Get scrollbar dimensions in pixels + float sbWidth, sbHeight; + deviceContext->GetScrollBarDimensions(sbWidth, sbHeight); + PRInt32 scrollBarWidth = PRInt32(sbWidth*pixelScale); + PRInt32 scrollBarHeight = PRInt32(sbHeight*pixelScale); + + // Determine webshell size in pixels + PRInt32 shellX, shellY, shellWidth, shellHeight; + result = webShell->GetBounds(shellX, shellY, shellWidth, shellHeight); + + // Determine page size in pixels + nscoord contX, contY; + scrollableView->GetContainerSize(&contX, &contY); + + PRInt32 pageWidth, pageHeight; + pageWidth = PRInt32((float)contX*pixelScale); + pageHeight = PRInt32((float)contY*pixelScale); + + printf("mozXMLTermStream::SizeToContentHeight: scrollbar %d, %d\n", + scrollBarWidth, scrollBarHeight); + + printf("mozXMLTermStream::SizeToContentHeight: shell %d, %d\n", + shellWidth, shellHeight); + + printf("mozXMLTermStream::SizeToContentHeight: page %d, %d, %e\n", + pageWidth, pageHeight, pixelScale); + + if ((pageHeight > shellHeight) || (pageWidth > shellWidth)) { + // Page larger than webshell + nsAutoString attHeight = "height"; + nsAutoString attWidth = "width"; + nsAutoString attValue = ""; + + PRInt32 newPageHeight = pageHeight; + PRInt32 excessWidth = (pageWidth+scrollBarWidth - shellWidth); + + printf("mozXMLTermStream::SizeToContentHeight: excessWidth %d\n", + excessWidth); + + if (excessWidth > 0) { + // Widen IFRAME beyond page width by scrollbar width + attValue = ""; + attValue.Append(shellWidth+scrollBarWidth); + mDOMIFrameElement->SetAttribute(attWidth,attValue); + + // Recompute page dimensions + scrollableView->GetContainerSize(&contX, &contY); + pageWidth = PRInt32((float)contX*pixelScale); + pageHeight = PRInt32((float)contY*pixelScale); + + newPageHeight = pageHeight; + if (excessWidth > scrollBarWidth) + newPageHeight += scrollBarHeight; + + printf("mozXMLTermStream::SizeToContentHeight: page2 %d, %d, %d\n", + pageWidth, pageHeight, newPageHeight); + + // Reset IFRAME width + attValue = ""; + attValue.Append(shellWidth); + mDOMIFrameElement->SetAttribute(attWidth,attValue); + } + + // Resize IFRAME height to match page height (subject to a maximum) + if (newPageHeight > maxHeight) newPageHeight = maxHeight; + attValue = ""; + attValue.Append(newPageHeight); + mDOMIFrameElement->SetAttribute(attHeight,attValue); + } + + return NS_OK; +} + + +// nsIInputStream interface +NS_IMETHODIMP mozXMLTermStream::Available(PRUint32 *_retval) +{ + if (!_retval) + return NS_ERROR_NULL_POINTER; + + *_retval = mUTF8Buffer.Length() - mUTF8Offset; + + XMLT_LOG(mozXMLTermStream::Available,60,("retval=%d\n", *_retval)); + + return NS_OK; +} + + +NS_IMETHODIMP mozXMLTermStream::Read(char* buf, PRUint32 count, + PRUint32* _retval) +{ + XMLT_LOG(mozXMLTermStream::Read,60,("count=%d\n", count)); + + if (!_retval) + return NS_ERROR_NULL_POINTER; + + PR_ASSERT(mUTF8Buffer.Length() >= mUTF8Offset); + + PRUint32 remCount = mUTF8Buffer.Length() - mUTF8Offset; + + if (remCount == 0) { + // Empty buffer + *_retval = 0; + return NS_OK; + } + + if (count >= remCount) { + // Return entire remaining buffer + *_retval = remCount; + + } else { + // Return only portion of buffer + *_retval = count; + } + + // Copy portion of string + mUTF8Buffer.ToCString(buf, *_retval, mUTF8Offset); + + mUTF8Offset += *_retval; + + XMLT_LOG(mozXMLTermStream::Read,61,("*retval=%d\n", *_retval)); + + return NS_OK; +} + + +/** Write Unicode string to stream (blocks until write is completed) + * @param buf string to write + * @return NS_OK on success + */ +NS_IMETHODIMP mozXMLTermStream::Write(const PRUnichar* buf) +{ + nsresult result; + + XMLT_LOG(mozXMLTermStream::Write,50,("\n")); + + if (!buf) + return NS_ERROR_FAILURE; + + nsAutoString strBuf ( buf ); + + // Convert Unicode string to UTF8 and store in buffer + char* utf8Str = strBuf.ToNewUTF8String(); + mUTF8Buffer = utf8Str; + nsAllocator::Free(utf8Str); + + mUTF8Offset = 0; + + PRUint32 sourceOffset = 0; + + while (mUTF8Offset < mUTF8Buffer.Length()) { + PRUint32 remCount = mUTF8Buffer.Length() - mUTF8Offset; + result = mStreamListener->OnDataAvailable(mChannel, mContext, + this, sourceOffset, remCount); + if (NS_FAILED(result)) + return result; + } + + XMLT_LOG(mozXMLTermStream::Write,51,("returning mUTF8Offset=%d\n", + mUTF8Offset)); + + return NS_OK; +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermStream.h b/mozilla/extensions/xmlterm/base/mozXMLTermStream.h new file mode 100644 index 00000000000..9fcfcad8f61 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermStream.h @@ -0,0 +1,96 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermStream.h: declaration of mozXMLTermStream +// which implements the mozIXMLTermStream interface +// to display HTML/XML streams as documents + +#include "nscore.h" +#include "nspr.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "mozXMLT.h" +#include "mozIXMLTermStream.h" + +class mozXMLTermStream : public mozIXMLTermStream +{ + public: + + mozXMLTermStream(); + virtual ~mozXMLTermStream(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIInputStream interface + NS_IMETHOD Close(void); + + NS_IMETHOD Available(PRUint32 *_retval); + NS_IMETHOD Read(char * buf, PRUint32 count, PRUint32 *_retval); + + // mozIXMLTermStream interface + + // Open stream in specified frame, or in current frame if frameName is null + NS_IMETHOD Open(nsIDOMWindow* aDOMWindow, + const char* frameName, + const char* contentURL, + const char* contentType, + PRInt32 maxResizeHeight); + + // Write Unicode string to stream + NS_IMETHOD Write(const PRUnichar* buf); + + protected: + + /** Adjusts height of frame displaying stream to fit content + * @param maxHeight maximum height of resized frame (pixels) + * (zero value implies no maximum) + */ + NS_IMETHOD SizeToContentHeight(PRInt32 maxHeight); + + /** UTF8 data buffer to hold to be read by rendering engine */ + nsCString mUTF8Buffer; + + /** offset at which to start reading the UTF8 data buffer */ + PRInt32 mUTF8Offset; + + /** maximum frame height for resizing */ + PRInt32 mMaxResizeHeight; + + /** DOM window in which to display stream */ + nsCOMPtr mDOMWindow; + + /** Frame element in which to display stream */ + nsCOMPtr mDOMIFrameElement; + + /** Context for stream display (what's this??) */ + nsCOMPtr mContext; + + /** Load group for stream display (what's this??) */ + nsCOMPtr mLoadGroup; + + /** Channel for stream display (what's this??) */ + nsCOMPtr mChannel; + + /** Stream listener object */ + nsCOMPtr mStreamListener; +}; + diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermUtils.cpp b/mozilla/extensions/xmlterm/base/mozXMLTermUtils.cpp new file mode 100644 index 00000000000..fa7336c119a --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermUtils.cpp @@ -0,0 +1,454 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermUtils.cpp: XMLTerm utilities implementation + +#include "nscore.h" +#include "nspr.h" +#include "prlog.h" + +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "nsIContentViewer.h" +#include "nsIDocumentViewer.h" +#include "nsIPresContext.h" +#include "nsIPresShell.h" +#include "nsIDeviceContext.h" + +#include "nsIPrincipal.h" +#include "nsIScriptContext.h" +#include "nsIScriptContextOwner.h" +#include "nsIScriptGlobalObject.h" +#include "nsIDOMWindowCollection.h" +#include "nsIDocument.h" + +#include "mozXMLT.h" +#include "mozXMLTermUtils.h" + +///////////////////////////////////////////////////////////////////////// + +/** Gets presentation context for web shell + * @param aWebShell web shell + * @param aPresContext returned presentation context + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::GetWebShellPresContext(nsIWebShell* aWebShell, + nsIPresContext** aPresContext) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::GetWebShellPresContext,30,("\n")); + + if (!aPresContext) + return NS_ERROR_FAILURE; + + *aPresContext = nsnull; + + nsCOMPtr contViewer; + result = aWebShell->GetContentViewer(getter_AddRefs(contViewer)); + if (NS_FAILED(result) || !contViewer) + return NS_ERROR_FAILURE; + + nsCOMPtr docViewer; + result = contViewer->QueryInterface(NS_GET_IID(nsIDocumentViewer), + (void**)getter_AddRefs(docViewer)); + if (NS_FAILED(result) || !docViewer) + return NS_ERROR_FAILURE; + + nsCOMPtr presContext; + result = docViewer->GetPresContext(*getter_AddRefs(presContext)); + if (NS_FAILED(result) || !presContext) + return NS_ERROR_FAILURE; + + *aPresContext = presContext.get(); + NS_ADDREF(*aPresContext); + + return NS_OK; +} + + +/** Gets DOM document for web shell + * @param aWebShell web shell + * @param aDOMDocument returned DOM document + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::GetWebShellDOMDocument(nsIWebShell* aWebShell, + nsIDOMDocument** aDOMDocument) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::GetWebShellDOMDocument,30,("\n")); + + if (!aDOMDocument) + return NS_ERROR_FAILURE; + + *aDOMDocument = nsnull; + + nsCOMPtr contViewer; + result = aWebShell->GetContentViewer(getter_AddRefs(contViewer)); + if (NS_FAILED(result) || !contViewer) + return NS_ERROR_FAILURE; + + nsCOMPtr docViewer; + result = contViewer->QueryInterface(NS_GET_IID(nsIDocumentViewer), + (void**)getter_AddRefs(docViewer)); + if (NS_FAILED(result) || !docViewer) + return NS_ERROR_FAILURE; + + nsCOMPtr document; + result = docViewer->GetDocument(*getter_AddRefs(document)); + + if (NS_FAILED(result) || !document) + return NS_ERROR_FAILURE; + + nsCOMPtr domDocument = do_QueryInterface(document); + if (!domDocument) + return NS_ERROR_FAILURE; + + *aDOMDocument = domDocument.get(); + NS_ADDREF(*aDOMDocument); + + return NS_OK; +} + + +/** Gets DOM window for web shell + * @param aWebShell web shell + * @param aDOMWindow returned DOM window (frame) + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::ConvertWebShellToDOMWindow(nsIWebShell* aWebShell, + nsIDOMWindow** aDOMWindow) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::ConvertWebShellToDOMWindow,30,("\n")); + + if (!aDOMWindow) + return NS_ERROR_FAILURE; + + *aDOMWindow = nsnull; + + nsCOMPtr scriptContextOwner = + do_QueryInterface(aWebShell); + if (!scriptContextOwner) + return NS_ERROR_FAILURE; + + nsCOMPtr scriptGlobalObject; + result = scriptContextOwner->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); + + if (NS_FAILED(result) || !scriptGlobalObject) + return NS_ERROR_FAILURE; + + nsCOMPtr domWindow = do_QueryInterface(scriptGlobalObject); + if (!domWindow) + return NS_ERROR_FAILURE; + + *aDOMWindow = domWindow.get(); + NS_ADDREF(*aDOMWindow); + + return NS_OK; +} + + +/** Gets web shell for DOM window + * @param aDOMWindow DOM window (frame) + * @param aWebShell returned web shell + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::ConvertDOMWindowToWebShell(nsIDOMWindow* aDOMWindow, + nsIWebShell** aWebShell) +{ + XMLT_LOG(mozXMLTermUtils::ConvertDOMWindowToWebShell,30,("\n")); + + nsCOMPtr globalObject = do_QueryInterface(aDOMWindow); + if (!globalObject) + return NS_ERROR_FAILURE; + + globalObject->GetWebShell(aWebShell); + + if (!*aWebShell) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Locates named inner DOM window (frame) inside outer DOM window + * @param outerDOMWindow outer DOM window (frame) + * @param innerFrameName name of inner frame to be returned + * @param innerDOMWindow returned inner DOM window (frame) + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::GetInnerDOMWindow(nsIDOMWindow* outerDOMWindow, + const nsString& innerFrameName, + nsIDOMWindow** innerDOMWindow) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::GetInnerDOMWindow,30,("\n")); + + nsCOMPtr innerDOMWindowList; + result = outerDOMWindow->GetFrames(getter_AddRefs(innerDOMWindowList)); + if (NS_FAILED(result) || !innerDOMWindowList) + return NS_ERROR_FAILURE; + + PRUint32 frameCount = 0; + result = innerDOMWindowList->GetLength(&frameCount); + XMLT_LOG(mozXMLTermUtils::GetInnerDOMWindow,31,("frameCount=%d\n", + frameCount)); + + result = innerDOMWindowList->NamedItem(innerFrameName, innerDOMWindow); + if (NS_FAILED(result) || !*innerDOMWindow) + return NS_ERROR_FAILURE; + + return NS_OK; +} + + +/** Gets the scrollable view for presentation context + * @param aPresContext presentation context + * @param aScrollableView returned scrollable view + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::GetPresContextScrollableView(nsIPresContext* aPresContext, + nsIScrollableView** aScrollableView) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::GetPresContextScrollableView,30,("\n")); + + if (!aScrollableView) + return NS_ERROR_FAILURE; + + *aScrollableView = nsnull; + + nsCOMPtr presShell; + result = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(result) || !presShell) + return NS_ERROR_FAILURE; + + nsCOMPtr viewManager; + result = presShell->GetViewManager(getter_AddRefs(viewManager)); + if (NS_FAILED(result) || !viewManager) + return NS_ERROR_FAILURE; + + return viewManager->GetRootScrollableView(aScrollableView); +} + + +/** Gets the device context for presentation context + * @param aPresContext presentation context + * @param aDeviceContext returned device context + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::GetPresContextDeviceContext(nsIPresContext* aPresContext, + nsIDeviceContext** aDeviceContext) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::GetPresContextScrollableView,30,("\n")); + + if (!aDeviceContext) + return NS_ERROR_FAILURE; + + *aDeviceContext = nsnull; + + nsCOMPtr presShell; + result = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(result) || !presShell) + return NS_ERROR_FAILURE; + + nsCOMPtr viewManager; + result = presShell->GetViewManager(getter_AddRefs(viewManager)); + if (NS_FAILED(result) || !viewManager) + return NS_ERROR_FAILURE; + + nsCOMPtr deviceContext; + result = viewManager->GetDeviceContext(*getter_AddRefs(deviceContext)); + if (NS_FAILED(result) || !deviceContext) + return NS_ERROR_FAILURE; + + *aDeviceContext = deviceContext.get(); + NS_ADDREF(*aDeviceContext); + + return NS_OK; +} + + +/** Gets the script context for document + * @param aDOMDocument document providing context + * @param aScriptContext returned script context + * @return NS_OK on success + */ +NS_EXPORT nsresult +mozXMLTermUtils::GetScriptContext(nsIDOMDocument* aDOMDocument, + nsIScriptContext** aScriptContext) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::GetScriptContext,20,("\n")); + + nsCOMPtr doc ( do_QueryInterface(aDOMDocument) ); + if (!doc) + return NS_ERROR_FAILURE; + + nsCOMPtr scriptGlobalObject; + result = doc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); + + if (NS_FAILED(result) || !scriptGlobalObject) + return NS_ERROR_FAILURE; + + return scriptGlobalObject->GetContext(aScriptContext); +} + + +/** Executes script in specified document's context. + * @param aDOMDocument document providing context for script execution + * @param aScript string to be executed + * @param aOutput output string produced by script execution + * @return NS_OK if script was valid and got executed properly + */ +NS_EXPORT nsresult +mozXMLTermUtils::ExecuteScript(nsIDOMDocument* aDOMDocument, + const nsString& aScript, + nsString& aOutput) +{ + nsresult result; + + XMLT_LOG(mozXMLTermUtils::ExecuteScript,20,("\n")); + + // Get document principal + nsCOMPtr doc = do_QueryInterface(aDOMDocument); + if (!doc) + return NS_ERROR_FAILURE; + + nsCOMPtr docPrincipal=dont_AddRef(doc->GetDocumentPrincipal()); + + // Get document script context + nsCOMPtr scriptContext; + result = GetScriptContext(aDOMDocument, getter_AddRefs(scriptContext)); + if (NS_FAILED(result) || !scriptContext) + return NS_ERROR_FAILURE; + + // Execute script + PRBool isUndefined = PR_FALSE; + nsString outputString = ""; + const char* URL = ""; + const char* version = ""; + result = scriptContext-> EvaluateString(aScript, (void *) nsnull, + docPrincipal, URL, 0, version, + aOutput, &isUndefined); + return result; +} + + +/** Returns a timestamp string containing the local time, if at least + * deltaSec seconds have elapsed since the last timestamp. Otherwise, + * a null string is returned. + * @param deltaSec minimum elapsed seconds since last timestamp (>=0) + * @param lastTime in/out parameter containing time of last timestamp + * @param aTimeStamp returned timestamp string + * @return NS_OK on success + */ +NS_IMETHODIMP mozXMLTermUtils::TimeStamp(PRInt32 deltaSec, PRTime& lastTime, + nsString& aTimeStamp) +{ + static const PRInt32 DATE_LEN = 19; + PRTime deltaTime ; + char dateStr[DATE_LEN+1]; + PRTime curTime, difTime; + + curTime = PR_Now(); + LL_SUB(difTime, curTime, lastTime); + + LL_I2L(deltaTime, deltaSec*1000000); + if (LL_CMP(difTime, <, deltaTime)) { + // Not enough time has elapsed for a new time stamp + aTimeStamp = ""; + return NS_OK; + } + + lastTime = curTime; + + // Current local time + PRExplodedTime localTime; + PR_ExplodeTime(curTime, PR_LocalTimeParameters, &localTime); + + PRInt32 nWritten = PR_snprintf(dateStr, DATE_LEN+1, + "%02d:%02d:%02d %02d/%02d/%04d", + localTime.tm_hour, localTime.tm_min, localTime.tm_sec, + localTime.tm_mday, localTime.tm_month+1, localTime.tm_year); + + if (nWritten != DATE_LEN) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozXMLTermUtils::LocalTime,99,("localTime=%s\n", dateStr)); + + aTimeStamp = dateStr; + return NS_OK; +} + + +/** Returns a string containing a 11-digit random cookie based upon the + * current local time and the elapsed execution of the program. + * @param aCookie returned cookie string + * @return NS_OK on success + */ +NS_IMETHODIMP mozXMLTermUtils::RandomCookie(nsString& aCookie) +{ + // Current local time + PRExplodedTime localTime; + PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &localTime); + + PRInt32 randomNumberA = localTime.tm_sec*1000000+localTime.tm_usec; + PRIntervalTime randomNumberB = PR_IntervalNow(); + + XMLT_LOG(mozXMLTermUtils::RandomCookie,30,("ranA=0x%x, ranB=0x%x\n", + randomNumberA, randomNumberB)); + PR_ASSERT(randomNumberA >= 0); + PR_ASSERT(randomNumberB >= 0); + + static const char cookieDigits[17] = "0123456789abcdef"; + char cookie[12]; + int j; + + for (j=0; j<6; j++) { + cookie[j] = cookieDigits[randomNumberA%16]; + randomNumberA = randomNumberA/16; + } + for (j=6; j<11; j++) { + cookie[j] = cookieDigits[randomNumberB%16]; + randomNumberB = randomNumberB/16; + } + cookie[11] = '\0'; + + aCookie = cookie; + + return NS_OK; +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTermUtils.h b/mozilla/extensions/xmlterm/base/mozXMLTermUtils.h new file mode 100644 index 00000000000..d1bde6ee356 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTermUtils.h @@ -0,0 +1,145 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTermUtils.h: XMLTerm utilities header + +#ifndef _MOZXMLTERMUTILS_H + +#define _MOZXMLTERMUTILS_H 1 + +#include "nscore.h" + +#include "nsString.h" + +#include "nsIWebShell.h" +#include "nsIDOMWindow.h" +#include "nsIDOMDocument.h" + +class mozXMLTermUtils +{ + public: + /** Gets presentation context for web shell + * @param aWebShell web shell + * @param aPresContext returned presentation context + * @return NS_OK on success + */ + static NS_EXPORT nsresult + GetWebShellPresContext(nsIWebShell* aWebShell, + nsIPresContext** aPresContext); + + /** Gets DOM document for web shell + * @param aWebShell web shell + * @param aDOMDocument returned DOM document + * @return NS_OK on success + */ + static NS_EXPORT nsresult + GetWebShellDOMDocument(nsIWebShell* aWebShell, + nsIDOMDocument** aDOMDocument); + + /** Gets DOM window for web shell + * @param aWebShell web shell + * @param aDOMWindow returned DOM window (frame) + * @return NS_OK on success + */ + static NS_EXPORT nsresult + ConvertWebShellToDOMWindow(nsIWebShell* aWebShell, + nsIDOMWindow** aDOMWindow); + + /** Gets web shell for DOM window + * @param aDOMWindow DOM window (frame) + * @param aWebShell returned web shell + * @return NS_OK on success + */ + static NS_EXPORT nsresult + ConvertDOMWindowToWebShell(nsIDOMWindow* aDOMWindow, + nsIWebShell** aWebShell); + + /** Locates named inner DOM window (frame) inside outer DOM window + * @param outerDOMWindow outer DOM window (frame) + * @param innerFrameName name of inner frame to be returned + * @param innerDOMWindow returned inner DOM window (frame) + * @return NS_OK on success + */ + static NS_EXPORT nsresult + GetInnerDOMWindow(nsIDOMWindow* outerDOMWindow, + const nsString& innerFrameName, + nsIDOMWindow** innerDOMWindow); + + /** Gets the scrollable view for presentation context + * @param aPresContext presentation context + * @param aScrollableView returned scrollable view + * @return NS_OK on success + */ + static NS_EXPORT nsresult + GetPresContextScrollableView(nsIPresContext* aPresContext, + nsIScrollableView** aScrollableView); + + /** Gets the device context for presentation context + * @param aPresContext presentation context + * @param aDeviceContext returned device context + * @return NS_OK on success + */ + static NS_EXPORT nsresult + GetPresContextDeviceContext(nsIPresContext* aPresContext, + nsIDeviceContext** aDeviceContext); + + /** Gets the script context for document + * @param aDOMDocument document providing context + * @param aScriptContext returned script context + * @return NS_OK on success + */ + static NS_EXPORT nsresult + GetScriptContext(nsIDOMDocument* aDOMDocument, + nsIScriptContext** aScriptContext); + + /** Executes script in specified document's context. + * @param aDOMDocument document providing context for script execution + * @param aScript string to be executed + * @param aOutput output string produced by script execution + * @return NS_OK if script was valid and got executed properly + */ + static NS_EXPORT nsresult + ExecuteScript(nsIDOMDocument* aDOMDocument, + const nsString& aScript, + nsString& aOutput); + + /** Returns a timestamp string containing the local time, if at least + * deltaSec seconds have elapsed since the last timestamp. Otherwise, + * a null string is returned. + * @param deltaSec minimum elapsed seconds since last timestamp (>=0) + * @param lastTime in/out parameter containing time of last timestamp + * @param aTimeStamp returned timestamp string + * @return NS_OK on success + */ + static NS_EXPORT nsresult + TimeStamp(PRInt32 deltaSec, PRTime& lastTime, + nsString& aTimeStamp); + + /** Returns a string containing a 11-digit random cookie based upon the + * current local time and the elapsed execution of the program. + * @param aCookie returned cookie string + * @return NS_OK on success + */ + static NS_EXPORT nsresult + RandomCookie(nsString& aCookie); + +}; + +#endif /* _MOZXMLTERMUTILS_H */ diff --git a/mozilla/extensions/xmlterm/base/mozXMLTerminal.cpp b/mozilla/extensions/xmlterm/base/mozXMLTerminal.cpp new file mode 100644 index 00000000000..5fc8b7b6812 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTerminal.cpp @@ -0,0 +1,770 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTerminal.cpp: implementation of mozIXMLTerminal interface +// to manage all XMLTerm operations. +// Creates a new mozXMLTermSession object to manage session input/output. +// Creates a mozLineTermAux object to access LineTerm operations. +// Creates key/text/mouse/drag listener objects to handle user events. + +#include "nscore.h" +#include "nspr.h" + +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "nsIDocument.h" +#include "nsIDOMHTMLDocument.h" +#include "nsIDocumentViewer.h" +#include "nsIDocumentLoaderObserver.h" +#include "nsIObserver.h" + +#include "nsIPresContext.h" + +#include "nsIDOMEventReceiver.h" +#include "nsIDOMEventListener.h" + +#include "nsIServiceManager.h" +#include "nsISupportsPrimitives.h" + +#include "nsWidgetsCID.h" +#include "nsIClipboard.h" +#include "nsITransferable.h" + +#include "mozXMLT.h" +#include "mozXMLTermUtils.h" +#include "mozXMLTerminal.h" + +//////////////////////////////////////////////////////////////////////// + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +static NS_DEFINE_IID(kIXMLTerminalIID, MOZIXMLTERMINAL_IID); +static NS_DEFINE_IID(kXMLTerminalCID, MOZXMLTERMINAL_CID); + +static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID); +static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID); + +///////////////////////////////////////////////////////////////////////// +// mozXMLTerminal factory +///////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewXMLTerminal(mozIXMLTerminal** aXMLTerminal) +{ + NS_PRECONDITION(aXMLTerminal != nsnull, "null ptr"); + if (!aXMLTerminal) + return NS_ERROR_NULL_POINTER; + + *aXMLTerminal = new mozXMLTerminal(); + if (! *aXMLTerminal) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aXMLTerminal); + return NS_OK; +} + + +///////////////////////////////////////////////////////////////////////// +// mozXMLTerminal implementation +///////////////////////////////////////////////////////////////////////// +mozXMLTerminal::mozXMLTerminal() : + mInitialized(PR_FALSE), + + mCookie(""), + + mCommand(""), + mPromptExpr(""), + mFirstInput(""), + + mXMLTermShell(nsnull), + mWebShell(nsnull), + mPresShell(nsnull), + mDOMDocument(nsnull), + + mXMLTermSession(nsnull), + + mLineTermAux(nsnull), + + mKeyListener(nsnull), + mTextListener(nsnull), + mMouseListener(nsnull), + mDragListener(nsnull) +{ + NS_INIT_REFCNT(); +} + + +mozXMLTerminal::~mozXMLTerminal() +{ + if (mInitialized) { + Finalize(); + } +} + + +// Implement AddRef and Release +NS_IMPL_ADDREF(mozXMLTerminal) +NS_IMPL_RELEASE(mozXMLTerminal) + + +NS_IMETHODIMP +mozXMLTerminal::QueryInterface(REFNSIID aIID,void** aInstancePtr) +{ + if (aInstancePtr == NULL) { + return NS_ERROR_NULL_POINTER; + } + + // Always NULL result, in case of failure + *aInstancePtr = NULL; + + if ( aIID.Equals(kISupportsIID)) { + *aInstancePtr = NS_STATIC_CAST(nsISupports*, + NS_STATIC_CAST(mozIXMLTerminal*,this)); + + } else if ( aIID.Equals(mozIXMLTerminal::GetIID()) ) { + *aInstancePtr = NS_STATIC_CAST(mozIXMLTerminal*,this); + + } else if (aIID.Equals(nsIDocumentLoaderObserver::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIDocumentLoaderObserver*,this); + + } else if (aIID.Equals(nsIObserver::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsIObserver*,this); + + } else { + return NS_ERROR_NO_INTERFACE; + } + + NS_ADDREF_THIS(); + + XMLT_LOG(mozXMLTerminal::QueryInterface,20,("mRefCnt = %d\n", mRefCnt)); + + return NS_OK; +} + + +NS_IMETHODIMP mozXMLTerminal::GetCurrentEntryNumber(PRInt32 *aNumber) +{ + if (mXMLTermSession) { + return mXMLTermSession->GetCurrentEntryNumber(aNumber); + } else { + return NS_ERROR_FAILURE; + } +} + + +NS_IMETHODIMP mozXMLTerminal::GetHistory(PRInt32 *aHistory) +{ + if (mXMLTermSession) { + return mXMLTermSession->GetHistory(aHistory); + } else { + return NS_ERROR_FAILURE; + } +} + + +NS_IMETHODIMP mozXMLTerminal::SetHistory(PRInt32 aHistory) +{ + if (mXMLTermSession) { + return mXMLTermSession->SetHistory(aHistory); + } else { + return NS_ERROR_FAILURE; + } +} + + +NS_IMETHODIMP mozXMLTerminal::GetPrompt(PRUnichar **aPrompt) +{ + if (mXMLTermSession) { + return mXMLTermSession->GetPrompt(aPrompt); + } else { + return NS_ERROR_FAILURE; + } +} + + +NS_IMETHODIMP mozXMLTerminal::SetPrompt(const PRUnichar* aPrompt) +{ + if (mXMLTermSession) { + return mXMLTermSession->SetPrompt(aPrompt); + } else { + return NS_ERROR_FAILURE; + } +} + + +// Initialize by starting load of Init page for XMLTerm +NS_IMETHODIMP mozXMLTerminal::Init(nsIWebShell* aWebShell, + mozIXMLTermShell* aXMLTermShell, + const PRUnichar* aURL, + const PRUnichar* args) +{ + XMLT_LOG(mozXMLTerminal::Init,20,("\n")); + + if (!aWebShell) + return NS_ERROR_NULL_POINTER; + + if (mWebShell) + return NS_ERROR_ALREADY_INITIALIZED; + + mWebShell = aWebShell; // containing webshell; no addref + + mXMLTermShell = aXMLTermShell; // containing xmlterm shell; no addref + + nsresult result = NS_OK; + + // NOTE: Need to parse args string!!! + mCommand = ""; + mPromptExpr = ""; + mFirstInput = args; + + // Initialization completed + mInitialized = PR_TRUE; + + if ((aURL != nsnull) && (*aURL != 0)) { + // Load URL and activate XMLTerm after loading + XMLT_LOG(mozXMLTerminal::Init,22,("setting DocLoaderObs\n")); + + // About to create owning reference to this + result = mWebShell->SetDocLoaderObserver((nsIDocumentLoaderObserver*)this); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + XMLT_LOG(mozXMLTerminal::Init,22,("done setting DocLoaderObs\n")); + + // Load initial XMLterm background document + nsAutoString urlString(aURL); + + result = mWebShell->LoadURL(urlString.GetUnicode()); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + + } else { + // Document already loaded; activate XMLTerm + result = Activate(); + if (NS_FAILED(result)) + return NS_ERROR_FAILURE; + } + + XMLT_LOG(mozXMLTerminal::Init,21,("exiting\n")); + return result; +} + + +// De-initialize XMLTerminal +NS_IMETHODIMP mozXMLTerminal::Finalize(void) +{ + if (mXMLTermSession) { + // Finalize XMLTermSession object and delete it (it is not ref. counted) + mXMLTermSession->Finalize(); + delete mXMLTermSession; + mXMLTermSession = nsnull; + } + + if (mDOMDocument) { + // Release any event listeners for the document + nsCOMPtr eventReceiver; + nsresult result = mDOMDocument->QueryInterface(nsIDOMEventReceiver::GetIID(), getter_AddRefs(eventReceiver)); + + if (NS_SUCCEEDED(result) && eventReceiver) { + if (mKeyListener) { + eventReceiver->RemoveEventListenerByIID(mKeyListener, + nsIDOMKeyListener::GetIID()); + mKeyListener = nsnull; + } + + if (mTextListener) { + eventReceiver->RemoveEventListenerByIID(mTextListener, + nsIDOMTextListener::GetIID()); + mTextListener = nsnull; + } + + if (mMouseListener) { + eventReceiver->RemoveEventListenerByIID(mMouseListener, + nsIDOMMouseListener::GetIID()); + mMouseListener = nsnull; + } + + if (mDragListener) { + eventReceiver->RemoveEventListenerByIID(mDragListener, + nsIDOMDragListener::GetIID()); + mDragListener = nsnull; + } + } + mDOMDocument = nsnull; + } + + if (mLineTermAux) { + // Finalize and release reference to LineTerm object owned by us + mLineTermAux->CloseAux(); + mLineTermAux = nsnull; + } + + if (mWebShell) { + // Stop observing document loading + mWebShell->SetDocLoaderObserver((nsIDocumentLoaderObserver *)nsnull); + mWebShell = nsnull; + } + + mPresShell = nsnull; + mXMLTermShell = nsnull; + + mInitialized = PR_FALSE; + + return NS_OK; +} + + +/** Activates XMLterm and instantiates LineTerm; + * called at the the end of Init page loading. + */ +NS_IMETHODIMP mozXMLTerminal::Activate(void) +{ + nsresult result = NS_OK; + +#if 0 + // TEMPORARY: Testing mozIXMLTermStream + nsAutoString streamData = "Stream Title" + "" + "Stream Body " + "Clik
" +"
 
" + "
ABCD
EFGH
JKLM
" + ""; + + nsCOMPtr stream; + result = NS_NewXMLTermStream(getter_AddRefs(stream)); + if (NS_FAILED(result)) { + fprintf(stderr, "mozXMLTerminal::Activate: Failed to create stream\n"); + return result; + } + + nsCOMPtr outerDOMWindow; + result = mozXMLTermUtils::ConvertWebShellToDOMWindow(mWebShell, + getter_AddRefs(outerDOMWindow)); + + if (NS_FAILED(result) || !outerDOMWindow) + return NS_ERROR_FAILURE; + + result = stream->Open(outerDOMWindow, "iframe1", "chrome://dummy", + "text/html", 800); + if (NS_FAILED(result)) { + fprintf(stderr, "mozXMLTerminal::Activate: Failed to open stream\n"); + return result; + } + + result = stream->Write(streamData.GetUnicode()); + if (NS_FAILED(result)) { + fprintf(stderr, "mozXMLTerminal::Activate: Failed to write to stream\n"); + return result; + } + + result = stream->Close(); + if (NS_FAILED(result)) { + fprintf(stderr, "mozXMLTerminal::Activate: Failed to close stream\n"); + return result; + } + +#endif + + XMLT_LOG(mozXMLTerminal::Activate,20,("\n")); + + if (!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + PR_ASSERT(mWebShell != nsnull); + + if ((mDOMDocument != nsnull) || (mPresShell != nsnull)) + return NS_ERROR_FAILURE; + + // Get reference to DOMDocument + nsCOMPtr domDocument; + result = mozXMLTermUtils::GetWebShellDOMDocument(mWebShell, + getter_AddRefs(domDocument)); + + if (NS_FAILED(result) || !domDocument) + return NS_ERROR_FAILURE; + + // Get reference to presentation shell + if (mPresShell != nsnull) + return NS_ERROR_FAILURE; + + nsCOMPtr presContext; + result = mozXMLTermUtils::GetWebShellPresContext(mWebShell, + getter_AddRefs(presContext)); + if (NS_FAILED(result) || !presContext) + return NS_ERROR_FAILURE; + + nsCOMPtr presShell; + result = presContext->GetShell(getter_AddRefs(presShell)); + + if (NS_FAILED(result) || !presShell) + return NS_ERROR_FAILURE; + + // Save references to DOMDocument and presentation shell + // (SVN: Should these be addref'ed and released in the destructor?) + mDOMDocument = domDocument; // no addref + mPresShell = presShell; // no addref + + // Instantiate and initialize XMLTermSession object + mXMLTermSession = new mozXMLTermSession(); + + if (!mXMLTermSession) { + return NS_ERROR_OUT_OF_MEMORY; + } + + result = mXMLTermSession->Init(this, mPresShell, mDOMDocument); + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to initialize XMLTermSession\n"); + return NS_ERROR_FAILURE; + } + + + // Instantiate LineTerm + XMLT_LOG(mozXMLTerminal::Activate,22,("instantiating lineterm\n")); + result = NS_NewLineTermAux(getter_AddRefs(mLineTermAux)); + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to instantiate LineTermAux\n"); + return result; + } + + // Open LineTerm to execute command + // Non-owning reference to this; delete LineTerm before deleting self + PRInt32 options = LTERM_NOSTDERR_FLAG; + + XMLT_LOG(mozXMLTerminal::Activate,22,("Opening LineTerm\n")); + nsCOMPtr anObserver = this; +#ifdef NO_CALLBACK + anObserver = nsnull; +#endif + nsAutoString cookie; + result = mLineTermAux->OpenAux(mCommand.GetUnicode(), + mPromptExpr.GetUnicode(), + options, LTERM_DETERMINE_PROCESS, + mDOMDocument, anObserver, cookie); + + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to open LineTermAux\n"); + return result; + } + XMLT_LOG(mozXMLTerminal::Activate,22,("Opened LineTerm\n")); + + // Save cookie + mCookie = cookie; + + if (mFirstInput.Length() > 0) { + // Send first input command line + result = SendTextAux(mFirstInput); + if (NS_FAILED(result)) + return result; + } + + // Get the DOM event receiver for document + nsCOMPtr eventReceiver; + result = mDOMDocument->QueryInterface(nsIDOMEventReceiver::GetIID(), + getter_AddRefs(eventReceiver)); + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to get DOM receiver\n"); + return result; + } + + // Create a key listener + result = NS_NewXMLTermKeyListener(getter_AddRefs(mKeyListener), this); + if (NS_OK != result) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to get key listener\n"); + return result; + } + + // Register the key listener with the DOM event receiver + result = eventReceiver->AddEventListenerByIID(mKeyListener, + nsIDOMKeyListener::GetIID()); + + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to register key listener\n"); + return result; + } + + // Create a text listener + result = NS_NewXMLTermTextListener(getter_AddRefs(mTextListener), this); + if (NS_OK != result) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to get text listener\n"); + return result; + } + + // Register the text listener with the DOM event receiver + result = eventReceiver->AddEventListenerByIID(mTextListener, + nsIDOMTextListener::GetIID()); + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to register text listener\n"); + return result; + } + + // Create a mouse listener + result = NS_NewXMLTermMouseListener(getter_AddRefs(mMouseListener), this); + if (NS_OK != result) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to get mouse listener\n"); + return result; + } + + // Register the mouse listener with the DOM event receiver + result = eventReceiver->AddEventListenerByIID(mMouseListener, + nsIDOMMouseListener::GetIID()); + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to register mouse listener\n"); + return result; + } + + // Create a drag listener + result = NS_NewXMLTermDragListener(getter_AddRefs(mDragListener), this); + if (NS_OK != result) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to get drag listener\n"); + return result; + } + + // Register the drag listener with the DOM event receiver + result = eventReceiver->AddEventListenerByIID(mDragListener, + nsIDOMDragListener::GetIID()); + if (NS_FAILED(result)) { + XMLT_WARNING("mozXMLTerminal::Activate: Warning - Failed to register drag listener\n"); + return result; + } + + return NS_OK; +} + + +// Transmit string to LineTerm (use saved cookie) +NS_IMETHODIMP mozXMLTerminal::SendTextAux(const nsString& aString) +{ + return SendText(aString, mCookie.GetUnicode()); +} + + +// Transmit string to LineTerm +NS_IMETHODIMP mozXMLTerminal::SendText(const nsString& aString, + const PRUnichar* aCookie) +{ + nsresult result; + + if (!mLineTermAux) + return NS_ERROR_FAILURE; + + // Preprocess string and check if it is to be consumed + PRBool consumed = false; + result = mXMLTermSession->Preprocess(aString, consumed); + + if (!consumed) { + result = mLineTermAux->Write(aString.GetUnicode(), aCookie); + if (NS_FAILED(result)) { + // Close LineTerm + mLineTermAux->Close(aCookie); + return NS_ERROR_FAILURE; + } + } + + return NS_OK; +} + + +// Paste data from clipboard to terminal +NS_IMETHODIMP mozXMLTerminal::Paste() +{ + nsresult result; + nsAutoString pasteString; + + XMLT_LOG(mozXMLTerminal::Paste,20,("\n")); + + // Get Clipboard service + NS_WITH_SERVICE (nsIClipboard, clipboard, kCClipboardCID, &result); + if ( NS_FAILED(result) ) + return result; + + // Generic transferable for getting clipboard data + nsCOMPtr trans; + result = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, + nsITransferable::GetIID(), + (void**) getter_AddRefs(trans)); + + if (NS_FAILED(result) || !trans) + return NS_ERROR_FAILURE; + + // DataFlavors to get out of transferable + trans->AddDataFlavor(kHTMLMime); + trans->AddDataFlavor(kTextMime); + + // Get data from clipboard + result = clipboard->GetData(trans); + if (NS_FAILED(result)) + return result; + + char* bestFlavor = nsnull; + nsCOMPtr genericDataObj; + PRUint32 objLen = 0; + result = trans->GetAnyTransferData(&bestFlavor, + getter_AddRefs(genericDataObj), &objLen); + if (NS_FAILED(result)) + return result; + + nsAutoString flavor ( bestFlavor ); + + char* temCStr = flavor.ToNewCString(); + XMLT_LOG(mozXMLTerminal::Paste,20,("flavour=%s\n", temCStr)); + nsAllocator::Free(temCStr); + + if (flavor.Equals(kHTMLMime)) { + nsCOMPtr textDataObj ( do_QueryInterface(genericDataObj) ); + if (textDataObj && objLen > 0) { + PRUnichar* text = nsnull; + textDataObj->ToString ( &text ); + pasteString.SetString ( text, objLen / 2 ); + result = SendTextAux(pasteString); + } + + } else if (flavor.Equals(kTextMime)) { + nsCOMPtr textDataObj ( do_QueryInterface(genericDataObj) ); + if (textDataObj && objLen > 0) { + char* text = nsnull; + textDataObj->ToString ( &text ); + pasteString.SetString ( text, objLen ); + result = SendTextAux(pasteString); + } + } + + nsAllocator::Free(bestFlavor); + + return NS_OK; +} + + +// Poll for readable data from LineTerm +NS_IMETHODIMP mozXMLTerminal::Poll(void) +{ + if (!mLineTermAux) + return NS_ERROR_NOT_INITIALIZED; + + XMLT_LOG(mozXMLTerminal::Poll,20,("\n")); + + return mXMLTermSession->ReadAll(mLineTermAux); +} + + +// Handle callback from LineTerm when new input/output needs to be displayed +NS_IMETHODIMP mozXMLTerminal::Observe(nsISupports *aSubject, + const PRUnichar *aTopic, + const PRUnichar *someData) +{ + nsCOMPtr lineTermAux = do_QueryInterface(aSubject); + PR_ASSERT(lineTermAux != nsnull); + + return mXMLTermSession->ReadAll(lineTermAux); +} + + +// Returns document associated with XMLTerminal +NS_IMETHODIMP mozXMLTerminal::GetDocument(nsIDOMDocument** aDoc) +{ + if (!aDoc) + return NS_ERROR_NULL_POINTER; + *aDoc = nsnull; + + NS_PRECONDITION(mDOMDocument, "bad state, null mDOMDocument"); + if (!mDOMDocument) + return NS_ERROR_NOT_INITIALIZED; + return mDOMDocument->QueryInterface(nsIDOMDocument::GetIID(), + (void **)aDoc); +} + + +// Returns presentation shell associated with XMLTerm +NS_IMETHODIMP mozXMLTerminal::GetPresShell(nsIPresShell** aPresShell) +{ + if (!aPresShell) + return NS_ERROR_NULL_POINTER; + *aPresShell = nsnull; + + NS_PRECONDITION(mPresShell, "bad state, null mPresShell"); + if (!mPresShell) + return NS_ERROR_NOT_INITIALIZED; + return mPresShell->QueryInterface(nsIPresShell::GetIID(), + (void **)aPresShell); +} + +// nsIDocumentLoaderObserver methods +NS_IMETHODIMP +mozXMLTerminal::OnStartDocumentLoad(nsIDocumentLoader* loader, nsIURI* aURL, + const char* aCommand) +{ + return NS_OK; +} + +NS_IMETHODIMP +mozXMLTerminal::OnEndDocumentLoad(nsIDocumentLoader* loader, nsIChannel* channel, + nsresult aStatus, + nsIDocumentLoaderObserver * aObserver) +{ + + return NS_OK; +} + +NS_IMETHODIMP +mozXMLTerminal::OnStartURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, + nsIContentViewer* aViewer) +{ + + return NS_OK; +} + +NS_IMETHODIMP +mozXMLTerminal::OnProgressURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, PRUint32 aProgress, + PRUint32 aProgressMax) +{ + return NS_OK; +} + +NS_IMETHODIMP +mozXMLTerminal::OnStatusURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, nsString& aMsg) +{ + return NS_OK; +} + +NS_IMETHODIMP +mozXMLTerminal::OnEndURLLoad(nsIDocumentLoader* loader, + nsIChannel* channel, nsresult aStatus) +{ + XMLT_LOG(mozXMLTerminal::OnEndURLLoad,20,("\n")); + + // Activate XMLTerm + Activate(); + return NS_OK; +} + +NS_IMETHODIMP +mozXMLTerminal::HandleUnknownContentType(nsIDocumentLoader* loader, + nsIChannel* channel, + const char *aContentType, + const char *aCommand ) +{ + return NS_OK; +} diff --git a/mozilla/extensions/xmlterm/base/mozXMLTerminal.h b/mozilla/extensions/xmlterm/base/mozXMLTerminal.h new file mode 100644 index 00000000000..bf7f424b351 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/mozXMLTerminal.h @@ -0,0 +1,153 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is XMLterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + */ + +// mozXMLTerminal.h: declaration of mozXMLTerminal +// which implements the mozIXMLTerminal interface +// to manage all XMLterm operations. + +#include "nscore.h" +#include "nspr.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "mozXMLT.h" + +#include "mozILineTermAux.h" +#include "mozIXMLTerminal.h" +#include "mozXMLTermSession.h" +#include "mozXMLTermListeners.h" +#include "mozIXMLTermStream.h" + + +class mozXMLTerminal : public mozIXMLTerminal, + public nsIDocumentLoaderObserver, + public nsIObserver +{ + public: + + mozXMLTerminal(); + virtual ~mozXMLTerminal(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // mozIXMLTerminal interface + + NS_IMETHOD Init(nsIWebShell* aWebShell, + mozIXMLTermShell* aXMLTermShell, + const PRUnichar* aURL, + const PRUnichar* args); + + NS_IMETHOD Finalize(void); + NS_IMETHOD Poll(void); + + NS_IMETHOD GetCurrentEntryNumber(PRInt32 *aNumber); + + NS_IMETHOD GetHistory(PRInt32 *aHistory); + NS_IMETHOD SetHistory(PRInt32 aHistory); + NS_IMETHOD GetPrompt(PRUnichar **aPrompt); + NS_IMETHOD SetPrompt(const PRUnichar* aPrompt); + + NS_IMETHOD SendTextAux(const nsString& aString); + NS_IMETHOD SendText(const nsString& aString, const PRUnichar* aCookie); + + NS_IMETHOD Paste(); + + NS_IMETHOD GetDocument(nsIDOMDocument** aDoc); + + NS_IMETHOD GetPresShell(nsIPresShell** aPresShell); + + // nsIDocumentLoaderObserver interface + NS_IMETHOD OnStartDocumentLoad(nsIDocumentLoader* loader, nsIURI* aURL, + const char* aCommand); + + NS_IMETHOD OnEndDocumentLoad(nsIDocumentLoader* loader, nsIChannel* channel, + nsresult aStatus, + nsIDocumentLoaderObserver * aObserver); + + NS_IMETHOD OnStartURLLoad(nsIDocumentLoader* loader, nsIChannel* channel, + nsIContentViewer* aViewer); + + NS_IMETHOD OnProgressURLLoad(nsIDocumentLoader* loader, nsIChannel* channel, PRUint32 aProgress, + PRUint32 aProgressMax); + + NS_IMETHOD OnStatusURLLoad(nsIDocumentLoader* loader, nsIChannel* channel, + nsString& aMsg); + + NS_IMETHOD OnEndURLLoad(nsIDocumentLoader* loader, nsIChannel* channel, + nsresult aStatus); + + NS_IMETHOD HandleUnknownContentType(nsIDocumentLoader* loader, + nsIChannel* channel, + const char *aContentType, + const char *aCommand ); + + // nsIObserver interface + NS_IMETHOD Observe(nsISupports *aSubject, const PRUnichar *aTopic, + const PRUnichar *someData); + + // Others + NS_IMETHOD Activate(void); + + protected: + + /** object initialization flag */ + PRBool mInitialized; + + /** cookie string used for authentication (stored in document.cookie) */ + nsString mCookie; + + nsString mCommand; + nsString mPromptExpr; + + /** initial input string to be sent to LineTerm */ + nsString mFirstInput; + + /** non-owning reference to containing XMLTermShell object */ + mozIXMLTermShell* mXMLTermShell; + + /** non-owning reference to containing web shell */ + nsIWebShell* mWebShell; + + /** non-owning (??) reference to presentation shell for XMLterm */ + nsIPresShell* mPresShell; + + /** non-owning (??) reference to DOM document containing XMLterm */ + nsIDOMDocument* mDOMDocument; + + /** XMLTermSession object created by us (not reference counted) */ + mozXMLTermSession* mXMLTermSession; + + /** owning reference to LineTermAux object created by us */ + nsCOMPtr mLineTermAux; + + /** owning referencing to key listener object created by us */ + nsCOMPtr mKeyListener; + + /** owning referencing to text listener object created by us */ + nsCOMPtr mTextListener; + + /** owning referencing to mouse listener object created by us */ + nsCOMPtr mMouseListener; + + /** owning referencing to drag listener object created by us */ + nsCOMPtr mDragListener; + +}; diff --git a/mozilla/extensions/xmlterm/base/ptystream.c b/mozilla/extensions/xmlterm/base/ptystream.c new file mode 100644 index 00000000000..8f93ea7ba54 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ptystream.c @@ -0,0 +1,512 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ptystream.c: pseudo-TTY stream implementation + * CPP options: + * LINUX: for Linux2.0/glibc + * SOLARIS: for Solaris2.6 + * NOERRMSG: for suppressing all error messages + * DEBUG: for printing some debugging output to STDERR + */ + +/* system header files */ + + +#include +#include +#include +#include + +#ifdef LINUX +#define __USE_BSD 1 +#include +#endif +#include +#include + +#include +#include +#include +#include + + +/* public declarations */ +#include "ptystream.h" + +/* private declarations */ +static int openPTY(struct ptys *ptyp, int noblock); +static int attachToTTY(struct ptys *ptyp, int errfd, int noecho); +static int setTTYAttr(int ttyFD, int noecho); +static void pty_error(const char *errmsg, const char *errmsg2); + +/* parameters */ +#define C_CTL_C '\003' /* ^C */ +#define C_CTL_D '\004' /* ^D */ +#define C_CTL_H '\010' /* ^H */ +#define C_CTL_O '\017' /* ^O */ +#define C_CTL_Q '\021' /* ^Q */ +#define C_CTL_R '\022' /* ^R */ +#define C_CTL_S '\023' /* ^S */ +#define C_CTL_U '\025' /* ^U */ +#define C_CTL_V '\026' /* ^V */ +#define C_CTL_W '\027' /* ^W */ +#define C_CTL_Y '\031' /* ^Y */ +#define C_CTL_Z '\032' /* ^Z */ +#define C_CTL_BSL '\034' /* ^\ */ + +/* Disable special character functions */ +#ifdef _POSIX_VDISABLE +#define VDISABLE _POSIX_VDISABLE +#else +#define VDISABLE 255 +#endif + +#define PTYCHAR1 "pqrstuvwxyzPQRSTUVWXYZ" +#define PTYCHAR2 "0123456789abcdef" + + +/* creates a new pseudo-TTY */ +int pty_create(struct ptys *ptyp, char *const argv[], + int errfd, int noblock, int noecho, int noexport, int debug) +{ + pid_t child_pid; + int errfd2; + + if (!ptyp) { + pty_error("pty_create: NULL value for PTY structure", NULL); + return -1; + } + + /* Set debug flag */ + ptyp->debug = debug; + +#ifdef DEBUG + if (ptyp->debug) + fprintf(stderr, "00-pty_create: errfd=%d, noblock=%d, noecho=%d, noexport=%d\n", + errfd, noblock, noecho, noexport); +#endif + + /* Open PTY */ + if (openPTY(ptyp, noblock) == -1) return -1; + + /* Set default TTY size */ + if (pty_resize(ptyp, 24, 80, 0, 0) != 0) + return -1; + + if (errfd >= -1) { + /* No STDERR pipe */ + ptyp->errpipeFD = -1; + errfd2 = errfd; + + } else { + /* Create pipe to handle STDERR output */ + int pipeFD[2]; + + if (pipe(pipeFD) == -1) { + pty_error("pty_create: STDERR pipe creation failed", NULL); + return -1; + } + + /* Copy pipe file descriptors */ + ptyp->errpipeFD = pipeFD[0]; + errfd2 = pipeFD[1]; + } + + /* Fork a child process (VFORK) */ + child_pid = vfork(); + if (child_pid < 0) { + pty_error("pty_create: vfork failed", NULL); + return -1; + } + + ptyp->pid = child_pid; + +#ifdef DEBUG + if (ptyp->debug) + fprintf(stderr, "00-pty_create: Fork child pid = %d, initially attached to %s\n", + child_pid, ttyname(0)); +#endif + + if (child_pid == 0) { + /* Child process */ + + /* Attach child to slave TTY */ + if (attachToTTY(ptyp, errfd2, noecho) == -1) return -1; + + /* Set default signal handling */ + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + /* Set ignore signal handling */ + signal(SIGTSTP, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + + if (argv != NULL) { + /* Execute specified command with arguments */ + if (noexport) + execve(argv[0], argv, NULL); + else + execvp(argv[0], argv); + + pty_error("Error in executing command ", argv[0]); + return -1; + + } else { + /* Execute $SHELL or /bin/sh by default */ + char *shell = (char *) getenv("SHELL"); + + if ((shell == NULL) || (*shell == '\0')) + shell = "/bin/sh"; + + if (noexport) + execle(shell, shell, NULL, NULL); + else + execlp(shell, shell, NULL); + + pty_error("pty_create: Error in executing command ", shell); + return -1; + } + + } + + if (errfd < -1) { + /* Close write end of STDERR pipe in parent process */ + close(errfd2); + } + + /* Return from parent */ + return 0; +} + + +/* closes a pseudo-TTY */ +int pty_close(struct ptys *ptyp) +{ + if (!ptyp) { + pty_error("pty_close: NULL value for PTY structure", NULL); + return -1; + } + + kill(ptyp->pid, SIGKILL); + ptyp->pid = 0; + + close(ptyp->ptyFD); + ptyp->ptyFD = -1; + + if (ptyp->errpipeFD >= 0) { + close(ptyp->errpipeFD); + ptyp->errpipeFD = -1; + } + + return 0; +} + + +/* resizes a pseudo-TTY */ +int pty_resize(struct ptys *ptyp, int rows, int cols, + int xpix, int ypix) +{ + struct winsize wsize; + + if (!ptyp) { + pty_error("pty_resize: NULL value for PTY structure", NULL); + return -1; + } + + if (ioctl(ptyp->ptyFD, TIOCGWINSZ, &wsize ) == -1) { + pty_error("pty_resize: Failed to get TTY window size", NULL); + return -1; + } + + /* Set TTY window size */ + wsize.ws_row = (unsigned short) rows; + wsize.ws_col = (unsigned short) cols; + wsize.ws_xpixel = (unsigned short) xpix; + wsize.ws_ypixel = (unsigned short) ypix; + + if (ioctl(ptyp->ptyFD, TIOCSWINSZ, &wsize ) == -1) { + pty_error("pty_resize: Failed to set TTY window size", NULL); + return -1; + } + + return 0; +} + + +static int openPTY(struct ptys *ptyp, int noblock) +{ + char ptyName[PTYNAMELEN+1], ttyName[PTYNAMELEN+1]; + + int plen, tlen, ptyFD, letIndex, devIndex; + + (void) strncpy(ptyName, "/dev/pty??", PTYNAMELEN+1); + (void) strncpy(ttyName, "/dev/tty??", PTYNAMELEN+1); + + plen = strlen(ptyName); + tlen = strlen(ttyName); + + assert(ptyp != NULL); + assert(plen <= PTYNAMELEN); + assert(tlen <= PTYNAMELEN); + + ptyFD = -1; + letIndex = 0; + while (PTYCHAR1[letIndex] && (ptyFD == -1)) { + ttyName[tlen - 2] = + ptyName[plen - 2] = PTYCHAR1 [letIndex]; + + devIndex = 0; + while (PTYCHAR2[devIndex] && (ptyFD == -1)) { + ttyName [tlen - 1] = + ptyName [plen - 1] = PTYCHAR2 [devIndex]; + + if ((ptyFD = open(ptyName, O_RDWR)) >= 0) { + if (access(ttyName, R_OK | W_OK) != 0) { + close(ptyFD); + ptyFD = -1; + } + } + devIndex++; + } + + letIndex++; + } + + if (ptyFD == -1) { + pty_error("openPTY: Unable to open pseudo-tty", NULL); + return -1; + } + + if (noblock) { + /* Set non-blocking mode */ + fcntl(ptyFD, F_SETFL, O_NDELAY); + } + + strncpy(ptyp->ptydev, ptyName, PTYNAMELEN+1); + strncpy(ptyp->ttydev, ttyName, PTYNAMELEN+1); + + ptyp->ptyFD = ptyFD; + +#ifdef DEBUG + if (ptyp->debug) + fprintf(stderr, "00-openPTY: Opened pty %s on fd %d\n", ptyName, ptyFD); +#endif + + return 0; +} + + +/* attaches new process to slave TTY */ +static int attachToTTY(struct ptys *ptyp, int errfd, int noecho) +{ + int ttyFD, fd, fdMax; + pid_t sid; + gid_t gid; + unsigned int ttyMode = 0622; + + assert(ptyp != NULL); + + /* Create new session */ + sid = setsid(); + +#ifdef DEBUG + if (ptyp->debug) + fprintf(stderr, "00-attachToTTY: Returned %d from setsid\n", sid); +#endif + + if (sid < 0) { +#ifndef NOERRMSG + perror("attachToTTY"); +#endif + return -1; + } + + if ((ttyFD = open(ptyp->ttydev, O_RDWR)) < 0) { + pty_error("attachToTTY: Unable to open slave tty ", ptyp->ttydev ); + return -1; + } + +#ifdef DEBUG + if (ptyp->debug) + fprintf(stderr,"00-attachToTTY: Attaching process %d to TTY %s on fd %d\n", + getpid(), ptyp->ttydev, ttyFD); +#endif + + /* Change TTY ownership and permissions*/ + gid = getgid(); + + fchown(ttyFD, getuid(), gid); + fchmod(ttyFD, ttyMode); + + /* Set TTY attributes (this actually seems to be harmful; so commented out!) + */ + /* if (setTTYAttr(ttyFD, noecho) == -1) return -1; */ + + /* Redirect to specified descriptor or to PTY */ + if (errfd >= 0) { + /* Redirect STDERR to specified file descriptor */ + if (dup2(errfd, 2) == -1) { + pty_error("attachToTTY: Failed dup2 for specified stderr", NULL); + return -1; + } + + } else { + /* Redirect STDERR to PTY */ + if (dup2(ttyFD, 2) == -1) { + pty_error("attachToTTY: Failed dup2 for default stderr", NULL); + return -1; + } + } + + /* Redirect STDIN and STDOUT to PTY */ + if (dup2(ttyFD, 0) == -1) { + pty_error("attachToTTY: Failed dup2 for stdin", NULL); + return -1; + } + + if (dup2(ttyFD, 1) == -1) { + pty_error("attachToTTY: Failed dup2 for stdout", NULL); + return -1; + } + + /* Close all other file descriptors in child process */ + fdMax = sysconf(_SC_OPEN_MAX); + for (fd = 3; fd < fdMax; fd++) + close(fd); + + /* Set process group */ + tcsetpgrp(0, sid); + + /* close(open(ptyp->ttydev, O_RDWR, 0)); */ + + return 0; +} + + +/* sets slave TTY attributes (NOT USED) */ +static int setTTYAttr(int ttyFD, int noecho) +{ + struct termios tios; + + /* Get TTY attributes */ + if (tcgetattr(ttyFD, &tios ) == -1) { +#ifndef NOERRMSG + perror("setTTYAttr"); +#endif + pty_error("setTTYattr: Failed to get TTY attributes", NULL); + return -1; + } + + /* TERMIOS settings for TTY */ + tios.c_cc[VINTR] = C_CTL_C; + tios.c_cc[VQUIT] = C_CTL_BSL; + tios.c_cc[VERASE] = C_CTL_H; + tios.c_cc[VKILL] = C_CTL_U; + tios.c_cc[VEOF] = C_CTL_D; + tios.c_cc[VEOL] = VDISABLE; + tios.c_cc[VEOL2] = VDISABLE; +#ifdef SOLARIS + tios.c_cc[VSWTCH] = VDISABLE; +#endif + tios.c_cc[VSTART] = C_CTL_Q; + tios.c_cc[VSTOP] = C_CTL_S; + tios.c_cc[VSUSP] = C_CTL_Z; + tios.c_cc[VREPRINT] = C_CTL_R; + tios.c_cc[VDISCARD] = C_CTL_O; + tios.c_cc[VWERASE] = C_CTL_W; + tios.c_cc[VLNEXT] = C_CTL_V; + + tios.c_cc[VMIN] = 1; /* Wait for at least 1 char of input */ + tios.c_cc[VTIME] = 0; /* Wait indefinitely (block) */ + + /* Input modes */ + tios.c_iflag &= ~IUCLC; /* Disable map of upper case input to lower*/ + tios.c_iflag &= ~IGNBRK; /* Do not ignore break */ + tios.c_iflag &= ~BRKINT; /* Do not signal interrupt on break either */ + + /* Output modes */ + tios.c_oflag &= ~OPOST; /* Disable output postprocessing */ + tios.c_oflag &= ~ONLCR; /* Disable mapping of NL to CR-NL on output */ + tios.c_oflag &= ~OLCUC; /* Disable map of lower case output to upper */ + /* No output delays */ + tios.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); + + /* control modes */ + tios.c_cflag |= (CS8 | CREAD); + + /* line discipline modes */ + if (noecho) + tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT | + ECHOCTL); /* Disable echo */ + else + tios.c_lflag |= (ECHO | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT | + ECHOCTL); /* Enable echo */ + + tios.c_lflag |= ISIG; /* Enable signals */ + tios.c_lflag |= ICANON; /* Enable erase/kill and eof processing */ + + /* NOTE: tcsh does not echo to be turned off if TERM=xterm; + setting TERM=dumb allows echo to be turned off, + but command completion is turned off as well */ + + /* Set TTY attributes */ + cfsetospeed (&tios, B38400); + cfsetispeed (&tios, B38400); + + if (tcsetattr(ttyFD, TCSADRAIN, &tios ) == -1) { +#ifndef NOERRMSG + perror("setTTYAttr"); +#endif + pty_error("setTTYattr: Failed to set TTY attributes", NULL); + return -1; + } + + return 0; +} + + +/* displays an error message, optionally concatenated with another */ +static void pty_error(const char *errmsg, const char *errmsg2) { + +#ifndef NOERRMSG + if (errmsg != NULL) { + if (errmsg2 != NULL) { + fprintf(stderr, "%s%s\n", errmsg, errmsg2); + } else { + fprintf(stderr, "%s\n", errmsg); + } + } +#endif + +} diff --git a/mozilla/extensions/xmlterm/base/ptystream.h b/mozilla/extensions/xmlterm/base/ptystream.h new file mode 100644 index 00000000000..1f8bbf4ff77 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/ptystream.h @@ -0,0 +1,92 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* ptystream.h: pseudo-TTY stream header + * (used by ltermPrivate.h) + */ + +#ifndef _PTYSTREAM_H + +#define _PTYSTREAM_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define PTYNAMELEN 10 /* Length of PTY/TTY device name: /dev/pty?? */ + +struct ptys { /* PTY structure */ + + int ptyFD; /* PTY file descriptor (bi-directional) */ + int errpipeFD; /* stderr pipe file descriptor (-1, if none) */ + + long pid; /* PTY child PID */ + + int debug; /* Debugging flag */ + + char ptydev[PTYNAMELEN+1]; /* PTY (master) name */ + char ttydev[PTYNAMELEN+1]; /* TTY (slave) name */ +}; + +/* creates a new pseudo-TTY (PTY) and also a new process attached to + * it to execute the command line contained in array ARGV. + * The PTY details are stored in the PTY structure PTYP. + * ERRFD is the file descriptor to which the STDERR output of the + * child process is directed. + * If ERRFD == -1, then the STDERR output is redirected to STDOUT. + * If ERRFD == -2, then a new pipe is created and STDERR is redirected + * through it. + * If NOBLOCK is true, enable non-blocking I/O on PTY. + * If NOECHO is true, tty echoing is turned off. + * If NOEXPORT is true, then the current environment is not exported + * to the new process. + * If DEBUG is true, debugging messages are printed to STDERR. + * Returns 0 on success and -1 on error. + */ +int pty_create(struct ptys *ptyp, char *const argv[], + int errfd, int noblock, int noecho, int noexport, int debug); + +/* resizes the PTY, returning 0 on success and -1 on error */ +int pty_resize(struct ptys *ptyp, int rows, int cols, + int xpix, int ypix); + +/* closes the PTY and kills the associated child process, if still alive. + * Also close STDERR pipe, if open. + * Returns 0 on success and -1 on error. + */ +int pty_close(struct ptys *ptyp); + +#ifdef __cplusplus +} +#endif + +#endif /* _PTYSTREAM_H */ diff --git a/mozilla/extensions/xmlterm/base/tracelog.c b/mozilla/extensions/xmlterm/base/tracelog.c new file mode 100644 index 00000000000..ca60c8222eb --- /dev/null +++ b/mozilla/extensions/xmlterm/base/tracelog.c @@ -0,0 +1,205 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* tracelog.c: Tracing/logging module implementation + */ + +/* public declarations */ +#include +#include + +#include "unistring.h" +#include "tracelog.h" + +/* private declarations */ + +/* TRACELOG global variable structure */ +TlogGlobal tlogGlobal; + +/** Initializes all TRACELOG operations and sets filestream for trace/log + * output. Setting filestream to NULL suppresses all output. + * (documented in tracelog.h) + */ +void tlog_init(FILE* fileStream) +{ + int imodule; + + fprintf(stderr, "tlog_init:\n"); + + /* Error output stream */ + tlogGlobal.errorStream = fileStream; + + /* Debugging is disabled initially */ + tlogGlobal.debugOn = 0; + + for (imodule=0; imodule= TLOG_MAXMODULES)) + return -1; + + /* Message level */ + tlogGlobal.messageLevel[imodule] = messageLevel; + + if (messageLevel > 0) { + tlog_warning("tlog_set_level: module %d, messageLevel=%d\n", + imodule, messageLevel); + } + + /* Free function list string */ + free(tlogGlobal.functionList[imodule]); + + if (functionList == NULL) { + tlogGlobal.functionList[imodule] = NULL; + + } else { + /* Duplicate function list string */ + int slen = strlen(functionList); + char *stem; + + if (slen > 1000) slen = 1000; + + stem = malloc((unsigned int) slen+3); + strncpy(&stem[1], functionList, (unsigned int) slen); + stem[0] = ':'; + stem[slen+1] = ':'; + stem[slen+2] = '\0'; + + tlogGlobal.functionList[imodule] = stem; + + if (messageLevel > 0) { + tlog_warning("tlog_set_level: module %d, functionList=\"%s\"\n", + imodule, tlogGlobal.functionList[imodule]); + } + } + + /* Turn on debugging only if needed */ + tlogGlobal.debugOn = 0; + + if (tlogGlobal.errorStream != NULL) { + for (j=0; j 0) || + (tlogGlobal.functionList != NULL)) + tlogGlobal.debugOn = 1; + } + } + + return 0; +} + + +/** Determines whether trace/log message is to be displayed for specified + * module at specified message level. + * @return 1 (true) if message should be displayed, 0 otherwise + */ +int tlog_test(int imodule, char *procstr, int level) +{ + if (tlogGlobal.errorStream == NULL) + return 0; + + if ((imodule < 0) || (imodule >= TLOG_MAXMODULES)) + return 0; + + if ( (level%10 <= tlogGlobal.messageLevel[imodule]%10) && + ( (level <= tlogGlobal.messageLevel[imodule]) || + ((tlogGlobal.functionList[imodule] != NULL) && + ( (strstr(tlogGlobal.functionList[imodule],procstr) != NULL) || + (strstr(procstr,tlogGlobal.functionList[imodule]) != NULL)) ) )) { + /* Display message */ + fprintf(tlogGlobal.errorStream, "%s%2d: ", procstr, level); + return 1; + } + + return 0; +} + + +/** Displays an error message on the TRACELOG filestream */ +void tlog_message(const char *format, ...) +{ + va_list ap; /* pointer to variable length argument list */ + + if (tlogGlobal.errorStream == NULL) + return; + + va_start(ap, format); /* make ap point to first unnamed arg */ + vfprintf(tlogGlobal.errorStream, format, ap); + va_end(ap); /* clean up */ + return; +} + + +/** Displays a warning message on the TRACELOG filestream */ +void tlog_warning(const char *format, ...) +{ + va_list ap; /* pointer to variable length argument list */ + + if ((tlogGlobal.errorStream == NULL) || !tlogGlobal.debugOn) + return; + + va_start(ap, format); /* make ap point to first unnamed arg */ + vfprintf(tlogGlobal.errorStream, format, ap); + va_end(ap); /* clean up */ + return; +} + + +#ifdef _UNISTRING_H +#define MAXCOL 1024 /* Maximum columns in line buffer */ + +/** Displays an Unicode message on the TRACELOG filestream */ +void tlog_unichar(const UNICHAR *buf, int count) +{ + if (tlogGlobal.errorStream == NULL) + return; + + fprintf(tlogGlobal.errorStream, "U(%d): ", count); + + ucsprint(tlogGlobal.errorStream, buf, count); + + fprintf(tlogGlobal.errorStream, "\n"); +} +#endif diff --git a/mozilla/extensions/xmlterm/base/tracelog.h b/mozilla/extensions/xmlterm/base/tracelog.h new file mode 100644 index 00000000000..1a2a985c57e --- /dev/null +++ b/mozilla/extensions/xmlterm/base/tracelog.h @@ -0,0 +1,154 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* tracelog.h: Tracing/logging module header + * CPP options: + * DEBUG: to enable debugging output + * _UNISTRING_H: for unicode messages compatible with "unistring.h" + */ + +#ifndef _TRACELOG_H + +#define _TRACELOG_H 1 + +#include +#include + +/* Trace/log macros (to be used after call to tlog_init to initialize): + * TLOG_ERROR: error message macro, e.g., + * TLOG_ERROR(format, val1, val2); + * TOG_WARNING: warning message macro, e.g., + * TLOG_WARNING(format, val1, val2); + * TLOG_PRINT: message logging macro, e.g., (no terminating semicolon) + * TLOG_PRINT(10,(format, val1, val2)); + * (if UNISTRING module is being used) + * TLOG_UNICHAR: Unicode string logging macro, e.g., (no terminating semicolon) + * TLOG_UNICHAR(10,(label,str,count)); + */ + +/* Max. number of modules recognized by TRACELOG */ +# define TLOG_MAXMODULES 50 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializes all TRACELOG operations; + * needs to be called before any other trace/log calls. + * + * FILESTREAM is the file stream to be used to print messages. + * + * Normally, only error messages are sent to FILESTREAM. + * If FILESTREAM is null, all output, including error output, is suppressed. + */ + +void tlog_init(FILE* fileStream); + +/** Set diagnostic message display level for module no. IMODULE. + * (0 <= IMODULE < TLOG_MAXMODULES) + * + * MESSAGELEVEL (>=0) specifies the diagnostic message display level: + * only diagnostic messages with level values >= MESSAGELEVEL are printed + * (For example, level 10, 11, ...: outermost level; + * level 20, 21, ...: next inner level; + * ... + * level 50, 51, ...: innermost level) + * + * The message SUBLEVEL threshold is defined as MESSAGELEVEL%10 + * (ranging from 0 to 9). + * Only those diagnostic messages with sublevel values >= SUBLEVEL threshold + * are displayed + * Usually, the SUBLEVEL threshold values are interpreted as + * 0 => print single message per selected procedure. + * 1...9 => print only messages upto selected sublevel. + * + * Setting MESSAGELEVEL to zero and FUNCTIONLIST to null for all modules + * disables debugging and printing of warning messages. + * (This is the initial configuration following the call to lterm_init.) + * Setting MESSAGELEVEL to 1 for atleast one module enables debugging and + * causes warning messages for all modules to be printed. + * + * FUNCTIONLIST is a colon-separated string of function names, e.g., + * "func_a:func_b". + * Trace/log messages for functions in this list are always output + * if debugging is enabled provided the sublevel values exceed the threshold, + * regardless of full message level values. + * If FUNCTIONLIST contains a single method name without a class name, or a + * class name without a method name, then the missing portion is assumed + * to be wild-carded. + * + * Returns 0 on success, -1 otherwise (i.e., for invalid module numbers) + */ + +int tlog_set_level(int imodule, int messageLevel, const char *functionList); + +int tlog_test(int imodule, char *procname, int level); +void tlog_message(const char *format, ...); +void tlog_warning(const char *format, ...); + +/* TRACELOG global variables */ +typedef struct { + FILE *errorStream; /* file stream for logging */ + int debugOn; + int messageLevel[TLOG_MAXMODULES]; + char *functionList[TLOG_MAXMODULES]; /* list of functions to be debugged */ +} TlogGlobal; + +extern TlogGlobal tlogGlobal; + +#ifdef __cplusplus +} +#endif + +#define TLOG_ERROR tlog_message + +#define TLOG_WARNING tlog_warning + +#define TLOG_PRINT(imodule,procname,level,args) \ +do { \ + if (tlogGlobal.debugOn && tlog_test(imodule,":" #procname ":",level)) { \ + tlog_message args; \ + } \ +} while(0) + +#ifdef _UNISTRING_H +void tlog_unichar(const UNICHAR *buf, int count); + +#define TLOG_UNICHAR(imodule,procname,level,args) \ +do { \ +if (tlogGlobal.debugOn && tlog_test(imodule,":" #procname ":",level)) { \ + tlog_unichar args; \ + } \ +} while(0) +#endif + +#endif /* _TRACELOG_H */ diff --git a/mozilla/extensions/xmlterm/base/unistring.c b/mozilla/extensions/xmlterm/base/unistring.c new file mode 100644 index 00000000000..a1f1900f657 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/unistring.c @@ -0,0 +1,186 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* unistring.c: Unicode string operations implementation */ + +/* public declarations */ +#include "unistring.h" + +/* private declarations */ + +/** Encodes Unicode string US with NUS characters into UTF8 string S with + * upto NS characters, returning the number of REMAINING Unicode characters + * and the number of ENCODED Utf8 characters + */ +void ucstoutf8(const UNICHAR* us, int nus, char* s, int ns, + int* remaining, int* encoded) +{ + int j, k; + + j = 0; + k = 0; + while ((j < ns) && (k < nus)) { + UNICHAR uch = us[k++]; + + if (uch < 0x0080) { + s[j++] = uch; + + } else if (uch < 0x0800) { + if (j >= ns-1) break; + s[j++] = ((uch & 0x07C0) >> 6) | 0xC0; + s[j++] = (uch & 0x003F) | 0x80; + + } else { + if (j >= ns-2) break; + s[j++] = ((uch & 0xF000) >> 12) | 0xE0; + s[j++] = ((uch & 0x0FC0) >> 6) | 0x80; + s[j++] = (uch & 0x003F) | 0x80; + } + } + + if (remaining) + *remaining = nus - k; + + if (encoded) + *encoded = j; +} + + +/** Decodes UTF8 string S with NS characters to Unicode string US with + * upto NUS characters, returning the number of REMAINING Utf8 characters + * and the number of DECODED Unicode characters. + * If skipNUL is non-zero, NUL input characters are skipped. + * returns 0 if successful, + * -1 if an error occurred during decoding + */ +int utf8toucs(const char* s, int ns, UNICHAR* us, int nus, + int skipNUL, int* remaining, int* decoded) +{ + int j, k; + int retcode = 0; + + j = 0; + k = 0; + while ((j < ns) && (k < nus)) { + char ch = s[j]; + + if (0x80 & ch) { + if (0x40 & ch) { + if (0x20 & ch) { + /* consume 3 */ + if (j >= ns-2) break; + + if ( (s[j+1] & 0x40) || !(s[j+1] & 0x80) || + (s[j+2] & 0x40) || !(s[j+2] & 0x80) ) { + retcode = -1; + } + + us[k++] = ((ch & 0x0F) << 12) + | ((s[j+1] & 0x3F) << 6) + | ( s[j+2] & 0x3F); + + j += 3; + + } else { + /* consume 2 */ + if (j >= ns-1) break; + + if ( (s[j+1] & 0x40) || !(s[j+1] & 0x80) ) { + retcode = -1; + } + + us[k++] = ((ch & 0x1F) << 6) + | ( s[j+1] & 0x3F); + j += 2; + } + + } else { + /* consume 1 (error) */ + retcode = -1; + j++; + } + + } else { + /* consume 1 */ + if (ch || !skipNUL) { + us[k++] = ch; + } + j++; + } + } + + if (remaining) + *remaining = ns - j; + + if (decoded) + *decoded = k; + + return retcode; +} + + +/** Prints Unicode string US with NUS characters to file stream STREAM, + * escaping non-printable ASCII characters and all non-ASCII characters + */ +void ucsprint(FILE* stream, const UNICHAR* us, int nus) +{ + static const char hexDigits[17] = "0123456789abcdef"; + UNICHAR uch; + int k; + + for (k=0; k1; j--) { + esc_str[j] = hexDigits[uch%16]; + uch = uch / 16; + } + fprintf(stream, "%s", esc_str); + } + } +} diff --git a/mozilla/extensions/xmlterm/base/unistring.h b/mozilla/extensions/xmlterm/base/unistring.h new file mode 100644 index 00000000000..f7e9c78aec6 --- /dev/null +++ b/mozilla/extensions/xmlterm/base/unistring.h @@ -0,0 +1,277 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "MPL"); you may not use this file + * except in compliance with the MPL. You may obtain a copy of + * the MPL at http://www.mozilla.org/MPL/ + * + * Software distributed under the MPL is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the MPL for the specific language governing + * rights and limitations under the MPL. + * + * The Original Code is lineterm. + * + * The Initial Developer of the Original Code is Ramalingam Saravanan. + * Portions created by Ramalingam Saravanan are + * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License (the "GPL"), in which case + * the provisions of the GPL are applicable instead of + * those above. If you wish to allow use of your version of this + * file only under the terms of the GPL and not to allow + * others to use your version of this file under the MPL, indicate + * your decision by deleting the provisions above and replace them + * with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* unistring.h: Unicode string operations header + * (used by lineterm.h) + * CPP options: + * HAVE_WCSWCS: define is function wcswcs is available + * HAVE_WCSSTR: define is function wcsstr is available + */ + +#ifndef _UNISTRING_H + +#define _UNISTRING_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _WCHAR_H +#include "wchar.h" +#endif + +#ifndef _STDIO_H +#include "stdio.h" +#endif + +/* Unicode character type: + * Uses the wchar_t implementation for moment. + * Later we might implement a 16-bit UNICHAR type to save space + */ + +typedef wchar_t UNICHAR; + +/* Unicode string functions: + * use the wchar_t implementation for moment + */ + +/** Encodes Unicode string US with NUS characters into UTF8 string S with + * upto NS characters, returning the number of REMAINING Unicode characters + * and the number of ENCODED Utf8 characters + */ +void ucstoutf8(const UNICHAR* us, int nus, char* s, int ns, + int* remaining, int* encoded); + +/** Decodes UTF8 string S with NS characters to Unicode string US with + * upto NUS characters, returning the number of REMAINING Utf8 characters + * and the number of DECODED Unicode characters. + * If skipNUL is non-zero, NUL input characters are skipped. + * returns 0 if successful, + * -1 if an error occurred during decoding + */ +int utf8toucs(const char* s, int ns, UNICHAR* us, int nus, + int skipNUL, int* remaining, int* decoded); + +/** Prints Unicode string US with NUS characters to file stream STREAM, + * escaping non-printable ASCII characters and all non-ASCII characters + */ +void ucsprint(FILE* stream, const UNICHAR* us, int nus); + +#define ucscpy wcscpy +#define ucsncpy wcsncpy + +#define ucscat wcscat +#define ucsncat wcsncat + +#define ucscmp wcscmp +#define ucsncmp wcsncmp + +#define ucschr wcschr +#define ucsrchr wcsrchr + +#define ucsspn wcsspn +#define ucscspn wcscspn + +#define ucspbrk wcspbrk + +#ifdef HAVE_WCSWCS +#define ucsucs wcswcs +#else +#ifdef HAVE_WCSSTR +#define ucsucs wcsstr +#endif +#endif + +#define ucslen wcslen + +#define ucstok wcstok + + +/* unsigned short constants */ + +#define U_NUL 0x00U + +#define U_CTL_A 0x01U +#define U_CTL_B 0x02U +#define U_CTL_C 0x03U +#define U_CTL_D 0x04U +#define U_CTL_E 0x05U +#define U_CTL_F 0x06U + +#define U_BEL 0x07U /* ^G */ +#define U_BACKSPACE 0x08U /* ^H */ +#define U_TAB 0x09U /* ^I */ +#define U_LINEFEED 0x0AU /* ^J */ + +#define U_CTL_K 0x0BU +#define U_CTL_L 0x0CU + +#define U_CRETURN 0x0DU /* ^M */ + +#define U_CTL_N 0x0EU +#define U_CTL_O 0x0FU +#define U_CTL_P 0x10U +#define U_CTL_Q 0x11U +#define U_CTL_R 0x12U +#define U_CTL_S 0x13U +#define U_CTL_T 0x14U +#define U_CTL_U 0x15U +#define U_CTL_V 0x16U +#define U_CTL_W 0x17U +#define U_CTL_X 0x18U +#define U_CTL_Y 0x19U +#define U_CTL_Z 0x1AU + +#define U_ESCAPE 0x1BU /* escape */ + +#define U_SPACE 0x20U /* space */ +#define U_EXCLAMATION 0x21U /* ! */ +#define U_DBLQUOTE 0x22U /* " */ +#define U_NUMBER 0x23U /* # */ +#define U_DOLLAR 0x24U /* $ */ +#define U_PERCENT 0x25U /* % */ +#define U_AMPERSAND 0x26U /* & */ +#define U_SNGLQUOTE 0x27U /* ' */ +#define U_LPAREN 0x28U /* ( */ +#define U_RPAREN 0x29U /* ) */ + +#define U_STAR 0x2AU /* * */ +#define U_PLUS 0x2BU /* + */ +#define U_COMMA 0x2CU /* , */ +#define U_DASH 0x2DU /* - */ +#define U_PERIOD 0x2EU /* . */ +#define U_SLASH 0x2FU /* / */ + +#define U_ZERO 0x30U /* 0 */ +#define U_ONE 0x31U /* 1 */ +#define U_TWO 0x32U /* 2 */ +#define U_THREE 0x33U /* 3 */ +#define U_FOUR 0x34U /* 4 */ +#define U_FIVE 0x35U /* 5 */ +#define U_SIX 0x36U /* 6 */ +#define U_SEVEN 0x37U /* 7 */ +#define U_EIGHT 0x38U /* 8 */ +#define U_NINE 0x39U /* 9 */ + +#define U_COLON 0x3AU /* : */ +#define U_SEMICOLON 0x3BU /* ; */ +#define U_LESSTHAN 0x3CU /* < */ +#define U_EQUALS 0x3DU /* = */ +#define U_GREATERTHAN 0x3EU /* > */ +#define U_QUERYMARK 0x3FU /* ? */ + +#define U_ATSIGN 0x40U /* @ */ + +#define U_A_CHAR 0x41U /* A */ +#define U_B_CHAR 0x42U /* B */ +#define U_C_CHAR 0x43U /* C */ +#define U_D_CHAR 0x44U /* D */ +#define U_E_CHAR 0x45U /* E */ +#define U_F_CHAR 0x46U /* F */ +#define U_G_CHAR 0x47U /* G */ +#define U_H_CHAR 0x48U /* H */ +#define U_I_CHAR 0x49U /* I */ +#define U_J_CHAR 0x4AU /* J */ +#define U_K_CHAR 0x4BU /* K */ +#define U_L_CHAR 0x4CU /* L */ +#define U_M_CHAR 0x4DU /* M */ +#define U_N_CHAR 0x4EU /* N */ +#define U_O_CHAR 0x4FU /* O */ +#define U_P_CHAR 0x50U /* P */ +#define U_Q_CHAR 0x51U /* Q */ +#define U_R_CHAR 0x52U /* R */ +#define U_S_CHAR 0x53U /* S */ +#define U_T_CHAR 0x54U /* T */ +#define U_U_CHAR 0x55U /* U */ +#define U_V_CHAR 0x56U /* V */ +#define U_W_CHAR 0x57U /* W */ +#define U_X_CHAR 0x58U /* X */ +#define U_Y_CHAR 0x59U /* Y */ +#define U_Z_CHAR 0x5AU /* Z */ + +#define U_LBRACKET 0x5BU /* [ */ +#define U_BACKSLASH 0x5CU /* \ */ +#define U_RBRACKET 0x5DU /* ] */ + +#define U_CARET 0x5EU /* ^ */ +#define U_UNDERSCORE 0x5FU /* _ */ +#define U_BACKQUOTE 0x60U /* ` */ + +#define U_a_CHAR 0x61U /* a */ +#define U_b_CHAR 0x62U /* b */ +#define U_c_CHAR 0x63U /* c */ +#define U_d_CHAR 0x64U /* d */ +#define U_e_CHAR 0x65U /* e */ +#define U_f_CHAR 0x66U /* f */ +#define U_g_CHAR 0x67U /* g */ +#define U_h_CHAR 0x68U /* h */ +#define U_i_CHAR 0x69U /* i */ +#define U_j_CHAR 0x6AU /* j */ +#define U_k_CHAR 0x6BU /* k */ +#define U_l_CHAR 0x6CU /* l */ +#define U_m_CHAR 0x6DU /* m */ +#define U_n_CHAR 0x6EU /* n */ +#define U_o_CHAR 0x6FU /* o */ +#define U_p_CHAR 0x70U /* p */ +#define U_q_CHAR 0x71U /* q */ +#define U_r_CHAR 0x72U /* r */ +#define U_s_CHAR 0x73U /* s */ +#define U_t_CHAR 0x74U /* t */ +#define U_u_CHAR 0x75U /* u */ +#define U_v_CHAR 0x76U /* v */ +#define U_w_CHAR 0x77U /* w */ +#define U_x_CHAR 0x78U /* x */ +#define U_y_CHAR 0x79U /* y */ +#define U_z_CHAR 0x7AU /* z */ + +#define U_LCURLY 0x7BU /* { */ +#define U_VERTBAR 0x7CU /* | */ +#define U_RCURLY 0x7DU /* } */ + +#define U_TILDE 0x7EU /* ~ */ +#define U_DEL 0x7FU /* delete */ + +#define U_LATIN1LO 0xA0U /* lowest Latin1 extension character */ +#define U_NOBRKSPACE 0xA0U /* no-break space */ +#define U_LATIN1HI 0xFFU /* highest Latin1 extension character */ + +#define IS_ASCII_LETTER(x) ( (((x) >= U_A_CHAR) && ((x) <= U_Z_CHAR)) || \ + (((x) >= U_a_CHAR) && ((x) <= U_z_CHAR)) ) + +#define IS_ASCII_DIGIT(x) ( ((x) >= U_ZERO) && ((x) <= U_NINE) ) + + +#ifdef __cplusplus +} +#endif + +#endif /* _UNISTRING_H */ diff --git a/mozilla/extensions/xmlterm/config/README b/mozilla/extensions/xmlterm/config/README new file mode 100644 index 00000000000..576fc89e5dd --- /dev/null +++ b/mozilla/extensions/xmlterm/config/README @@ -0,0 +1 @@ +config --- Configuration info and Make rules diff --git a/mozilla/extensions/xmlterm/config/autoconf.mk b/mozilla/extensions/xmlterm/config/autoconf.mk new file mode 100644 index 00000000000..2e70bbb8463 --- /dev/null +++ b/mozilla/extensions/xmlterm/config/autoconf.mk @@ -0,0 +1,47 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# autoconf.mk: autoconf info for stand-alone LineTerm only + +# C compiler +CC = gcc + +# C++ compiler +CXX = c++ + +# Library archive creation command +AR = ar cr $@ + +OS_INCLUDES = +OS_CFLAGS = +OS_CXXFLAGS = +OS_LDFLAGS = diff --git a/mozilla/extensions/xmlterm/config/config.mk b/mozilla/extensions/xmlterm/config/config.mk new file mode 100644 index 00000000000..e9ab9e7cf68 --- /dev/null +++ b/mozilla/extensions/xmlterm/config/config.mk @@ -0,0 +1,93 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# config.mk: config info for stand-alone LineTerm only + +# Options +# DEBUG: debug option + +# OS details +OS_ARCH := $(subst /,_,$(shell uname -s)) +OS_RELEASE := $(shell uname -r) + +ifneq (,$(filter Linux SunOS,$(OS_ARCH))) +OS_VERS := $(suffix $(OS_RELEASE)) +OS_RELEASE := $(basename $(OS_RELEASE)) +endif + +OS_CONFIG := $(OS_ARCH)$(OS_RELEASE) + +ifeq ($(OS_ARCH),Linux) +LIB_SUFFIX = a +RANLIB = /usr/bin/ranlib +endif + +ifeq ($(OS_CONFIG),SunOS5) +LIB_SUFFIX = a +RANLIB = /bin/true +endif + +# C++ compiler +CCC = $(CXX) + +# OS flags +OS_CFLAGS += $(PLATFORM_FLAGS) +OS_CXXFLAGS += $(PLATFORM_FLAGS) +OS_LDFLAGS += + +# Object directory +OBJDIR = lib + +# Library directory +LIBS_DIR = -L$(topsrcdir)/dist/$(OBJDIR) + +# Distribution includes +LOCAL_INCLUDES += -I$(topsrcdir)/dist/include + +# NSPR libraries +NSPR_LIBS = -lnspr3 + +# +# Debug option +# +ifdef DEBUG +OPTIMIZER = -g +DEFINES += -DDEBUG +else +OPTIMIZER = +endif + +INCLUDES = $(LOCAL_INCLUDES) $(OS_INCLUDES) + +CFLAGS = $(OPTIMIZER) $(OS_CFLAGS) $(DEFINES) $(INCLUDES) +CXXFLAGS = $(OPTIMIZER) $(OS_CXXFLAGS) $(DEFINES) $(INCLUDES) +LDFLAGS = $(OS_LDFLAGS) diff --git a/mozilla/extensions/xmlterm/config/rules.mk b/mozilla/extensions/xmlterm/config/rules.mk new file mode 100644 index 00000000000..f6f2c831bfb --- /dev/null +++ b/mozilla/extensions/xmlterm/config/rules.mk @@ -0,0 +1,157 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# rules.mk: Make rules for stand-alone LineTerm only + +# CAUTION: Dependency checking is very limited. +# For compilation, the only dependencies are on *.h files in the current +# directory and in the distribution include directory. +# When creating executables, there is additional dependency on +# all *.a files in the distribution object directory. + +ifndef LIBRARY +ifdef LIBRARY_NAME +LIBRARY := lib$(LIBRARY_NAME).$(LIB_SUFFIX) +endif # LIBRARY_NAME +endif # LIBRARY + +ifdef PROGRAM +PROGRAM := $(addprefix $(OBJDIR)/, $(PROGRAM)) +endif + +ifdef SIMPLE_PROGRAMS +SIMPLE_PROGRAMS := $(addprefix $(OBJDIR)/, $(SIMPLE_PROGRAMS)) +endif + +ifdef LIBRARY +LIBRARY := $(addprefix $(OBJDIR)/, $(LIBRARY)) +endif + +ifndef OBJS +OBJS = $(CSRCS:.c=.o) $(CPPSRCS:.cpp=.o) +endif + +OBJS := $(addprefix $(OBJDIR)/, $(OBJS)) + +ifdef DIRS +LOOP_OVER_DIRS = \ + @for d in $(DIRS); do \ + if test -f $$d/Makefile; then \ + set -e; \ + echo "cd $$d; $(MAKE) $@"; \ + oldDir=`pwd`; \ + cd $$d; $(MAKE) $@; cd $$oldDir; \ + set +e; \ + else \ + echo "Skipping non-directory $$d..."; \ + fi; \ + done +endif + +ifndef PROGOBJS +PROGOBJS = $(OBJS) +endif + +# Targets +all: export libs progs + +export: $(EXPORTS) +ifneq (,$(EXPORTS)) + +for x in $^; do \ + rm $(topsrcdir)/dist/include/$$x; \ + echo ln -s `pwd`/$$x $(topsrcdir)/dist/include/$$x; \ + ln -s `pwd`/$$x $(topsrcdir)/dist/include/$$x; \ + done +endif + +$(LOOP_OVER_DIRS) + +libs: $(LIBRARY) + +$(LOOP_OVER_DIRS) + +progs: $(SIMPLE_PROGRAMS) + +$(LOOP_OVER_DIRS) + +clean: + -rm $(OBJDIR)/* + +$(LOOP_OVER_DIRS) + +# +# Turn on C++ linking if we have any .cpp files +# +ifdef CPPSRCS +CPP_PROG_LINK = 1 +endif + +# Create single executable program (with limited dependency checking) +$(PROGRAM): $(PROGOBJS) $(wildcard $(topsrcdir)/dist/$(OBJDIR)/*.a) +ifeq ($(CPP_PROG_LINK),1) + $(CCC) -o $@ $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS)) +else + $(CC) -o $@ $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) +endif + +# Create multiple simple executable programs (with limited dependency checking) +$(SIMPLE_PROGRAMS): $(OBJDIR)/%: $(OBJDIR)/%.o \ + $(wildcard $(topsrcdir)/dist/$(OBJDIR)/*.a) +ifeq ($(CPP_PROG_LINK),1) + $(CCC) -o $@ $< $(LDFLAGS) $(LIBS_DIR) $(LIBS)) +else + $(CC) -o $@ $< $(LDFLAGS) $(LIBS_DIR) $(LIBS) +endif + +# Create library and export it +$(LIBRARY): $(OBJS) + $(AR) $(OBJS) + $(RANLIB) $@ + -rm $(topsrcdir)/dist/$@ + ln -s `pwd`/$@ $(topsrcdir)/dist/$@ + + +# Compilation rules (with limited dependency checking) +$(OBJDIR)/%.o: %.c $(wildcard *.h) $(wildcard $(topsrcdir)/dist/include/*.h) + $(CC) -o $@ -c $(CFLAGS) $< + +$(OBJDIR)/%.o: %.cpp $(wildcard *.h) $(wildcard $(topsrcdir)/dist/include/*.h) + $(CCC) -o $@ -c $(CXXFLAGS) $< + + +# Recognized suffixes +.SUFFIXES: +.SUFFIXES: .a .o .c .cpp .h .pl .class .java .html .mk .in + +# Always recognized targets +.PHONY: all clean clobber clobber_all export install libs + +# OS configuration +os_config: + @echo "OS_ARCH = $(OS_ARCH), OS_CONFIG=$(OS_CONFIG)" + @echo "OS_RELEASE=$(OS_RELEASE), OS_VERS=$(OS_VERS)" diff --git a/mozilla/extensions/xmlterm/config/xmlterm_config.mk b/mozilla/extensions/xmlterm/config/xmlterm_config.mk new file mode 100644 index 00000000000..51623ccfed1 --- /dev/null +++ b/mozilla/extensions/xmlterm/config/xmlterm_config.mk @@ -0,0 +1,102 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# xmlterm_config.mk: XMLTERM-specific configuration options + +# Options +# STAND_ALONE: compile outside Mozilla/NSPR environment +# DEBUG: debug option +# NO_WORKAROUND: disables workarounds to expose bugs +# USE_GTK_WIDGETS use GTK widget library +# USE_NSPR_BASE: use basic NSPR API (excluding I/O and process creation) +# USE_NSPR_IO: use NSPR I/O and process API instead of Unix API +# NO_PTY: force use of pipes rather than PTY for process communication +# NO_CALLBACK: do not use GTK callbacks to handle LineTerm output +# (use polling instead) + +ifdef NO_WORKAROUND +DEFINES += -DNO_WORKAROUND +endif + +# +# OS dependent options +# +ifneq (,$(filter-out Linux2.0 Linux2.2 SunOS5,$(OS_CONFIG))) +# Unsupported platform for PTY; use pipes for process communication +NO_PTY = 1 +endif + +ifeq ($(OS_ARCH),Linux) +DEFINES += -DLINUX -DHAVE_WCSSTR +endif + +ifeq ($(OS_CONFIG),SunOS5) +DEFINES += -DSOLARIS -DHAVE_WCSWCS +endif + +ifeq ($(MOZ_WIDGET_TOOLKIT),gtk) +USE_GTK_WIDGETS = 1 +endif + +# +# Netscape Portable Runtime options +# +ifndef STAND_ALONE +# Use NSPR base +USE_NSPR_BASE = 1 +endif + +ifdef USE_GTK_WIDGETS +DEFINES += -DUSE_GTK_WIDGETS +else +# No callback +NO_CALLBACK = 1 +endif + +ifdef USE_NSPR_IO +DEFINES += -DUSE_NSPR_IO +USE_NSPR_BASE = 1 +NO_CALLBACK = 1 +endif + +ifdef USE_NSPR_BASE +DEFINES += -DUSE_NSPR_BASE +LIBS += $(NSPR_LIBS) +endif + +ifdef NO_PTY +DEFINES += -DNO_PTY +endif + +ifdef NO_CALLBACK +DEFINES += -DNO_CALLBACK +endif diff --git a/mozilla/extensions/xmlterm/dist/README b/mozilla/extensions/xmlterm/dist/README new file mode 100644 index 00000000000..a52f0feaa41 --- /dev/null +++ b/mozilla/extensions/xmlterm/dist/README @@ -0,0 +1 @@ +dist --- Include and library files for LineTerm only diff --git a/mozilla/extensions/xmlterm/doc/BUGS b/mozilla/extensions/xmlterm/doc/BUGS new file mode 100644 index 00000000000..e206fe57231 --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/BUGS @@ -0,0 +1,9 @@ +Known bugs +---------- + +10 Nov 1999 + + +1. Command line completion output duplicates command line + +2. Early use of "xls -i" does not scroll properly diff --git a/mozilla/extensions/xmlterm/doc/FinalizeXPCOM b/mozilla/extensions/xmlterm/doc/FinalizeXPCOM new file mode 100644 index 00000000000..b193012cfd7 --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/FinalizeXPCOM @@ -0,0 +1,31 @@ +"Finalize tree" to break XPCOM cycles and have clean shutdowns +-------------------------------------------------------------- + + XMLterm class embedding hierarchy + ================================= + + mozXMLTermShell (or ../geckoterm/mozGeckoTerm) + | + | + mozXMLTerminal + +-----------------+----------------+ + | | | + mozXMLTermSession mozLineTermAux mozXMLTermListeners + | | + | | + mozXMLTermStream... (lineterm) + +We would like to have clean shutdowns of an XMLterm, since we are using +external resources, e.g., a shell process or an rlogin process. However, the +XPCOM reference counting can hinder shutdowns, if there cycles. To avoid +that, the XMLterm interfaces have a Finalize or Close method. A shutdown +event triggers a call to the Finalize method of the root interface in the +"Finalize tree". When the Finalize method of any interface is called, it +first calls the Finalize methods of any child nodes in the Finalize tree, then +releases all the XPCOM references it owns, de-initializes itself and quietly +waits for its reference count to go to zero. In this "closed" state of the +interface, any attempts use it result in an error return. + +The destructor of an object simply checks if all its interfaces have been +finalized, and calls the Finalize methods for any that have not been. +-- diff --git a/mozilla/extensions/xmlterm/doc/INSTALL.xmlterm b/mozilla/extensions/xmlterm/doc/INSTALL.xmlterm new file mode 100644 index 00000000000..fb9ae341e3a --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/INSTALL.xmlterm @@ -0,0 +1,60 @@ +XMLterm installation instructions for Linux binaries +---------------------------------------------------- + +*NOTE* This work in progress. User beware! + +*NOTE* Check the XMLterm web site for updates. + +19 Nov 1999 + +1. First obtain the Mozilla Linux binary tar file + ftp://ftp.mozilla.org/pub/mozilla/releases/m11/mozilla-i686-pc-linux-gnu-M11.tar.gz" + and untar it in any convenient location. This will create a + directory named "package" containing the binaries. + +2. Untar the XMLterm binary tar file "xmlterm-i686-pc-linux-gnu-M11.tar.gz" + in the "package" directory created above. + +3. Type the following command in the "package" directory: + + ./mozilla chrome://xmlterm/content/xmlterm.html + + This should create an XMLTerm in the browser window. Then click on + that window with the mouse to shift focus and start typing UNIX + commands. + + **NOTE** + The command prompt is assumed to be terminated by one of the characters + "#$%>?", followed by a space. If this is not the case, many features will + not work. This restriction will be relaxed in the future. + +4. To use the stand-alone XMLterm executable called "xmlterm", + type the following command in the "package" directory: + + ./run-mozilla.sh xmlterm + + (The Mozilla component registry may need to be updated by running the + full browser using step 3 at least once before running "xmlterm".) + +5. The command line can be edited using EMACS-style key bindings. + Command completion should also work with TCSH and BASH, as should history + recall. + +6. By default, blue coloring is used to indicate clickable display elements. + Note that the prompt and the input command line are clickable. + (Of course, the appearance of XMLterm is completely configurable + using the CSS stylesheet chrome://xmlterm/skin/default/xmlterm.css) + + After typing one or two commands, click on the prompt string of any previous + command to see what happens! Then click again on the same prompt string. + Also click on "Hide all output" button at the top of the document. + + Clicking on a previous command line (to the right of the prompt) re-executes + the command. + +7. The sample Perl script "xls", the iconic/hypertext version of the Unix + "ls" command, is also installed in the "package" directory. Adding + the "package" directory to your path should enable you to use the "xls" + command. + +-- diff --git a/mozilla/extensions/xmlterm/doc/Implementation b/mozilla/extensions/xmlterm/doc/Implementation new file mode 100644 index 00000000000..c8921ea3d35 --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/Implementation @@ -0,0 +1,28 @@ +Implementation issues +--------------------- + +16 Sep 1999 + +- Slowness due to DOM reflows + +- Cursor positioning problems + +- Scrolling problems + +- Finding a slot in the "Tasks/Tools" menu on the browser menu bar + for an XMLterm menu with the following options: + + shell + rlogin + telnet + About XMLterm + + This needs to be done using XUL overlays. + +- Drag and drop implementation; integrating XMLterm with Gnome/KDE/CDE + +- Full screen implementation; determining screen size + +- Inline floating frames to display stream output + +-- diff --git a/mozilla/extensions/xmlterm/doc/MPL b/mozilla/extensions/xmlterm/doc/MPL new file mode 100644 index 00000000000..856d18bb032 --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/MPL @@ -0,0 +1,602 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + --------- + + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making + the Covered Code available to a third party. + + + 1.1. ''Contributor'' means each entity that creates or + contributes to the creation of Modifications. + + + 1.2. ''Contributor Version'' means the combination of the + Original Code, prior Modifications used by a Contributor, and the + Modifications made by that particular Contributor. + + + 1.3. ''Covered Code'' means the Original Code or Modifications or + the combination + + of the Original Code and Modifications, in each case including + portions thereof. + + 1.4. ''Electronic Distribution Mechanism'' means a mechanism + generally + + accepted in the software development community for the electronic + transfer of data. + + 1.5. ''Executable'' means Covered Code in any form other than + Source Code. + + 1.6. ''Initial Developer'' means the individual or entity + identified as the Initial Developer in the Source Code + notice required by Exhibit A. + + 1.7. ''Larger Work'' means a work which combines Covered Code or + portions thereof with code not governed by the terms of this + License. + + 1.8. ''License'' means this document. + + 1.8.1. "Licensable" means having the right to grant, to the + maximum extent possible, whether at the time of the initial grant + or subsequently acquired, any and all of the rights conveyed + herein. + + 1.9. ''Modifications'' means any addition to or deletion from the + substance or structure of either the Original Code or any + previous Modifications. When Covered Code is released as a series + of files, a Modification is: A. Any addition to or deletion from + the contents of a file containing Original Code or previous + Modifications. + + B. Any new file that contains any part of the Original Code + or previous Modifications. + + 1.10. ''Original Code'' means Source Code of computer software + code which is described in the Source Code notice required by + Exhibit A as Original Code, and which, at the time of its release + under this License is not already Covered Code governed by this + License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, + process, and apparatus claims, in any patent Licensable by + grantor. + + 1.11. ''Source Code'' means the preferred form of the Covered + Code for making modifications to it, including all modules it + contains, plus any associated interface definition files, scripts + used to control compilation and installation of an Executable, or + source code differential comparisons against either the Original + Code or another well known, available Covered Code of the + Contributor's choice. The Source Code can be in a compressed or + archival form, provided the appropriate decompression or + de-archiving software is widely available for no charge. + + 1.12. "You'' (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License or a future version of this License issued under + Section 6.1. For legal entities, "You'' includes any entity which + controls, is controlled by, or is under common control with + You. For purposes of this definition, "control'' means (a) the + power, direct or indirect, to cause the direction or management + of such entity, whether by contract or otherwise, or (b) + ownership of more than fifty percent (50%) of the outstanding + shares or beneficial ownership of such entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. The Initial Developer hereby + grants You a world-wide, royalty-free, non-exclusive license, + subject to third party intellectual property claims: (a) under + intellectual property rights (other than patent or trademark) + Licensable by Initial Developer to use, reproduce, modify, + display, perform, sublicense and distribute the Original Code (or + portions thereof) with or without Modifications, and/or as part + of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license + is granted: 1) for code that You delete from the Original + Code; 2) separate from the Original Code; or 3) for + infringements caused by: i) the modification of the Original + Code or ii) the combination of the Original Code with other + software or devices. + + 2.2. Contributor Grant. Subject to third party intellectual + property claims, each Contributor hereby grants You a world-wide, + royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, + modify, display, perform, sublicense and distribute the + Modifications created by such Contributor (or portions + thereof) either on an unmodified basis, with other + Modifications, as Covered Code and/or as part of a Larger + Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either + alone and/or in combination with its Contributor Version (or + portions of such combination), to make, use, sell, offer for + sale, have made, and/or otherwise dispose of: 1) + Modifications made by that Contributor (or portions + thereof); and 2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions + of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use + of the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license + is granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; 3) for + infringements caused by: i) third party modifications of Contributor + Version or ii) the combination of Modifications made by that + Contributor with other software (except as part of the Contributor + Version) or other devices; or 4) under Patent Claims infringed by + Covered Code in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. The Modifications which You create + or to which You contribute are governed by the terms of this + License, including without limitation Section 2.2. The Source + Code version of Covered Code may be distributed only under the + terms of this License or a future version of this License + released under Section 6.1, and You must include a copy of this + License with every copy of the Source Code You distribute. You + may not offer or impose any terms on any Source Code version that + alters or restricts the applicable version of this License or the + recipients' rights hereunder. However, You may include an + additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. Any Modification which You + create or to which You contribute must be made available in + Source Code form under the terms of this License either on the + same media as an Executable version or via an accepted Electronic + Distribution Mechanism to anyone to whom you made an Executable + version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve + (12) months after the date it initially became available, or at + least six (6) months after a subsequent version of that + particular Modification has been made available to such + recipients. You are responsible for ensuring that the Source Code + version remains available even if the Electronic Distribution + Mechanism is maintained by a third party. + + 3.3. Description of Modifications. You must cause all Covered + Code to which You contribute to contain a file documenting the + changes You made to create that Covered Code and the date of any + change. You must include a prominent statement that the + Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of + the Initial Developer in (a) the Source Code, and (b) in any + notice in an Executable version or related documentation in which + You describe the origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters (a) Third Party Claims. If + Contributor has knowledge that a license under a third + party's intellectual property rights is required to exercise + the rights granted by such Contributor under Sections 2.1 or + 2.2, Contributor must include a text file with the Source + Code distribution titled "LEGAL'' which describes the claim + and the party making the claim in sufficient detail that a + recipient will know whom to contact. If Contributor obtains + such knowledge after the Modification is made available as + described in Section 3.2, Contributor shall promptly modify + the LEGAL file in all copies Contributor makes available + thereafter and shall take other steps (such as notifying + appropriate mailing lists or newsgroups) reasonably + calculated to inform those who received the Covered Code + that new knowledge has been obtained. + + (b) Contributor APIs. If Contributor's Modifications + include an application programming interface and Contributor + has knowledge of patent licenses which are reasonably + necessary to implement that API, Contributor must also + include this information in the LEGAL file. + + (c) Representations. Contributor represents that, + except as disclosed pursuant to Section 3.4(a) above, + Contributor believes that Contributor's Modifications are + Contributor's original creation(s) and/or Contributor has + sufficient rights to grant the rights conveyed by this + License. + + 3.5. Required Notices. You must duplicate the notice in Exhibit + A in each file of the Source Code. If it is not possible to put + such notice in a particular Source Code file due to its + structure, then You must include such notice in a location (such + as a relevant directory) where a user would be likely to look for + such a notice. If You created one or more Modification(s) You + may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any + documentation for the Source Code where You describe recipients' + rights or ownership rights relating to Covered Code. You may + choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of + Covered Code. However, You may do so only on Your own behalf, + and not on behalf of the Initial Developer or any + Contributor. You must make it absolutely clear than any such + warranty, support, indemnity or liability obligation is offered + by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. You may distribute + Covered Code in Executable form only if the requirements of + Section 3.1-3.5 have been met for that Covered Code, and if You + include a notice stating that the Source Code version of the + Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously + included in any notice in an Executable version, related + documentation or collateral in which You describe recipients' + rights relating to the Covered Code. You may distribute the + Executable version of Covered Code or ownership rights under a + license of Your choice, which may contain terms different from + this License, provided that You are in compliance with the terms + of this License and that the license for the Executable version + does not attempt to limit or alter the recipient's rights in the + Source Code version from the rights set forth in this License. If + You distribute the Executable version under a different license + You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability + incurred by the Initial Developer or such Contributor as a result + of any such terms You offer. + + 3.7. Larger Works. You may create a Larger Work by combining + Covered Code with other code not governed by the terms of this + License and distribute the Larger Work as a single product. In + such a case, You must make sure the requirements of this License + are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of + this License with respect to some or all of the Covered Code due + to statute, judicial order, or regulation then You must: (a) + comply with the terms of this License to the maximum extent + possible; and (b) describe the limitations and the code they + affect. Such description must be included in the LEGAL file + described in Section 3.4 and must be included with all + distributions of the Source Code. Except to the extent + prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be + able to understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. Netscape Communications Corporation + (''Netscape'') may publish revised and/or new versions of the + License from time to time. Each version will be given a + distinguishing version number. + + 6.2. Effect of New Versions. Once Covered Code has been + published under a particular version of the License, You may + always continue to use it under the terms of that version. You + may also choose to use such Covered Code under the terms of any + subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable + to Covered Code created under this License. + + 6.3. Derivative Works. If You create or use a modified version + of this License (which you may only do in order to apply it to + code which is not already Covered Code governed by this License), + You must (a) rename Your license so that the phrases ''Mozilla'', + ''MOZILLAPL'', ''MOZPL'', ''Netscape'', "MPL", ''NPL'' or any + confusingly similar phrase do not appear in your license (except + to note that your license differs from this License) and (b) + otherwise make it clear that Your version of the license contains + terms which differ from the Mozilla Public License and Netscape + Public License. (Filling in the name of the Initial Developer, + Original Code or Contributor in the notice described in Exhibit A + shall not of themselves be deemed to be modifications of this + License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE + IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will + terminate automatically if You fail to comply with terms herein + and fail to cure such breach within 30 days of becoming aware of + the breach. All sublicenses to the Covered Code which are + properly granted shall survive any termination of this + License. Provisions which, by their nature, must remain in effect + beyond the termination of this License shall survive. + + 8.2. If You initiate litigation by asserting a patent + infringement claim (excluding declatory judgment actions) against + Initial Developer or a Contributor (the Initial Developer or + Contributor against whom You file such action is referred to as + "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate + prospectively, unless if within 60 days after receipt of notice + You either: (i) agree in writing to pay Participant a mutually + agreeable reasonable royalty for Your past and future use of + Modifications made by such Participant, or (ii) withdraw Your + litigation claim with respect to the Contributor Version against + such Participant. If within 60 days of notice, a reasonable + royalty and payment arrangement are not mutually agreed upon in + writing by the parties or the litigation claim is not withdrawn, + the rights granted by Participant to You under Sections 2.1 + and/or 2.2 automatically terminate at the expiration of the 60 + day notice period specified above. + + (b) any software, hardware, or device, other than such + Participant's Contributor Version, directly or indirectly + infringes any patent, then any rights granted to You by such + Participant under Sections 2.1(b) and 2.2(b) are revoked + effective as of the date You first made, used, sold, distributed, + or had made, Modifications made by that Participant. + + 8.3. If You assert a patent infringement claim against + Participant alleging that such Participant's Contributor Version + directly or indirectly infringes any patent where such claim is + resolved (such as by license or settlement) prior to the + initiation of patent infringement litigation, then the reasonable + value of the licenses granted by such Participant under Sections + 2.1 or 2.2 shall be taken into account in determining the amount + or value of any payment or license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 + above, all end user license agreements (excluding distributors + and resellers) which have been validly granted by You or any + distributor hereunder prior to termination shall survive + termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE + TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER + FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES + OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE + POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL + NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING + FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, + SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a ''commercial item,'' as that term is + defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of + ''commercial computer software'' and ''commercial computer + software documentation,'' as such terms are used in 48 + C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and + 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all + U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the + extent necessary to make it enforceable. This License shall be + governed by California law provisions (except to the extent + applicable law, if any, provides otherwise), excluding its + conflict-of-law provisions. With respect to disputes in which at + least one party is a citizen of, or an entity chartered or + registered to do business in the United States of America, any + litigation relating to this License shall be subject to the + jurisdiction of the Federal Courts of the Northern District of + California, with venue lying in Santa Clara County, California, + with the losing party responsible for costs, including without + limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly + excluded. Any law or regulation which provides that the language + of a contract shall be construed against the drafter shall not + apply to this License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or + indirectly, out of its utilization of rights under this License + and You agree to work with Initial Developer and Contributors to + distribute such responsibility on an equitable basis. Nothing + herein is intended or shall be deemed to constitute any admission + of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + ?Multiple-Licensed?. ?Multiple-Licensed? means that the Initial + Developer permits you to utilize portions of the Covered Code + under Your choice of the NPL or the alternative licenses, if any, + specified by the Initial Developer in the file described in + Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``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 ______________________________________. + + The Initial Developer of the Original Code is + ________________________. Portions created by + ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the ?[___] License?), in which case + the provisions of [______] License are applicable instead of + those above. If you wish to allow use of your version of this + file only under the terms of the [____] License and not to allow + others to use your version of this file under the MPL, indicate + your decision by deleting the provisions above and replace them + with the notice and other provisions required by the [___] + License. If you do not delete the provisions above, a recipient + may use your version of this file under either the MPL or the + [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the + text of the notices in the Source Code files of the Original + Code. You should use the text of this Exhibit A rather than the + text found in the Original Code Source Code for Your + Modifications.] + + ---------------------------------------- + + AMENDMENTS + + The Netscape Public License Version 1.1 ("NPL") consists of the + Mozilla Public License Version 1.1 with the following Amendments, + including Exhibit A-Netscape Public License. Files identified + with "Exhibit A-Netscape Public License" are governed by the + Netscape Public License Version 1.1. + + Additional Terms applicable to the Netscape Public License. + I. Effect. These additional terms described in this Netscape + Public License -- Amendments shall apply to the Mozilla + Communicator client code and to all Covered Code under this + License. + + II. ''Netscape's Branded Code'' means Covered Code that + Netscape distributes and/or permits others to distribute + under one or more trademark(s) which are controlled by + Netscape but which are not licensed for use under this + License. + + III. Netscape and logo. This License does not grant any + rights to use the trademarks "Netscape'', the "Netscape N + and horizon'' logo or the "Netscape lighthouse" logo, + "Netcenter", "Gecko", "Java" or "JavaScript", "Smart + Browsing" even if such marks are included in the Original + Code or Modifications. + + IV. Inability to Comply Due to Contractual Obligation. + Prior to licensing the Original Code under this License, + Netscape has licensed third party code for use in Netscape's + Branded Code. To the extent that Netscape is limited + contractually from making such third party code available + under this License, Netscape may choose to reintegrate such + code into Covered Code without being required to distribute + such code in Source Code form, even if such code would + otherwise be considered ''Modifications'' under this + License. + + V. Use of Modifications and Covered Code by Initial + Developer. V.1. In General. The obligations of Section 3 + apply to Netscape, except to the extent specified in this + Amendment, Section V.2 and V.3. + + V.2. Other Products. Netscape may include Covered Code + in products other than the Netscape's Branded Code + which are released by Netscape during the two (2) years + following the release date of the Original Code, + without such additional products becoming subject to + the terms of this License, and may license such + additional products on different terms from those + contained in this License. + + V.3. Alternative Licensing. Netscape may license the + Source Code of Netscape's Branded Code, including + Modifications incorporated therein, without such + Netscape Branded Code becoming subject to the terms of + this License, and may license such Netscape Branded + Code on different terms from those contained in this + License. + + VI. Litigation. Notwithstanding the limitations of Section + 11 above, the provisions regarding litigation in Section + 11(a), (b) and (c) of the License shall apply to all + disputes relating to this License. + + EXHIBIT A-Netscape Public License. + + ''The contents of this file are subject to the Netscape + 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/NPL/ + + 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 Communicator client code, + released March 31, 1998. + + The Initial Developer of the Original Code is Netscape + Communications Corporation. Portions created by Netscape + are Copyright (C) 1998-1999 Netscape Communications + Corporation. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under + the terms of the _____ license (the ?[___] License?), in + which case the provisions of [______] License are applicable + instead of those above. If you wish to allow use of your + version of this file only under the terms of the [____] + License and not to allow others to use your version of this + file under the NPL, indicate your decision by deleting the + provisions above and replace them with the notice and other + provisions required by the [___] License. If you do not + delete the provisions above, a recipient may use your + version of this file under either the NPL or the [___] + License." + + +Copyright © 1998 The Mozilla Organization. diff --git a/mozilla/extensions/xmlterm/doc/Portability b/mozilla/extensions/xmlterm/doc/Portability new file mode 100644 index 00000000000..511820c167d --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/Portability @@ -0,0 +1,36 @@ +Portability issues +--------------------- + +16 Sep 1999 + +Much of the XMLterm code is cross-platform. Implementation features that +affect portability at the moment are: + +1. Main event handling: + By default, the present implementation of XMLterm directly uses a GTK + call to set up a handler for XMLterm output events. This can be disabled + by setting NO_CALLBACK=1 in the make command line, and calling the + method mozIXMLTermShell::Poll() frequently to poll for readable output + from LineTerm. + (A better event/callback mechanism needs to be implemented.) + +2. pseudo-TTY (PTY) operations: + The PTY interface for XMLterm is currently implemented only for + two platforms, Linux and Solaris. At some point, the PTY interface + should be ported to most Unix platforms. On platforms where PTY + operations are not implemented, the cross-platform NSPR process mechanism + is used to create a "slave" process. However, this process uses NSPR + pipes for communication, which prevents the use of terminal control + characters such as the most usefule Control-C. (Is there a way around + this restriction?) + + What about Windows? It should be possible to use XMLterm even under Windows, + using the NSPR process/pipe functions for communication and + using the Cygwin utilities to simulate the Unix environment. + +3. The lightweight GeckoTerm uses GTK. + +4. The "unistring" module uses wchar functions which do not always have + the same names. + +-- diff --git a/mozilla/extensions/xmlterm/doc/README b/mozilla/extensions/xmlterm/doc/README new file mode 100644 index 00000000000..9851f503239 --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/README @@ -0,0 +1,12 @@ +doc --- Some implementation notes and documentation + +This directory contains some rudimentary documentation and notes. +See the README file in the "base" directory (../base/README) for a brief +overview of XMLterm code architecture + +For a discussion of XMLterm from the user's point of view, check the XMLterm +home page at . + +Eventually, an XMLterm project page at mozilla.org + will contain a description +of XMLterm architecture from a Mozilla developer's point of view. diff --git a/mozilla/extensions/xmlterm/doc/SlowDOMBug b/mozilla/extensions/xmlterm/doc/SlowDOMBug new file mode 100644 index 00000000000..c6ba281cc5f --- /dev/null +++ b/mozilla/extensions/xmlterm/doc/SlowDOMBug @@ -0,0 +1,22 @@ +12 Sep 1999 + +Appending each output line separately, separated by
elements, to a +displayed HTML document seems to be rather slow. See the file +base/mozXMLTermSession.cpp + +As a workaround, multiple output lines are batched into a single
+element. This will basically only work for plain text output, without markup.
+To disable this workaround and expose the "bug", create the XMLterm libraries
+as described in the INSTALL file. Then execute the following to make the
+"buggy" libraries:
+
+cd base
+rm mozXMLTermSession.o
+make NO_WORKAROUND=1 mozXMLTermSession.o
+make libs
+
+(If you are using the "gterm" executable, you will need to re-make it as
+well)
+
+Now execute any command which produces several lines of output in an
+XMLterm window.
diff --git a/mozilla/extensions/xmlterm/doc/XMLterm_LICENSE b/mozilla/extensions/xmlterm/doc/XMLterm_LICENSE
new file mode 100644
index 00000000000..bcaf8bcb7a4
--- /dev/null
+++ b/mozilla/extensions/xmlterm/doc/XMLterm_LICENSE
@@ -0,0 +1,19 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is XMLterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ */
diff --git a/mozilla/extensions/xmlterm/doc/lineterm_LICENSE b/mozilla/extensions/xmlterm/doc/lineterm_LICENSE
new file mode 100644
index 00000000000..b50a3aee862
--- /dev/null
+++ b/mozilla/extensions/xmlterm/doc/lineterm_LICENSE
@@ -0,0 +1,31 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is lineterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ * 
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License (the "GPL"), in which case
+ * the provisions of the GPL are applicable instead of
+ * those above. If you wish to allow use of your version of this
+ * file only under the terms of the GPL and not to allow
+ * others to use your version of this file under the MPL, indicate
+ * your decision by deleting the provisions above and replace them
+ * with the notice and other provisions required by the GPL.
+ * If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
diff --git a/mozilla/extensions/xmlterm/geckoterm/Makefile.in b/mozilla/extensions/xmlterm/geckoterm/Makefile.in
new file mode 100644
index 00000000000..5da3a10cdf9
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/Makefile.in
@@ -0,0 +1,109 @@
+#!gmake
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "MPL"); you may not use this file
+# except in compliance with the MPL. You may obtain a copy of
+# the MPL at http://www.mozilla.org/MPL/
+# 
+# Software distributed under the MPL is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the MPL for the specific language governing
+# rights and limitations under the MPL.
+# 
+# The Original Code is lineterm.
+# 
+# The Initial Developer of the Original Code is Ramalingam Saravanan.
+# Portions created by Ramalingam Saravanan  are
+# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+# 
+# Contributor(s):
+# 
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License (the "GPL"), in which case
+# the provisions of the GPL are applicable instead of
+# those above. If you wish to allow use of your version of this
+# file only under the terms of the GPL and not to allow
+# others to use your version of this file under the MPL, indicate
+# your decision by deleting the provisions above and replace them
+# with the notice and other provisions required by the GPL.
+# If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+# makefile for xmlterm/geckoterm directory (stand alone XMLterm)
+
+ifdef STAND_ALONE
+DEPTH      = ..
+topsrcdir  = ..
+srcdir     = .
+include $(topsrcdir)/config/autoconf.mk
+else
+DEPTH      = ../../..
+topsrcdir  = @top_srcdir@
+srcdir     = @srcdir@
+include $(DEPTH)/config/autoconf.mk
+endif
+
+
+# Debug option
+DEBUG = 1
+
+# Program
+PROGRAM = xmlterm
+
+# Exported header files
+EXPORTS = mozISimpleContainer.h
+
+# Defines
+DEFINES = $(TK_CFLAGS)
+
+# C++ source files
+CPPSRCS = nsSetupRegistry.cpp  \
+	mozSimpleContainer.cpp \
+	mozGeckoTerm.cpp       \
+	nsTimer.cpp            \
+	$(NULL)
+
+# Libraries to be linked
+GTK_GLUE		= -lgtksuperwin
+
+XP_DIST_LIBS		= \
+			-lraptorgfx \
+			-lmozjs \
+			-lxpcom \
+			$(JSJ_LIB) \
+			$(NULL)
+
+XP_NS_UNDERBAR_CRAP	= \
+			$(MOZ_NECKO_UTIL_LIBS) \
+			$(MOZ_TIMER_LIBS) \
+			$(MOZ_WIDGET_SUPPORT_LIBS) \
+			$(NULL)
+
+XP_LIBS			= \
+			$(XP_NS_UNDERBAR_CRAP) \
+			$(XP_DIST_LIBS) \
+			$(NSPR_LIBS) \
+			$(NULL)
+
+ifdef DYNAMIC_LINK
+# NOTE: a soft link needs to be created for libxmlterm.so in dist/bin
+XMLTERM_LIBS = -lxmlterm
+else
+# Statically link the entire XMLTERM library
+XMLTERM_LIBS = ../base/libxmlterm.a
+endif
+
+LIBS =		        \
+        $(GTK_GLUE)     \
+	$(XP_LIBS)      \
+	$(TK_LIBS)      \
+	$(XMLTERM_LIBS) \
+	$(NULL)
+
+include $(topsrcdir)/config/config.mk
+
+include ../config/xmlterm_config.mk
+
+include $(topsrcdir)/config/rules.mk
diff --git a/mozilla/extensions/xmlterm/geckoterm/README b/mozilla/extensions/xmlterm/geckoterm/README
new file mode 100644
index 00000000000..03dda47848b
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/README
@@ -0,0 +1,24 @@
+geckoterm --- Stand-alone version of XMLterm using Gecko
+
+This directory contains the files used to create the stand-alone XMLterm
+executable, which runs independent of the browser. This would be the preferred
+way to use XMLterm, so that it runs as a separate process and will not
+crash if the browser does.
+
+28 Nov 1999
+
+FILES
+=====
+
+mozGeckoTerm.cpp        Main program for stand-alone "xmlterm" executable
+                          Uses GTK to create window
+                          Uses mozIXMLTerminal to create XMLterm
+                          Uses mozISimpleContainer for web shell container
+
+mozISimpleContainer.h   Simple WebShell container interface
+mozSimpleContainer.cpp  Implementation of mozISimpleContainer
+
+nsSetupRegistry.cpp     Just a copy of viewer's nSetupRegistry
+nsTimer.cpp             Implementation of timers using Gtk timer facility
+
+--
diff --git a/mozilla/extensions/xmlterm/geckoterm/default_prefs.js b/mozilla/extensions/xmlterm/geckoterm/default_prefs.js
new file mode 100755
index 00000000000..d7f493df6af
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/default_prefs.js
@@ -0,0 +1,3 @@
+# Mozilla User Preferences
+// This is a generated file!
+
diff --git a/mozilla/extensions/xmlterm/geckoterm/default_prefs.js.sav b/mozilla/extensions/xmlterm/geckoterm/default_prefs.js.sav
new file mode 100755
index 00000000000..1a4c5768b00
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/default_prefs.js.sav
@@ -0,0 +1,5 @@
+# Mozilla User Preferences
+// This is a generated file!
+pref("security.checkxpconnect", true);
+pref("security.policy.default.htmldocument.cookie", "sameOrigin");
+
diff --git a/mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp b/mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp
new file mode 100644
index 00000000000..b87f67e41f2
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp
@@ -0,0 +1,337 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is XMLterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ */
+
+// mozGeckoTerm.cpp: Stand-alone implementation of XMLterm using GTK
+//                   and the Mozilla Layout engine
+
+#include "stdio.h"
+
+#include 
+
+#if 0 // USE_SUPERWIN
+#include "gtkmozarea.h"
+#include "gdksuperwin.h"
+#endif // USE_SUPERWIN 
+
+#include "nscore.h"
+#include "nsCOMPtr.h"
+
+#include "nsRepository.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsIEventQueueService.h"
+#include "nsIPref.h"
+
+#include "mozXMLTermUtils.h"
+#include "mozISimpleContainer.h"
+#include "mozIXMLTerminal.h"
+#include "mozIXMLTermStream.h"
+
+#define XMLTERM_DLL   "libxmlterm"MOZ_DLL_SUFFIX
+
+static NS_DEFINE_IID(kISupportsIID,          NS_ISUPPORTS_IID);
+static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
+static NS_DEFINE_IID(kEventQueueServiceCID,  NS_EVENTQUEUESERVICE_CID);
+static NS_DEFINE_IID(kIPrefIID,              NS_IPREF_IID);
+static NS_DEFINE_CID(kPrefCID,               NS_PREF_CID);
+static NS_DEFINE_IID(kLineTermCID,           MOZLINETERM_CID);
+static NS_DEFINE_IID(kXMLTermShellCID,       MOZXMLTERMSHELL_CID);
+
+extern "C" void NS_SetupRegistry();
+
+nsCOMPtr gSimpleContainer = nsnull;
+nsCOMPtr gXMLTerminal = nsnull;
+
+/** Processes thread events */
+static void event_processor_callback(gpointer data,
+                                     gint source,
+                                     GdkInputCondition condition)
+{
+  nsIEventQueue *eventQueue = (nsIEventQueue*)data;
+  eventQueue->ProcessPendingEvents();
+  //fprintf(stderr, "event_processor_callback:\n");
+  return;
+}
+
+
+static void event_processor_configure(GtkWidget *window,
+                                      GdkEvent  *event,
+                                      GtkWidget *termWidget)
+{
+  GtkAllocation *alloc = >K_WIDGET(termWidget)->allocation;
+
+  //fprintf(stderr, "event_processor_configure:\n");
+
+  // Resize web shell window
+  gSimpleContainer->Resize(alloc->width, alloc->height);
+
+  return;
+}
+
+/** Cleans up and exits */
+static gint event_processor_quit(gpointer data,
+                                 gint source,
+                                 GdkInputCondition condition)
+{
+  fprintf(stderr, "event_processor_quit:\n");
+
+  if (gXMLTerminal) {
+    // Finalize XMLTerm and release owning reference to it
+    gXMLTerminal->Finalize();
+    gXMLTerminal = nsnull;
+  }
+
+  // Delete reference to container
+  gSimpleContainer = nsnull;
+
+  gtk_main_quit();
+  return TRUE;
+}
+
+
+int main( int argc, char *argv[] )
+{
+  GtkWidget *mainWin = NULL;
+  GtkWidget *vertBox = NULL;
+  GtkWidget *horBox = NULL;
+  GtkWidget *testButton = NULL;
+#if 0 // USE_SUPERWIN
+  GdkSuperWin *termWidget = NULL;
+  GtkWidget *mozArea;
+#else // USE_SUPERWIN 
+  GtkWidget *termWidget = NULL;
+#endif // !USE_SUPERWIN 
+
+  nsIEventQueue *mEventQueue = nsnull;
+
+  nsresult result = NS_OK;
+
+  // Set up registry
+  NS_SetupRegistry();
+
+  // Register XMLTermShell and LineTerm interfaces
+  result = nsComponentManager::RegisterComponentLib(kLineTermCID,NULL,NULL,
+                                           XMLTERM_DLL, PR_FALSE, PR_FALSE);
+  printf("mozGeckoTerm: registered LineTerm, result=0x%x\n", result);
+
+  result = nsComponentManager::RegisterComponentLib(kXMLTermShellCID,NULL,NULL,
+                                           XMLTERM_DLL, PR_FALSE, PR_FALSE);
+  printf("mozGeckoTerm: registered XMLTermShell, result=0x%x\n", result);
+
+  // Get the event queue service 
+  NS_WITH_SERVICE(nsIEventQueueService, eventQService,
+                  kEventQueueServiceCID, &result);
+  if (NS_FAILED(result)) {
+    NS_ASSERTION("Could not obtain event queue service", PR_FALSE);
+    return result;
+  }
+
+  // Get the event queue for the thread.
+  result = eventQService->GetThreadEventQueue(PR_GetCurrentThread(),
+                                              &mEventQueue);
+
+  if (!mEventQueue) {
+    // Create the event queue for the thread
+    result = eventQService->CreateThreadEventQueue();
+    if (NS_FAILED(result)) {
+      NS_ASSERTION("Could not create the thread event queue", PR_FALSE);
+      return result;
+  }
+
+    // Get the event queue for the thread
+    result = eventQService->GetThreadEventQueue(PR_GetCurrentThread(), &mEventQueue);
+    if (NS_FAILED(result)) {
+      NS_ASSERTION("Could not obtain the thread event queue", PR_FALSE);
+      return result;
+    }
+  }
+
+  // Creat pref object
+  nsCOMPtr mPref = nsnull;
+  result = nsComponentManager::CreateInstance(kPrefCID, NULL, 
+                                             kIPrefIID, getter_AddRefs(mPref));
+  if (NS_FAILED(result)) {
+    NS_ASSERTION("Failed to create nsIPref object", PR_FALSE);
+    return result;
+  }
+
+  mPref->StartUp();
+  mPref->ReadUserPrefs();
+
+  // Initialize GTK library
+  gtk_set_locale();
+
+  gtk_init(&argc, &argv);
+
+  gdk_rgb_init();
+
+  mainWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_default_size( GTK_WINDOW(mainWin), 600, 400);
+  gtk_window_set_title(GTK_WINDOW(mainWin), "XMLterm");
+
+  // VBox top level
+  vertBox = gtk_vbox_new(FALSE, 0);
+  gtk_container_add(GTK_CONTAINER(mainWin), vertBox);
+  gtk_widget_show(vertBox);
+
+  // HBox for toolbar
+  horBox = gtk_hbox_new(FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(vertBox), horBox, FALSE, FALSE, 0);
+
+  testButton = gtk_button_new_with_label("Test");
+  gtk_box_pack_start (GTK_BOX (horBox), testButton, FALSE, FALSE, 0);
+  gtk_widget_show(testButton);
+
+  gtk_widget_show(horBox);
+
+#if 0 // USE_SUPERWIN
+  gtk_window_set_policy(GTK_WINDOW(mainWin), PR_TRUE, PR_TRUE, PR_FALSE);
+  mozArea = gtk_mozarea_new();
+  gtk_container_add(GTK_CONTAINER(mainWin), mozArea);
+  gtk_widget_realize(GTK_WIDGET(mozArea));
+  termWidget = GTK_MOZAREA(mozArea)->superwin;
+
+#else // USE_SUPERWIN 
+
+  // XMLterm layout widget
+  termWidget = gtk_layout_new(NULL, NULL);
+  GTK_WIDGET_SET_FLAGS(termWidget, GTK_CAN_FOCUS);
+  gtk_widget_set_app_paintable(termWidget, TRUE);
+
+  gtk_box_pack_start(GTK_BOX(vertBox), termWidget, TRUE, TRUE, 0);
+  gtk_widget_show_all(termWidget);
+
+  gtk_widget_show(mainWin);
+#endif // !USE_SUPERWIN 
+
+  // Configure event handler
+  gtk_signal_connect_after( GTK_OBJECT(mainWin), "configure_event",
+                            GTK_SIGNAL_FUNC(event_processor_configure),
+                            termWidget);
+
+  // Cleanup and exit when window is deleted
+  gtk_signal_connect( GTK_OBJECT(mainWin), "delete_event",
+                      GTK_SIGNAL_FUNC(event_processor_quit),
+                      NULL);
+  
+  // Check for input in the events queue file descriptor
+  gdk_input_add(mEventQueue->GetEventQueueSelectFD(),
+                GDK_INPUT_READ,
+                event_processor_callback,
+                mEventQueue);
+
+  // Create simple container
+  result = NS_NewSimpleContainer(getter_AddRefs(gSimpleContainer));
+
+  if (NS_FAILED(result) || !gSimpleContainer) {
+    return result; // Exit main program
+  }
+
+  // Determine window dimensions
+  GtkAllocation *alloc = >K_WIDGET(termWidget)->allocation;
+    
+  // Initialize container to hold a web shell
+  result = gSimpleContainer->Init((nsNativeWidget *) termWidget,
+                              alloc->width, alloc->height, mPref);
+
+  if (NS_FAILED(result)) {
+    return result; // Exit main program
+  }
+
+  // Get reference to web shell embedded in a simple container
+  nsCOMPtr webShell;
+  result = gSimpleContainer->GetWebShell(*getter_AddRefs(webShell));
+
+  if (NS_FAILED(result) || !webShell) {
+    return result; // Exit main program
+  }
+
+#if 0
+  // TEMPORARY: Testing mozIXMLTermStream
+  nsAutoString streamData = "Stream Title"
+                            ""
+                            "Stream Body "
+                            "Clik"
+                            "";
+
+  nsCOMPtr stream;
+  result = NS_NewXMLTermStream(getter_AddRefs(stream));
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to create stream\n");
+    return result;
+  }
+
+  nsCOMPtr outerDOMWindow;
+  result = mozXMLTermUtils::ConvertWebShellToDOMWindow(webShell,
+                                              getter_AddRefs(outerDOMWindow));
+
+  if (NS_FAILED(result) || !outerDOMWindow)
+    return NS_ERROR_FAILURE;
+
+  result = stream->Open(outerDOMWindow, nsnull, "chrome://dummy", "text/html",
+                        0);
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to open stream\n");
+    return result;
+  }
+
+  result = stream->Write(streamData.GetUnicode());
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to write to stream\n");
+    return result;
+  }
+
+  result = stream->Close();
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to close stream\n");
+    return result;
+  }
+#else
+  // Load initial XMLterm document
+  result = gSimpleContainer->LoadURL(
+                             "chrome://xmlterm/content/xmlterm.html");
+  if (NS_FAILED(result))
+    return result;
+#endif
+
+#if 0
+  // Create an XMLTERM and attach to web shell
+  result = NS_NewXMLTerminal(getter_AddRefs(gXMLTerminal));
+
+  if(!gXMLTerminal)
+    result = NS_ERROR_OUT_OF_MEMORY;
+
+  if (NS_SUCCEEDED(result)) {
+    result = gXMLTerminal->Init(webShell, nsnull, nsnull);
+  }
+#endif
+
+  // Discard reference to web shell
+  webShell = nsnull;
+
+  // GTK event loop
+  gtk_main();
+
+  NS_IF_RELEASE(mEventQueue);
+
+  return 0;
+}
diff --git a/mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp.sav b/mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp.sav
new file mode 100644
index 00000000000..5dd098289bf
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/mozGeckoTerm.cpp.sav
@@ -0,0 +1,318 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is XMLterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ */
+
+// mozGeckoTerm.cpp: Stand-alone implementation of XMLterm using GTK
+//                   and the Mozilla Layout engine
+
+#include "stdio.h"
+
+#include 
+
+#include "nscore.h"
+#include "nsCOMPtr.h"
+
+#include "nsRepository.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsIEventQueueService.h"
+#include "nsIPref.h"
+
+#include "mozXMLTermUtils.h"
+#include "mozISimpleContainer.h"
+#include "mozIXMLTerminal.h"
+#include "mozIXMLTermStream.h"
+
+#define XMLTERM_DLL   "libxmlterm"MOZ_DLL_SUFFIX
+
+static NS_DEFINE_IID(kISupportsIID,          NS_ISUPPORTS_IID);
+static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
+static NS_DEFINE_IID(kEventQueueServiceCID,  NS_EVENTQUEUESERVICE_CID);
+static NS_DEFINE_IID(kIPrefIID,              NS_IPREF_IID);
+static NS_DEFINE_CID(kPrefCID,               NS_PREF_CID);
+static NS_DEFINE_IID(kLineTermCID,           MOZLINETERM_CID);
+static NS_DEFINE_IID(kXMLTermShellCID,       MOZXMLTERMSHELL_CID);
+
+extern "C" void NS_SetupRegistry();
+
+nsCOMPtr gSimpleContainer = nsnull;
+nsCOMPtr gXMLTerminal = nsnull;
+
+/** Processes thread events */
+static void event_processor_callback(gpointer data,
+                                     gint source,
+                                     GdkInputCondition condition)
+{
+  nsIEventQueue *eventQueue = (nsIEventQueue*)data;
+  eventQueue->ProcessPendingEvents();
+  //fprintf(stderr, "event_processor_callback:\n");
+  return;
+}
+
+
+static void event_processor_configure(GtkWidget *window,
+                                      GdkEvent  *event,
+                                      GtkWidget *termWidget)
+{
+  GtkAllocation *alloc = >K_WIDGET(termWidget)->allocation;
+
+  //fprintf(stderr, "event_processor_configure:\n");
+
+  // Resize web shell window
+  gSimpleContainer->Resize(alloc->width, alloc->height);
+
+  return;
+}
+
+/** Cleans up and exits */
+static gint event_processor_quit(gpointer data,
+                                 gint source,
+                                 GdkInputCondition condition)
+{
+  fprintf(stderr, "event_processor_quit:\n");
+
+  if (gXMLTerminal) {
+    // Finalize XMLTerm and release owning reference to it
+    gXMLTerminal->Finalize();
+    gXMLTerminal = nsnull;
+  }
+
+  // Delete reference to container
+  gSimpleContainer = nsnull;
+
+  gtk_main_quit();
+  return TRUE;
+}
+
+
+int main( int argc, char *argv[] )
+{
+  GtkWidget *mainWin = NULL;
+  GtkWidget *vertBox = NULL;
+  GtkWidget *horBox = NULL;
+  GtkWidget *testButton = NULL;
+  GtkWidget *termWidget = NULL;
+
+  nsIEventQueue *mEventQueue = nsnull;
+
+  nsresult result = NS_OK;
+
+  // Set up registry
+  NS_SetupRegistry();
+
+  // Register XMLTermShell and LineTerm interfaces
+  result = nsComponentManager::RegisterComponentLib(kLineTermCID,NULL,NULL,
+                                           XMLTERM_DLL, PR_FALSE, PR_FALSE);
+  printf("mozGeckoTerm: registered LineTerm, result=0x%x\n", result);
+
+  result = nsComponentManager::RegisterComponentLib(kXMLTermShellCID,NULL,NULL,
+                                           XMLTERM_DLL, PR_FALSE, PR_FALSE);
+  printf("mozGeckoTerm: registered XMLTermShell, result=0x%x\n", result);
+
+  // Get the event queue service 
+  NS_WITH_SERVICE(nsIEventQueueService, eventQService,
+                  kEventQueueServiceCID, &result);
+  if (NS_FAILED(result)) {
+    NS_ASSERTION("Could not obtain event queue service", PR_FALSE);
+    return result;
+  }
+
+  // Get the event queue for the thread.
+  result = eventQService->GetThreadEventQueue(PR_GetCurrentThread(),
+                                              &mEventQueue);
+
+  if (!mEventQueue) {
+    // Create the event queue for the thread
+    result = eventQService->CreateThreadEventQueue();
+    if (NS_FAILED(result)) {
+      NS_ASSERTION("Could not create the thread event queue", PR_FALSE);
+      return result;
+  }
+
+    // Get the event queue for the thread
+    result = eventQService->GetThreadEventQueue(PR_GetCurrentThread(), &mEventQueue);
+    if (NS_FAILED(result)) {
+      NS_ASSERTION("Could not obtain the thread event queue", PR_FALSE);
+      return result;
+    }
+  }
+
+  // Creat pref object
+  nsCOMPtr mPref = nsnull;
+  result = nsComponentManager::CreateInstance(kPrefCID, NULL, 
+                                             kIPrefIID, getter_AddRefs(mPref));
+  if (NS_FAILED(result)) {
+    NS_ASSERTION("Failed to create nsIPref object", PR_FALSE);
+    return result;
+  }
+
+  mPref->StartUp();
+  mPref->ReadUserPrefs();
+
+  // Initialize GTK library
+  gtk_set_locale();
+
+  gtk_init(&argc, &argv);
+
+  gdk_rgb_init();
+
+  mainWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_default_size( GTK_WINDOW(mainWin), 600, 400);
+  gtk_window_set_title(GTK_WINDOW(mainWin), "XMLterm");
+  
+  // VBox top level
+  vertBox = gtk_vbox_new(FALSE, 0);
+  gtk_container_add(GTK_CONTAINER(mainWin), vertBox);
+  gtk_widget_show(vertBox);
+
+  // HBox for toolbar
+  horBox = gtk_hbox_new(FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(vertBox), horBox, FALSE, FALSE, 0);
+
+  testButton = gtk_button_new_with_label("Test");
+  gtk_box_pack_start (GTK_BOX (horBox), testButton, FALSE, FALSE, 0);
+  gtk_widget_show(testButton);
+
+  gtk_widget_show(horBox);
+
+  // XMLterm layout widget
+  termWidget = gtk_layout_new(NULL, NULL);
+  GTK_WIDGET_SET_FLAGS(termWidget, GTK_CAN_FOCUS);
+  gtk_widget_set_app_paintable(termWidget, TRUE);
+
+  gtk_box_pack_start(GTK_BOX(vertBox), termWidget, TRUE, TRUE, 0);
+  gtk_widget_show_all(termWidget);
+
+  gtk_widget_show(mainWin);
+
+
+  // Configure event handler
+  gtk_signal_connect_after( GTK_OBJECT(mainWin), "configure_event",
+                            GTK_SIGNAL_FUNC(event_processor_configure),
+                            termWidget);
+
+  // Cleanup and exit when window is deleted
+  gtk_signal_connect( GTK_OBJECT(mainWin), "delete_event",
+                      GTK_SIGNAL_FUNC(event_processor_quit),
+                      NULL);
+  
+  // Check for input in the events queue file descriptor
+  gdk_input_add(mEventQueue->GetEventQueueSelectFD(),
+                GDK_INPUT_READ,
+                event_processor_callback,
+                mEventQueue);
+
+  // Create simple container
+  result = NS_NewSimpleContainer(getter_AddRefs(gSimpleContainer));
+
+  if (NS_FAILED(result) || !gSimpleContainer) {
+    return result; // Exit main program
+  }
+
+  // Determine window dimensions
+  GtkAllocation *alloc = >K_WIDGET(termWidget)->allocation;
+    
+  // Initialize container it to hold a web shell
+  result = gSimpleContainer->Init((nsNativeWidget *) termWidget,
+                              alloc->width, alloc->height, mPref);
+
+  if (NS_FAILED(result)) {
+    return result; // Exit main program
+  }
+
+  // Get reference to web shell embedded in a simple container
+  nsCOMPtr webShell;
+  result = gSimpleContainer->GetWebShell(*getter_AddRefs(webShell));
+
+  if (NS_FAILED(result) || !webShell) {
+    return result; // Exit main program
+  }
+
+#if 0
+  // TEMPORARY: Testing mozIXMLTermStream
+  nsAutoString streamData = "Stream Title"
+                            ""
+                            "Stream Body "
+                            "Clik"
+                            "";
+
+  nsCOMPtr stream;
+  result = NS_NewXMLTermStream(getter_AddRefs(stream));
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to create stream\n");
+    return result;
+  }
+
+  nsCOMPtr outerDOMWindow;
+  result = mozXMLTermUtils::ConvertWebShellToDOMWindow(webShell,
+                                              getter_AddRefs(outerDOMWindow));
+
+  if (NS_FAILED(result) || !outerDOMWindow)
+    return NS_ERROR_FAILURE;
+
+  result = stream->Open(outerDOMWindow, nsnull, "chrome://dummy", "text/html",
+                        0);
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to open stream\n");
+    return result;
+  }
+
+  result = stream->Write(streamData.GetUnicode());
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to write to stream\n");
+    return result;
+  }
+
+  result = stream->Close();
+  if (NS_FAILED(result)) {
+    fprintf(stderr, "mozGeckoTerm: Failed to close stream\n");
+    return result;
+  }
+#else
+  // Load initial XMLterm document
+  result = gSimpleContainer->LoadURL(
+                             "chrome://xmlterm/content/xmlterm.html");
+  if (NS_FAILED(result))
+    return result;
+#endif
+
+#if 0
+  // Create an XMLTERM and attach to web shell
+  result = NS_NewXMLTerminal(getter_AddRefs(gXMLTerminal));
+
+  if(!gXMLTerminal)
+    result = NS_ERROR_OUT_OF_MEMORY;
+
+  if (NS_SUCCEEDED(result)) {
+    result = gXMLTerminal->Init(webShell, nsnull, nsnull);
+  }
+#endif
+
+  // Discard reference to web shell
+  webShell = nsnull;
+
+  // GTK event loop
+  gtk_main();
+
+  NS_IF_RELEASE(mEventQueue);
+
+  return 0;
+}
diff --git a/mozilla/extensions/xmlterm/geckoterm/mozISimpleContainer.h b/mozilla/extensions/xmlterm/geckoterm/mozISimpleContainer.h
new file mode 100644
index 00000000000..bd0cfd40b7d
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/mozISimpleContainer.h
@@ -0,0 +1,134 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is XMLterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ */
+
+// mozISimpleContainer.h: a simple WebShell container interface
+//                        for use in simple programs using the layout engine
+//                        (unregistered interface)
+
+#ifndef mozISimpleContainer_h___
+#define mozISimpleContainer_h___
+
+#include "nscore.h"
+
+#include "nsISupports.h"
+#include "nsIWebShell.h"
+#include "nsIPref.h"
+#include "nsIPresShell.h"
+#include "nsIDOMDocument.h"
+
+/* starting interface: mozISimpleContainer */
+
+/* {0eb82bF0-43a2-11d3-8e76-006008948af5} */
+#define MOZISIMPLE_CONTAINER_IID_STR "0eb82bF0-43a2-11d3-8e76-006008948af5"
+#define MOZISIMPLE_CONTAINER_IID \
+  {0x0eb82bF0, 0x43a2, 0x11d3, \
+    { 0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5 }}
+
+class mozISimpleContainer : public nsIWebShellContainer {
+
+public:
+  NS_DEFINE_STATIC_IID_ACCESSOR(MOZISIMPLE_CONTAINER_IID)
+
+  // nsIWebShellContainer interface
+  NS_IMETHOD WillLoadURL(nsIWebShell* aShell,
+                         const PRUnichar* aURL,
+                         nsLoadType aReason) = 0;
+ 
+  NS_IMETHOD BeginLoadURL(nsIWebShell* aShell,
+                          const PRUnichar* aURL) = 0;
+ 
+
+  NS_IMETHOD ProgressLoadURL(nsIWebShell* aShell,
+                             const PRUnichar* aURL,
+                             PRInt32 aProgress,
+                             PRInt32 aProgressMax) = 0;
+ 
+  NS_IMETHOD EndLoadURL(nsIWebShell* aShell,
+                        const PRUnichar* aURL,
+                        nsresult aStatus) = 0;
+ 
+  NS_IMETHOD NewWebShell(PRUint32 aChromeMask,
+                         PRBool aVisible,
+                         nsIWebShell *&aNewWebShell) = 0;
+  
+  NS_IMETHOD FindWebShellWithName(const PRUnichar* aName,
+                                  nsIWebShell*& aResult) = 0;
+  
+  NS_IMETHOD ContentShellAdded(nsIWebShell* aChildShell,
+                               nsIContent* frameNode) = 0;
+
+  NS_IMETHOD CreatePopup(nsIDOMElement* aElement,
+                         nsIDOMElement* aPopupContent, 
+                         PRInt32 aXPos, PRInt32 aYPos, 
+                         const nsString& aPopupType,
+                         const nsString& anAnchorAlignment,
+                         const nsString& aPopupAlignment,
+                         nsIDOMWindow* aWindow, nsIDOMWindow** outPopup) = 0;
+
+  NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell,
+                            PRBool& aFocusTaken) = 0;
+
+  // other
+
+  /** Initializes simple container for native window widget
+   * @param aNativeWidget native window widget (e.g., GtkWidget)
+   * @param width window width (pixels)
+   * @param height window height (pixels)
+   * @param aPref preferences object
+   */
+  NS_IMETHOD Init(nsNativeWidget aNativeWidget,
+                  PRInt32 width, PRInt32 height,
+                  nsIPref* aPref) = 0;
+
+  /** Resizes container to new dimensions
+   * @param width new window width (pixels)
+   * @param height new window height (pixels)
+   */
+  NS_IMETHOD Resize(PRInt32 aWidth, PRInt32 aHeight) = 0;
+
+  /** Loads specified URL into container
+   * @param aURL URL string
+   */
+  NS_IMETHOD LoadURL(const char* aURL) = 0;
+
+  /** Gets web shell in container
+   * @param aWebShell (output) web shell object
+   */
+  NS_IMETHOD GetWebShell(nsIWebShell*& aWebShell) = 0;
+
+  /** Gets DOM document in container
+   * @param aDocument (output) DOM document
+   */
+  NS_IMETHOD GetDocument(nsIDOMDocument*& aDocument) = 0;
+
+  /** Gets presentation shell associated with container
+   * @param aPresShell (output) presentation shell
+   */
+  NS_IMETHOD GetPresShell(nsIPresShell*& aPresShell) = 0;
+};
+
+#define MOZSIMPLE_CONTAINER_CID              \
+{ /* 0eb82bF1-43a2-11d3-8e76-006008948af5 */ \
+   0x0eb82bF1, 0x43a2, 0x11d3,               \
+{0x8e, 0x76, 0x00, 0x60, 0x08, 0x94, 0x8a, 0xf5} }
+extern nsresult
+NS_NewSimpleContainer(mozISimpleContainer** aSimpleContainer);
+
+#endif /* mozISimpleContainer_h___ */
diff --git a/mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.cpp b/mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.cpp
new file mode 100644
index 00000000000..7f3a5c00582
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.cpp
@@ -0,0 +1,396 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is XMLterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ */
+
+// mozSimpleContainer.cpp: Implements mozISimpleContainer
+// which provides a WebShell container for use in simple programs
+// using the layout engine
+
+#include "nscore.h"
+#include "nsCOMPtr.h"
+
+#include "nsRepository.h"
+
+#include "nsISupports.h"
+
+#include "nsIWebShell.h"
+#include "nsIDOMDocument.h"
+#include "nsIDocumentViewer.h"
+#include "nsIPresContext.h"
+#include "nsIPresShell.h"
+#include "nsIDocument.h"
+
+#include "mozSimpleContainer.h"
+
+
+// Define Class IDs
+static NS_DEFINE_IID(kWebShellCID,           NS_WEB_SHELL_CID);
+
+// Define Interface IDs
+static NS_DEFINE_IID(kISupportsIID,          NS_ISUPPORTS_IID);
+static NS_DEFINE_IID(kIWebShellIID,          NS_IWEB_SHELL_IID);
+static NS_DEFINE_IID(kIDOMDocumentIID,       NS_IDOMDOCUMENT_IID);
+static NS_DEFINE_IID(kIDocumentViewerIID,    NS_IDOCUMENT_VIEWER_IID);
+
+/////////////////////////////////////////////////////////////////////////
+// mozSimpleContainer factory
+/////////////////////////////////////////////////////////////////////////
+
+nsresult
+NS_NewSimpleContainer(mozISimpleContainer** aSimpleContainer)
+{
+    NS_PRECONDITION(aSimpleContainer != nsnull, "null ptr");
+    if (!aSimpleContainer)
+        return NS_ERROR_NULL_POINTER;
+
+    *aSimpleContainer = new mozSimpleContainer();
+    if (! *aSimpleContainer)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    NS_ADDREF(*aSimpleContainer);
+    return NS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// mozSimpleContainer implementation
+/////////////////////////////////////////////////////////////////////////
+
+mozSimpleContainer::mozSimpleContainer() :
+  mWebShell(nsnull)
+{
+  NS_INIT_REFCNT();
+}
+
+
+mozSimpleContainer::~mozSimpleContainer()
+{
+  mWebShell = nsnull;
+}
+
+#define NS_IMPL_ADDREF_TRACE(_class)                         \
+NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void)                \
+{                                                            \
+  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");  \
+  ++mRefCnt;                                                 \
+  fprintf(stderr, "mozSimpleContainer:AddRef, mRefCnt=%d\n", mRefCnt);   \
+  return mRefCnt;                                            \
+}
+
+#define NS_IMPL_RELEASE_TRACE(_class)                  \
+NS_IMETHODIMP_(nsrefcnt) _class::Release(void)         \
+{                                                      \
+  NS_PRECONDITION(0 != mRefCnt, "dup release");        \
+  --mRefCnt;                                           \
+  fprintf(stderr, "mozSimpleContainer:Release, mRefCnt=%d\n", mRefCnt); \
+  if (mRefCnt == 0) {                                  \
+    NS_DELETEXPCOM(this);                              \
+    return 0;                                          \
+  }                                                    \
+  return mRefCnt;                                      \
+}
+
+// Implement AddRef and Release
+NS_IMPL_ADDREF(mozSimpleContainer)
+NS_IMPL_RELEASE(mozSimpleContainer)
+
+
+NS_IMETHODIMP 
+mozSimpleContainer::QueryInterface(REFNSIID aIID,void** aInstancePtr)
+{
+  if (aInstancePtr == NULL) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  // Always NULL result, in case of failure
+  *aInstancePtr = NULL;
+
+  if ( aIID.Equals(kISupportsIID)) {
+    *aInstancePtr = NS_STATIC_CAST(nsISupports*,
+                                   NS_STATIC_CAST(mozISimpleContainer*,this));
+
+  } else if ( aIID.Equals(mozISimpleContainer::GetIID()) ) {
+    *aInstancePtr = NS_STATIC_CAST(mozISimpleContainer*,this);
+
+  } else if ( aIID.Equals(nsIWebShellContainer::GetIID()) ) {
+    *aInstancePtr = NS_STATIC_CAST(nsIWebShellContainer*,this);
+
+  } else {
+    return NS_ERROR_NO_INTERFACE;
+  }
+
+  NS_ADDREF_THIS();
+
+  fprintf(stderr, "mozSimpleContainer::QueryInterface, mRefCnt = %d\n", mRefCnt);
+
+  return NS_OK;
+}
+
+
+/** Initializes simple container for native window widget
+ * @param aNativeWidget native window widget (e.g., GtkWidget)
+ * @param width window width (pixels)
+ * @param height window height (pixels)
+ * @param aPref preferences object
+ */
+NS_IMETHODIMP mozSimpleContainer::Init(nsNativeWidget aNativeWidget,
+                                       PRInt32 width, PRInt32 height,
+                                       nsIPref* aPref)
+{
+  // Create web shell and show it
+  nsresult result = nsRepository::CreateInstance(kWebShellCID, nsnull,
+                                                 kIWebShellIID,
+                                                 getter_AddRefs(mWebShell));
+
+  if (NS_FAILED(result) || !mWebShell) {
+    fprintf(stderr, "Failed to create create web shell\n");
+    return NS_ERROR_FAILURE;
+  }
+  
+  mWebShell->Init(aNativeWidget, 0, 0, width, height);
+
+  mWebShell->SetContainer(this);
+  if (aPref) {
+    mWebShell->SetPrefs(aPref);
+  }
+  mWebShell->Show();
+
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP mozSimpleContainer::WillLoadURL(nsIWebShell* aShell, const PRUnichar* aURL, nsLoadType aReason)
+{
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP mozSimpleContainer::BeginLoadURL(nsIWebShell* aShell, const PRUnichar* aURL)
+{
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP mozSimpleContainer::ProgressLoadURL(nsIWebShell* aShell,
+          const PRUnichar* aURL, PRInt32 aProgress, PRInt32 aProgressMax)
+{
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP mozSimpleContainer::EndLoadURL(nsIWebShell* aShell,
+                                             const PRUnichar* aURL,
+                                             nsresult aStatus)
+{
+  nsCOMPtr selection;
+  nsresult result;
+
+  if (aShell == mWebShell.get()) {
+    nsCOMPtr domDoc;
+    nsCOMPtr presShell;
+
+    result = GetDocument(*getter_AddRefs(domDoc));
+    if (NS_FAILED(result) || !domDoc) return result;
+
+    result = GetPresShell(*getter_AddRefs(presShell));
+    if (NS_FAILED(result) || !presShell) return result;
+  }
+
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP mozSimpleContainer::NewWebShell(PRUint32 aChromeMask,
+                                              PRBool aVisible,
+                                              nsIWebShell*& aNewWebShell)
+{
+  aNewWebShell = nsnull;
+  return NS_ERROR_FAILURE;
+}
+
+
+NS_IMETHODIMP mozSimpleContainer::FindWebShellWithName(const PRUnichar* aName,
+                                                       nsIWebShell*& aResult)
+{
+  aResult = nsnull;
+  nsString aNameStr(aName);
+
+  nsIWebShell *aWebShell;
+    
+  if (NS_OK == GetWebShell(aWebShell)) {
+    const PRUnichar *name;
+    if (NS_OK == aWebShell->GetName(&name)) {
+      if (aNameStr.Equals(name)) {
+        aResult = aWebShell;
+        NS_ADDREF(aResult);
+        return NS_OK;
+      }
+    }      
+  }
+
+  if (NS_OK == aWebShell->FindChildWithName(aName, aResult)) {
+    if (nsnull != aResult) {
+      return NS_OK;
+    }
+  }
+
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP
+mozSimpleContainer::ContentShellAdded(nsIWebShell* aChildShell,
+                                  nsIContent* frameNode)
+{
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP
+mozSimpleContainer::CreatePopup(nsIDOMElement* aElement, 
+                            nsIDOMElement* aPopupContent, 
+                            PRInt32 aXPos, PRInt32 aYPos, 
+                            const nsString& aPopupType,
+                            const nsString& anAnchorAlignment,
+                            const nsString& aPopupAlignment,
+                            nsIDOMWindow* aWindow, nsIDOMWindow** outPopup)
+{
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP
+mozSimpleContainer::FocusAvailable(nsIWebShell* aFocusedWebShell,
+                                   PRBool& aFocusTaken)
+{
+  return NS_OK;
+}
+
+
+/** Resizes container to new dimensions
+ * @param width new window width (pixels)
+ * @param height new window height (pixels)
+ */
+NS_IMETHODIMP mozSimpleContainer::Resize(PRInt32 aWidth, PRInt32 aHeight)
+{
+  if (!mWebShell) return NS_ERROR_FAILURE;
+
+  mWebShell->SetBounds(0, 0, aWidth, aHeight);
+  return NS_OK;
+}
+
+
+/** Loads specified URL into container
+ * @param aURL URL string
+ */
+NS_IMETHODIMP mozSimpleContainer::LoadURL(const char* aURL)
+{
+  if (!mWebShell) return NS_ERROR_FAILURE;
+
+  nsString aStr(aURL);
+  mWebShell->LoadURL(aStr.GetUnicode());
+  return NS_OK;
+}
+
+
+/** Gets web shell in container
+ * @param aWebShell (output) web shell object
+ */
+NS_IMETHODIMP mozSimpleContainer::GetWebShell(nsIWebShell*& aWebShell)
+{
+  aWebShell = mWebShell.get();
+  NS_IF_ADDREF(aWebShell);      // Add ref'ed; needs to be released
+  return NS_OK;
+}
+
+
+/** Gets DOM document in container
+ * @param aDocument (output) DOM document
+ */
+NS_IMETHODIMP mozSimpleContainer::GetDocument(nsIDOMDocument*& aDocument)
+{
+
+  aDocument = nsnull;
+
+  if (mWebShell) {
+    nsIContentViewer* contViewer;
+    mWebShell->GetContentViewer(&contViewer);
+
+    if (nsnull != contViewer) {
+      nsIDocumentViewer* docViewer;
+      if (NS_OK == contViewer->QueryInterface(kIDocumentViewerIID,
+                                            (void**) &docViewer)) 
+      {
+        nsIDocument* vDoc;
+        docViewer->GetDocument(vDoc);
+
+        if (nsnull != vDoc) {
+          nsIDOMDocument* vDOMDoc;
+          if (NS_OK == vDoc->QueryInterface(kIDOMDocumentIID,
+                                            (void**) &vDOMDoc)) 
+            {
+              aDocument = vDOMDoc; // Add ref'ed; needs to be released
+            }
+          NS_RELEASE(vDoc);
+        }
+
+        NS_RELEASE(docViewer);
+      }
+
+      NS_RELEASE(contViewer);
+    }
+  }
+  return NS_OK;
+}
+
+
+/** Gets presentation shell associated with container
+ * @param aPresShell (output) presentation shell
+ */
+NS_IMETHODIMP mozSimpleContainer::GetPresShell(nsIPresShell*& aPresShell)
+{
+  aPresShell = nsnull;
+
+  nsIPresShell* presShell = nsnull;
+
+  if (mWebShell) {
+    nsIContentViewer* contViewer = nsnull;
+    mWebShell->GetContentViewer(&contViewer);
+
+    if (nsnull != contViewer) {
+      nsIDocumentViewer* docViewer = nsnull;
+      contViewer->QueryInterface(kIDocumentViewerIID, (void**) &docViewer);
+
+      if (nsnull != docViewer) {
+        nsIPresContext* presContext;
+        docViewer->GetPresContext(presContext);
+
+        if (nsnull != presContext) {
+          presContext->GetShell(&presShell);  // Add ref'ed
+          aPresShell = presShell;
+          NS_RELEASE(presContext);
+        }
+
+        NS_RELEASE(docViewer);
+      }
+
+      NS_RELEASE(contViewer);
+    }
+  }
+  return NS_OK;
+}
diff --git a/mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.h b/mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.h
new file mode 100644
index 00000000000..9a9f4a4191a
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/mozSimpleContainer.h
@@ -0,0 +1,100 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is XMLterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ */
+
+// mozSimpleContainer.h: declaration of mozSimpleContainer class
+// implementing mozISimpleContainer,
+// which provides a WebShell container for use in simple programs
+// using the layout engine
+
+#include "nscore.h"
+#include "nsCOMPtr.h"
+
+#include "mozISimpleContainer.h"
+
+class mozSimpleContainer : public mozISimpleContainer {
+
+public:
+
+  mozSimpleContainer();
+  virtual ~mozSimpleContainer();
+
+  // nsISupports
+  NS_DECL_ISUPPORTS
+
+  // nsIWebShellContainer interface
+  NS_IMETHOD WillLoadURL(nsIWebShell* aShell,
+                         const PRUnichar* aURL,
+                         nsLoadType aReason);
+ 
+  NS_IMETHOD BeginLoadURL(nsIWebShell* aShell,
+                          const PRUnichar* aURL);
+ 
+
+  NS_IMETHOD ProgressLoadURL(nsIWebShell* aShell,
+                             const PRUnichar* aURL,
+                             PRInt32 aProgress,
+                             PRInt32 aProgressMax);
+ 
+  NS_IMETHOD EndLoadURL(nsIWebShell* aShell,
+                        const PRUnichar* aURL,
+                        nsresult aStatus);
+ 
+  NS_IMETHOD NewWebShell(PRUint32 aChromeMask,
+                         PRBool aVisible,
+                         nsIWebShell *&aNewWebShell);
+  
+  NS_IMETHOD FindWebShellWithName(const PRUnichar* aName,
+                                  nsIWebShell*& aResult);
+  
+  NS_IMETHOD ContentShellAdded(nsIWebShell* aChildShell,
+                               nsIContent* frameNode);
+
+  NS_IMETHOD CreatePopup(nsIDOMElement* aElement,
+                         nsIDOMElement* aPopupContent, 
+                         PRInt32 aXPos, PRInt32 aYPos, 
+                         const nsString& aPopupType,
+                         const nsString& anAnchorAlignment,
+                         const nsString& aPopupAlignment,
+                         nsIDOMWindow* aWindow, nsIDOMWindow** outPopup);
+
+  NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell,
+                            PRBool& aFocusTaken);
+
+  // other
+  NS_IMETHOD Init(nsNativeWidget aNativeWidget,
+                  PRInt32 width, PRInt32 height,
+                  nsIPref* aPref);
+
+  NS_IMETHOD Resize(PRInt32 aWidth, PRInt32 aHeight);
+
+  NS_IMETHOD LoadURL(const char* aURL);
+
+  NS_IMETHOD GetWebShell(nsIWebShell*& aWebShell);
+
+  NS_IMETHOD GetDocument(nsIDOMDocument*& aDocument);
+
+  NS_IMETHOD GetPresShell(nsIPresShell*& aPresShell);
+
+protected:
+
+  /** owning reference to web shell created by us */
+  nsCOMPtr mWebShell;
+
+};
diff --git a/mozilla/extensions/xmlterm/geckoterm/nsSetupRegistry.cpp b/mozilla/extensions/xmlterm/geckoterm/nsSetupRegistry.cpp
new file mode 100644
index 00000000000..4fa8ec2a799
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/nsSetupRegistry.cpp
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (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/NPL/
+ *
+ * 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation.  Portions created by Netscape are Copyright (C) 1998
+ * Netscape Communications Corporation.  All Rights Reserved.
+ */
+
+// nsSetupRegistry.cpp: Just a copy of viewer's nSetupRegistry
+
+#include "../../../webshell/tests/viewer/nsSetupRegistry.cpp"
+
diff --git a/mozilla/extensions/xmlterm/geckoterm/nsTimer.cpp b/mozilla/extensions/xmlterm/geckoterm/nsTimer.cpp
new file mode 100644
index 00000000000..2bdb2c0a4cc
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/nsTimer.cpp
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+#include "nsITimer.h"
+#include "nsITimerCallback.h"
+#include "nsCRT.h"
+#include "prlog.h"
+#include 
+#include 
+#include 
+
+static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
+
+extern "C" gint nsTimerExpired(gpointer aCallData);
+
+/*
+ * Implementation of timers using Gtk timer facility 
+ */
+class TimerImpl : public nsITimer {
+public:
+
+public:
+  TimerImpl();
+  virtual ~TimerImpl();
+
+  virtual nsresult Init(nsTimerCallbackFunc aFunc,
+                void *aClosure,
+//              PRBool aRepeat, 
+                PRUint32 aDelay);
+
+  virtual nsresult Init(nsITimerCallback *aCallback,
+//              PRBool aRepeat, 
+                PRUint32 aDelay);
+
+  NS_DECL_ISUPPORTS
+
+  virtual void Cancel();
+  virtual PRUint32 GetDelay() { return mDelay; }
+  virtual void SetDelay(PRUint32 aDelay) { mDelay=aDelay; };
+  virtual void* GetClosure() { return mClosure; }
+
+  void FireTimeout();
+
+private:
+  nsresult Init(PRUint32 aDelay);
+
+  PRUint32 mDelay;
+  nsTimerCallbackFunc mFunc;
+  void *mClosure;
+  nsITimerCallback *mCallback;
+  // PRBool mRepeat;
+  TimerImpl *mNext;
+  guint mTimerId;
+};
+
+void TimerImpl::FireTimeout()
+{
+  if (mFunc != NULL) {
+    (*mFunc)(this, mClosure);
+  }
+  else if (mCallback != NULL) {
+    mCallback->Notify(this); // Fire the timer
+  }
+
+// Always repeating here
+
+// if (mRepeat)
+//  mTimerId = gtk_timeout_add(aDelay, nsTimerExpired, this);
+}
+
+
+TimerImpl::TimerImpl()
+{
+  //  printf("TimerImple::TimerImpl called for %p\n", this);
+  NS_INIT_REFCNT();
+  mFunc = NULL;
+  mCallback = NULL;
+  mNext = NULL;
+  mTimerId = 0;
+  mDelay = 0;
+  mClosure = NULL;
+}
+
+TimerImpl::~TimerImpl()
+{
+  //printf("TimerImpl::~TimerImpl called for %p\n", this);
+  Cancel();
+  NS_IF_RELEASE(mCallback);
+}
+
+nsresult 
+TimerImpl::Init(nsTimerCallbackFunc aFunc,
+                void *aClosure,
+//              PRBool aRepeat, 
+                PRUint32 aDelay)
+{
+  //printf("TimerImpl::Init called with func + closure for %p\n", this);
+    mFunc = aFunc;
+    mClosure = aClosure;
+    // mRepeat = aRepeat;
+
+// This is ancient debug code that is making it impossible to have timeouts
+// greater than 10 seconds. -re
+
+//   if ((aDelay > 10000) || (aDelay < 0)) {
+//     printf("Timer::Init() called with bogus value \"%d\"!  Not enabling timer.\n",
+//            aDelay);
+//     return Init(aDelay);
+//   }
+
+    mTimerId = gtk_timeout_add(aDelay, nsTimerExpired, this);
+
+    return Init(aDelay);
+}
+
+nsresult 
+TimerImpl::Init(nsITimerCallback *aCallback,
+//              PRBool aRepeat, 
+                PRUint32 aDelay)
+{
+  //printf("TimerImpl::Init called with callback only for %p\n", this);
+    mCallback = aCallback;
+    NS_ADDREF(mCallback);
+    // mRepeat = aRepeat;
+
+// This is ancient debug code that is making it impossible to have timeouts
+// greater than 10 seconds. -re
+
+//   if ((aDelay > 10000) || (aDelay < 0)) {
+//     printf("Timer::Init() called with bogus value \"%d\"!  Not enabling timer.\n",
+//            aDelay);
+//     return Init(aDelay);
+//   }
+
+    mTimerId = gtk_timeout_add(aDelay, nsTimerExpired, this);
+
+    return Init(aDelay);
+}
+
+nsresult
+TimerImpl::Init(PRUint32 aDelay)
+{
+  //printf("TimerImpl::Init called with delay %d only for %p\n", aDelay, this);
+
+    mDelay = aDelay;
+    //    NS_ADDREF(this);
+
+    return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS(TimerImpl, kITimerIID)
+
+
+void
+TimerImpl::Cancel()
+{
+  //printf("TimerImpl::Cancel called for %p\n", this);
+  TimerImpl *me = this;
+  if (mTimerId)
+    gtk_timeout_remove(mTimerId);
+}
+
+NS_GFXNONXP nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
+{
+    NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
+    if (nsnull == aInstancePtrResult) {
+      return NS_ERROR_NULL_POINTER;
+    }  
+
+    TimerImpl *timer = new TimerImpl();
+    if (nsnull == timer) {
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
+}
+
+gint nsTimerExpired(gpointer aCallData)
+{
+  //printf("nsTimerExpired for %p\n", aCallData);
+  TimerImpl* timer = (TimerImpl *)aCallData;
+  timer->FireTimeout();
+  return 0;
+}
diff --git a/mozilla/extensions/xmlterm/geckoterm/remake b/mozilla/extensions/xmlterm/geckoterm/remake
new file mode 100755
index 00000000000..5fa6bcaa398
--- /dev/null
+++ b/mozilla/extensions/xmlterm/geckoterm/remake
@@ -0,0 +1,8 @@
+#!/bin/csh
+
+set echo
+
+cd ../base
+make
+cd ../geckoterm
+rm xmlterm; make xmlterm
diff --git a/mozilla/extensions/xmlterm/linetest/Makefile.in b/mozilla/extensions/xmlterm/linetest/Makefile.in
new file mode 100644
index 00000000000..0483fe2f3f2
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/Makefile.in
@@ -0,0 +1,65 @@
+#!gmake
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "MPL"); you may not use this file
+# except in compliance with the MPL. You may obtain a copy of
+# the MPL at http://www.mozilla.org/MPL/
+# 
+# Software distributed under the MPL is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the MPL for the specific language governing
+# rights and limitations under the MPL.
+# 
+# The Original Code is lineterm.
+# 
+# The Initial Developer of the Original Code is Ramalingam Saravanan.
+# Portions created by Ramalingam Saravanan  are
+# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+# 
+# Contributor(s):
+# 
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License (the "GPL"), in which case
+# the provisions of the GPL are applicable instead of
+# those above. If you wish to allow use of your version of this
+# file only under the terms of the GPL and not to allow
+# others to use your version of this file under the MPL, indicate
+# your decision by deleting the provisions above and replace them
+# with the notice and other provisions required by the GPL.
+# If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+# makefile for xmlterm/linetest directory
+
+ifdef STAND_ALONE
+DEPTH      = ..
+topsrcdir  = ..
+srcdir     = .
+include $(topsrcdir)/config/autoconf.mk
+else
+DEPTH      = ../../..
+topsrcdir  = @top_srcdir@
+srcdir     = @srcdir@
+include $(DEPTH)/config/autoconf.mk
+endif
+
+
+# Debug option
+DEBUG = 1
+
+# Program
+SIMPLE_PROGRAMS = lterm ptytest testunistr
+
+# Defines
+DEFINES =
+
+# Libraries to be linked
+LIBS = -lncurses -lxmlterm -lpthread
+
+include $(topsrcdir)/config/config.mk
+
+include ../config/xmlterm_config.mk
+
+include $(topsrcdir)/config/rules.mk
diff --git a/mozilla/extensions/xmlterm/linetest/README b/mozilla/extensions/xmlterm/linetest/README
new file mode 100644
index 00000000000..92cf39a2630
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/README
@@ -0,0 +1 @@
+linetest --- Test programs (for LineTerm only)
diff --git a/mozilla/extensions/xmlterm/linetest/lterm.c b/mozilla/extensions/xmlterm/linetest/lterm.c
new file mode 100644
index 00000000000..d67558cbe8a
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/lterm.c
@@ -0,0 +1,557 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is lineterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ * 
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License (the "GPL"), in which case
+ * the provisions of the GPL are applicable instead of
+ * those above. If you wish to allow use of your version of this
+ * file only under the terms of the GPL and not to allow
+ * others to use your version of this file under the MPL, indicate
+ * your decision by deleting the provisions above and replace them
+ * with the notice and other provisions required by the GPL.
+ * If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/* lterm.c: Test driver for LINETERM using NCURSES
+ * CPP options:
+ *   LINUX:   for Linux2.0/glibc
+ *   SOLARIS: for Solaris2.6
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "curses.h"
+
+#define _REENTRANT
+#include 
+
+#ifdef SOLARIS
+#include 
+#include 
+#endif
+
+#ifdef LINUX
+#include 
+#include 
+typedef unsigned int nfds_t;
+#endif
+
+#include "lineterm.h"
+#include "tracelog.h"
+
+#define MAXPROMPT 256          /* Maximum length of prompt regexp */
+#define MAXCOL 4096            /* Maximum columns in line buffer */
+
+/* (0,0) is upper lefthand corner of window */
+
+/* Character attributes
+        A_NORMAL        Normal display (no highlight)
+        A_STANDOUT      Best highlighting mode of the terminal.
+        A_UNDERLINE     Underlining
+        A_REVERSE       Reverse video
+        A_BLINK         Blinking
+        A_DIM           Half bright
+        A_BOLD          Extra bright or bold
+        A_PROTECT       Protected mode
+        A_INVIS         Invisible or blank mode
+        A_ALTCHARSET    Alternate character set
+        A_CHARTEXT      Bit-mask to extract a character
+        COLOR_PAIR(n)   Color-pair number n
+*/
+
+/* GLOBAL VARIABLES */
+static int lineFlag = 0;
+static int ptyFlag = 1;
+static int debugFlag = 0;
+static int ltermNumber = -1;
+static SCREEN  *termScreen = NULL;
+static char *ttyDevice;
+static char *errDevice;
+
+static struct termios tios;    /* TERMIOS structure */
+
+static void finish(int sig);
+static pthread_t output_handler_thread_ID;
+
+static void *output_handler(void *arg);
+
+static void input_handler(int *plterm);
+
+int main(int argc, char *argv[]) {
+  FILE *inFile, *outFile;
+  UNICHAR uregexp[MAXPROMPT+1];
+  int argNo, options, processType, retValue;
+  int remaining, decoded;
+  int messageLevel;
+  char *promptStr;
+  char **commandArgs;
+  char *defaultCommand[] = {(char *)getenv("SHELL"), "-i", NULL};
+
+  /* Process command line arguments */
+  lineFlag = 0;
+  ptyFlag = 1;
+  debugFlag = 0;
+  processType = LTERM_DETERMINE_PROCESS;
+  ttyDevice = NULL;
+  errDevice = NULL;
+  promptStr = "#$%>?";  /* JUST A LIST OF DELIMITERS AT PRESENT */
+
+  lineFlag = 1;         /* Temporary */
+
+  argNo = 1;
+  while (argNo < argc) {
+
+    if ((strcmp(argv[argNo],"-h") == 0)||(strcmp(argv[argNo],"-help") == 0)) {
+      fprintf(stderr, "Usage: %s [-help] [-line] [-nopty] [-debug] [-tcsh / -bash] [-tty /dev/ttyname] [-err /dev/ttyname] [-prompt ]  ...\n", argv[0]);
+      exit(0);
+
+    } else if (strcmp(argv[argNo],"-line") == 0) {
+      lineFlag = 1;
+      argNo++;
+
+    } else if (strcmp(argv[argNo],"-nopty") == 0) {
+      ptyFlag = 0;
+      argNo++;
+
+    } else if (strcmp(argv[argNo],"-debug") == 0) {
+      debugFlag = 1;
+      argNo++;
+
+    } else if (strcmp(argv[argNo],"-bash") == 0) {
+      processType = LTERM_BASH_PROCESS;
+      argNo++;
+
+    } else if (strcmp(argv[argNo],"-tcsh") == 0) {
+      processType = LTERM_TCSH_PROCESS;
+      argNo++;
+
+    } else if (strcmp(argv[argNo],"-tty") == 0) {
+      argNo++;
+      if (argNo < argc) {
+        ttyDevice = argv[argNo];
+        argNo++;
+      }
+
+    } else if (strcmp(argv[argNo],"-err") == 0) {
+      argNo++;
+      if (argNo < argc) {
+        errDevice = argv[argNo];
+        argNo++;
+      }
+
+    } else if (strcmp(argv[argNo],"-prompt") == 0) {
+      argNo++;
+      if (argNo < argc) {
+        promptStr = argv[argNo];
+        argNo++;
+      }
+
+    } else
+      break;
+  }
+
+  if (argNo < argc) {
+    /* Execute specified command */
+    commandArgs = argv + argNo;
+  } else {
+    /* Execute default shell */
+    commandArgs = defaultCommand;
+  }
+
+  /* Convert prompt string to Unicode */
+  retValue = utf8toucs(promptStr, strlen(promptStr), uregexp, MAXPROMPT,
+                       0, &remaining, &decoded);
+  if ((retValue < 0) || (remaining > 0)) {
+    fprintf(stderr, "lterm: Error in decoding prompt string\n");
+    exit(1);
+  }
+
+  assert(decoded <= MAXPROMPT);
+  uregexp[decoded] = U_NUL;
+
+  if (debugFlag) {
+    messageLevel = 98;
+  } else {
+    messageLevel = 1;
+  }
+
+  if (errDevice != NULL) {
+    /* Redirect debug STDERR output to specified device */
+    int errfd = -1;
+    if ( (errfd = open(errDevice, O_WRONLY)) == -1)
+        perror("lterm");
+
+    if (dup2(errfd, 2) == -1) {
+      fprintf(stderr, "lterm: Failed dup2 for specified stderr\n");
+      exit(-1);
+    }
+
+    fprintf(stderr, "\n\nlterm: Echoing %s output to %s\n",
+            argv[0], errDevice);
+  }
+
+  signal(SIGINT, finish); /* Interrupt handler */
+
+  if (lineFlag) {
+    /* Line mode */
+
+    /* Get terminal attributes */
+    if (tcgetattr(0, &tios) == -1) {
+      fprintf(stderr, "lterm: Failed to get TTY attributes\n");
+      exit(-1);
+    }
+
+    /* Disable signals, canonical mode processing, and echo  */
+    tios.c_lflag &= ~(ISIG | ICANON | ECHO );
+
+    /* set MIN=1 and TIME=0 */
+    tios.c_cc[VMIN] = 1;
+    tios.c_cc[VTIME] = 0;
+
+    /* Set terminal attributes */
+    if (tcsetattr(0, TCSAFLUSH, &tios) == -1) {
+      fprintf(stderr, "lterm: Failed to set TTY attributes\n");
+      exit(-1);
+    }
+
+  } else {
+    /* Screen mode */
+    if (ttyDevice == NULL) {
+      /* Initialize screen on controlling TTY */
+      initscr();
+
+    } else {
+      /* Initialize screen on specified TTY */
+      if (errDevice != NULL)
+        fprintf(stderr, "lterm-00: Opening xterm %s\n", ttyDevice);
+      inFile = fopen( ttyDevice, "r");
+      outFile = fopen( ttyDevice, "w");
+      termScreen = newterm("xterm", outFile, inFile);
+      set_term(termScreen);
+    }
+
+    /* NCURSES screen settings */
+    cbreak();                 /* set terminal to raw (non-canonical) mode */
+    noecho();                 /* Disable terminal echo */
+    nonl();                   /* Do not translate newline */
+    intrflush(stdscr, FALSE); /* Flush input on interrupt */
+    keypad(stdscr, TRUE);     /* Enable user keypad */
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(BUTTON1_CLICKED, NULL); /* Capture Button1 click events */
+#endif
+
+    clear(); /* Clear screen */
+  }
+
+  /* Initialize LTERM operations */
+  lterm_init(messageLevel);
+
+  if (errDevice != NULL) {
+    tlog_message("lterm-00: Testing tlog_message\n");
+    tlog_warning("lterm-00: Testing tlog_warning\n");
+    fprintf(stderr, "lterm-00: ");
+    tlog_unichar(uregexp, ucslen(uregexp));
+  }
+
+  if (errDevice != NULL)
+    fprintf(stderr, "lintest-00: Opening LTERM to execute %s\n", commandArgs[0]);
+
+  options = 0;
+  if (!ptyFlag) options |= LTERM_NOPTY_FLAG;
+
+  // options |= LTERM_NOSTDERR_FLAG;
+
+  ltermNumber = lterm_new();
+  retValue = lterm_open(ltermNumber, commandArgs, NULL, uregexp,
+                        options, processType, NULL, NULL);
+  if (retValue < 0) {
+    fprintf(stderr, "lterm: Error %d in opening LTERM\n", retValue);
+    exit(1);
+  }
+
+  /* Create output handler thread */
+  retValue = pthread_create(&output_handler_thread_ID,  NULL,
+                            output_handler, (void *) <ermNumber);
+  if (retValue != 0) {
+    fprintf(stderr, "lterm: Error %d in creating OUTPUT_HANDLER thread\n",
+                     retValue);
+    finish(0);
+  }
+
+  if (errDevice != NULL)
+    fprintf(stderr, "lterm-00: Created OUTPUT_HANDLER thread\n");
+
+  /* Process input */
+  input_handler(<ermNumber);
+
+  /* Join output handler thread */
+  if (errDevice != NULL)
+    fprintf(stderr, "lterm-00: Joining OUTPUT_HANDLER thread\n");
+
+  retValue = pthread_join(output_handler_thread_ID,  NULL);
+  if (retValue != 0) {
+    fprintf(stderr, "lterm: Error %d in joining OUTPUT_HANDLER thread\n",
+                     retValue);
+    finish(0);
+  }
+
+  finish(0);
+}
+
+void finish(int sig)
+{
+  if (!lineFlag) {
+    endwin(); /* Close window */
+    if (termScreen != NULL)
+      delscreen(termScreen);
+  }
+
+  if (ltermNumber >= 0) {
+    /* Close and delete LTERM */
+    lterm_delete(ltermNumber);
+  }
+
+  if (errDevice != NULL)
+    fprintf(stderr, "finished-00: Finished\n");
+
+  exit(0);
+}
+
+/** Output an Unicode message to specified file descriptor. */
+void writeUnicode(int fd, const UNICHAR *buf, int count)
+{
+  char str[MAXCOL];
+  int j, k;
+
+  k = 0;
+  for (j=0; j= MAXCOL-4) {
+      if (MAXCOL >= 4) {
+        str[MAXCOL-4] = '.';
+        str[MAXCOL-3] = '.';
+        str[MAXCOL-2] = '.';
+      }
+      k = MAXCOL-1;
+      break;
+    }
+
+    /* TEMPORARY IMPLEMENTATION: just truncate Unicode to byte characters */
+    str[k++] = buf[j];
+  }
+
+  if (k == 0) return;
+
+  if (write(fd, str, k) != k) {
+    fprintf(stderr, "writeUnicode: Error in writing to FD %d\n", fd);
+    exit(-1);
+  }
+}
+
+
+/** Output an Unicode message to specified output stream
+ * if NOCONTROL is true, control characters are converted to printable
+ * characters before output
+ */
+void printUnicode(FILE *outStream, const UNICHAR *buf, int count, int noControl)
+{
+  char str[MAXCOL];
+  int j, k;
+
+  k = 0;
+  for (j=0; j= MAXCOL-4) {
+      if (MAXCOL >= 4) {
+        str[MAXCOL-4] = '.';
+        str[MAXCOL-3] = '.';
+        str[MAXCOL-2] = '.';
+      }
+      k = MAXCOL-1;
+      break;
+    }
+
+    if (!noControl && ((buf[j] < U_SPACE) || (buf[j] == U_DEL)) ) {
+      /* Control character */
+      str[k++] = U_CARET;
+      str[k++] = buf[j]+U_ATSIGN;
+    } else {
+      /* Printable character */
+      /* TEMPORARY IMPLEMENTATION: just truncate Unicode to byte characters */
+      str[k++] = buf[j];
+    }
+  }
+
+  /* Insert terminating null character and display string */
+  str[k++] = '\0';
+  fprintf(outStream, "%s\n", str);
+}
+
+
+void input_handler(int *plterm)
+{
+  char ch;
+  UNICHAR uch;
+  int n_written;
+
+  if (lineFlag) {
+
+    for (;;) {
+      /* Read a character from TTY (raw mode) */
+      ch = getchar();
+
+      if (ch == 0) {
+        fprintf(stderr, "input_handler-00: NUL character read; terminating\n");
+        break;
+      }
+
+      uch = (UNICHAR) ch;
+      n_written = lterm_write(*plterm, &uch, 1, LTERM_WRITE_PLAIN_INPUT);
+
+      /* Exit loop if TTY has been closed */
+      if (n_written == -2) {
+        if (errDevice != NULL)
+          fprintf(stderr, "input_handler-00: pseudo-TTY has been closed\n", *plterm);
+        break;
+      }
+
+      if (n_written < 0) {
+        fprintf(stderr, "input_handler: Error %d return from lterm_write\n",
+                         n_written);
+        return;
+      }
+    }
+  }
+
+  /* Close LTERM */
+  if (errDevice != NULL)
+    fprintf(stderr, "input_handler-00: Closing LTERM %d\n", *plterm);
+
+  /* Close and delete LTERM */
+  lterm_delete(*plterm);
+  *plterm = -1;
+}
+
+void *output_handler(void *arg)
+{
+  int *plterm = (int *) arg;
+  int timeout = -1;
+  UNICHAR buf[MAXCOL];
+  UNISTYLE style[MAXCOL];
+  int n_read, opcodes, buf_row, buf_col, cursor_row, cursor_col;
+  int xmax, ymax, x, y, c;
+  MEVENT mev;
+
+  if (errDevice != NULL)
+    fprintf(stderr, "output_handler-00: thread ID = %d, LTERM=%d\n",
+                    pthread_self(), *plterm);
+
+  if (!lineFlag) {
+    /* Get screen size */
+    getmaxyx(stdscr, ymax, xmax);
+
+    if (errDevice != NULL)
+      fprintf(stderr, "output_handler-00: screen xmax = %d, ymax = %d\n",
+              xmax,ymax);
+  }
+
+  for (;;) {
+    n_read = lterm_read(*plterm, timeout, buf, MAXCOL,
+                        style, &opcodes,
+                        &buf_row, &buf_col, &cursor_row, &cursor_col);
+
+    if (n_read == -1) {
+      fprintf(stderr, "output_handler: Error %d return from lterm_read\n",
+                      n_read);
+      return NULL;
+    }
+
+    /* Exit loop if TTY has been closed;
+     * leave it to input handler to close the LTERM.
+     */
+    if (n_read == -2) {
+      if (errDevice != NULL)
+        fprintf(stderr, "output_handler: pseudo-TTY has been closed\n");
+      break;
+    }
+
+    if (debugFlag) {
+      fprintf(stderr, "output_handler-00: n_read=%d, opcodes=%x, buf_row/col=%d/%d, cursor_row/col=%d/%d\n",
+            n_read, opcodes, buf_row, buf_col, cursor_row, cursor_col);
+      fprintf(stderr, "output_handler-00: U(%d): ", n_read);
+      printUnicode(stderr, buf, n_read, 1);
+      fprintf(stderr, "\n");
+    }
+
+    if (opcodes & LTERM_STREAMDATA_CODE) {
+      /* Stream data */
+      if (debugFlag)
+        fprintf(stderr, "output_handler-00: STREAMDATA\n");
+
+    } else if (opcodes & LTERM_SCREENDATA_CODE) {
+      /* Screen data */
+      if (debugFlag)
+        fprintf(stderr, "output_handler-00: SCREENDATA\n");
+
+    } else if (opcodes & LTERM_LINEDATA_CODE) {
+      /* Line data */
+      if (debugFlag)
+        fprintf(stderr, "output_handler-00: LINEDATA\n");
+
+      if (lineFlag) {
+        int j;
+        write(1, "\033[2K", 4);
+        write(1, "\r", 1);
+
+        if (opcodes & LTERM_META_CODE)
+          write(1, "META", 4);
+
+        writeUnicode(1, buf, n_read);
+
+        for (j=0; j< (n_read-cursor_col); j++)
+          write(1, "\033[D", 3);
+
+        if (opcodes & LTERM_BELL_CODE)
+          write(1, "\007", 1);
+
+        if (opcodes & LTERM_CLEAR_CODE)
+          write(1, "\033[H\033[2J", 7);
+
+        if (opcodes & LTERM_NEWLINE_CODE)
+          write(1, "\n", 1);
+      }
+
+    } else if (opcodes != 0) {
+      fprintf(stderr, "output_handler: invalid opcodes %x\n", opcodes);
+    }
+  }
+
+  return NULL;
+}
diff --git a/mozilla/extensions/xmlterm/linetest/ptytest.c b/mozilla/extensions/xmlterm/linetest/ptytest.c
new file mode 100644
index 00000000000..53092889b4e
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/ptytest.c
@@ -0,0 +1,366 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "MPL"); you may not use this file
+ * except in compliance with the MPL. You may obtain a copy of
+ * the MPL at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the MPL is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the MPL for the specific language governing
+ * rights and limitations under the MPL.
+ * 
+ * The Original Code is lineterm.
+ * 
+ * The Initial Developer of the Original Code is Ramalingam Saravanan.
+ * Portions created by Ramalingam Saravanan  are
+ * Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
+ * 
+ * Contributor(s):
+ * 
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License (the "GPL"), in which case
+ * the provisions of the GPL are applicable instead of
+ * those above. If you wish to allow use of your version of this
+ * file only under the terms of the GPL and not to allow
+ * others to use your version of this file under the MPL, indicate
+ * your decision by deleting the provisions above and replace them
+ * with the notice and other provisions required by the GPL.
+ * If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/* ptytest.c: Test driver for ptystream.c
+ * CPP options:
+ *   LINUX:   for Linux2.0/glibc
+ *   SOLARIS: for Solaris2.6
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifdef SOLARIS
+#include 
+#include 
+#endif
+
+#ifdef LINUX
+#include 
+#include 
+typedef unsigned int nfds_t;
+#endif
+
+#include "ptystream.h"
+
+static struct termios tios;    /* TERMIOS structure */
+
+void pipeTest(int argc, char *argv[]);
+void ptyTest(int argc, char *argv[]);
+
+int echofd = -1;
+
+int main(int argc, char *argv[]) {
+
+  if (argc < 4) {
+    fprintf(stderr, "Usage: %s pty|pipe |''  ...\n",
+                    argv[0]);
+    exit(-1);
+  }
+
+  /* Get terminal attributes */
+  if (tcgetattr(0, &tios) == -1) {
+    fprintf(stderr, "Failed to get TTY attributes\n");
+    exit(-1);
+  }
+
+  /* Disable signals, canonical mode processing, and echo  */
+  tios.c_lflag &= ~(ISIG | ICANON | ECHO );
+
+  /* set MIN=1 and TIME=0 */
+  tios.c_cc[VMIN] = 1;
+  tios.c_cc[VTIME] = 0;
+
+  /* Set terminal attributes */
+  if (tcsetattr(0, TCSAFLUSH, &tios) == -1) {
+    fprintf(stderr, "Failed to set TTY attributes\n");
+    exit(-1);
+  }
+
+  if (strlen(argv[2]) > 0) {
+    /* Open TTY for echoing */
+    if ( (echofd = open(argv[2], O_WRONLY)) == -1)
+      perror("ptytest");
+    fprintf(stderr, "Echoing %s output to %s\n", argv[1], argv[2]);
+    write( echofd, "Echoing PTYTEST output ...\n", 27);
+  }
+
+  fprintf(stderr, "Type Control-@ (NUL) to terminate input\n");
+
+  if (strcmp(argv[1],"pipe") == 0) {
+    pipeTest(argc-3, argv+3);
+  } else {
+    ptyTest(argc-3, argv+3);
+  }
+
+  if (echofd >= 0) close(echofd);
+  exit(0);
+
+}
+
+
+/* sends raw terminal input/output to a shell through a pseudo-TTY */
+void ptyTest(int argc, char *argv[])
+{
+  struct pollfd pollFD[2];
+  nfds_t nfds = 2;
+  struct ptys ptyStruc;
+
+  unsigned char ch;
+  int ptyFD, pollCode;
+  ssize_t n_read, n_written;
+
+  char temstr[3] = "^@";
+
+  /* Create a PTY */
+  if (pty_create(&ptyStruc,argv,-1,0,0,0,1) == -1) {
+    fprintf(stderr, "PTY creation failed\n");
+    exit(-1);
+  }
+
+  ptyFD = ptyStruc.ptyFD;
+
+  /* fprintf(stderr, "Polling for input on fd=0 (%s) and fd=%d\n",
+     ttyname(0), ptyFD ); */
+
+  /* Set up polling to read from parent STDIN and child STDOUT */
+  pollFD[0].fd = 0;
+  pollFD[0].events = POLLIN;
+  pollFD[1].fd = ptyFD;
+  pollFD[1].events = POLLIN;
+
+  while ( (pollCode=poll(pollFD,nfds,-1)) >= 0) {
+    if (pollCode == 0) continue;
+    pollCode = 0;
+
+    if (pollFD[0].revents != 0) {
+      /* Read character from parent STDIN and write to child STDIN */
+      ch = getchar();
+
+      /* Exit poll loop if a null (Control-@) is read */
+      if (ch == 0) break;
+
+      if (write(ptyFD, &ch, 1) != 1) {
+        fprintf(stderr, "Error in writing to child STDIN\n");
+        exit(-1);
+      }
+
+    }
+
+    if (pollFD[1].revents != 0) {
+      /* Read character from child STDOUT and write to parent STDOUT */
+
+      if ( (n_read=read(ptyFD, &ch, 1)) < 0) {
+        fprintf(stderr, "Error in reading from child STDOUT\n");
+        if (echofd >= 0) close(echofd);
+        exit(-1);
+      }
+
+      if (n_read == 0) { /* End of file */
+        if (echofd >= 0) close(echofd);
+        exit(0);
+      }
+
+      if (echofd >= 0) {
+        /* Echo output to another TTY */
+        if (ch == 0x7F) {
+          write(echofd, "\\DEL", 4);
+        } else if (ch == 0x1B) {
+          write(echofd, "\\ESC", 4);
+        } else if (ch < 0x20) {
+          temstr[1]= ch+'@';
+          write(echofd, temstr, 2);
+        } else {
+          write(echofd, &ch, 1);
+        }
+      }
+
+      if (write(1, &ch, 1) != 1) {
+        fprintf(stderr, "Error in writing to parent STDOUT\n");
+        exit(-1);
+      }
+
+      /*
+      if (ioctl(1, I_FLUSH, FLUSHRW) == -1) {
+        fprintf(stderr, "Error return from ioctl\n");
+        exit(-1);
+      }
+      */
+
+    }
+  }
+
+  if (pollCode != 0) {
+    fprintf(stderr, "Error return from poll\n");
+    exit(-1);
+  }
+
+  /* Close PTY */
+  pty_close(&ptyStruc);
+
+}
+
+
+/* sends raw terminal input/output to a shell through a pipe */
+void pipeTest(int argc, char *argv[])
+{
+  struct pollfd pollFD[2];
+  nfds_t nfds = 2;
+  pid_t child_pid = -1;   /* child process id */
+
+  unsigned char ch;
+  int pipeFD[2], pipeIN, pipeOUT, procIN, procOUT;
+  int pollCode;
+  ssize_t n_read, n_written;
+
+  char temstr[3] = "^@";
+
+  /* Create process input pipe (assumed unidirectional) */
+  if (pipe(pipeFD) == -1) {
+    fprintf(stderr, "Input pipe creation failed\n");
+    exit(-1);
+  }
+#ifdef DEBUG
+  fprintf(stderr,"Created input pipe: %d %d\n", pipeFD[0], pipeFD[1]);
+#endif
+  procIN = pipeFD[0];
+  pipeIN = pipeFD[1];
+
+  /* Create process output pipe (assumed unidirectional) */
+  if (pipe(pipeFD) == -1) {
+    fprintf(stderr, "Output pipe creation failed\n");
+    exit(-1);
+  }
+#ifdef DEBUG
+  fprintf(stderr,"Created output pipe: %d %d\n", pipeFD[0], pipeFD[1]);
+#endif
+  pipeOUT = pipeFD[0];
+  procOUT = pipeFD[1];
+
+  /* Fork a child process */
+  child_pid = fork();
+  if (child_pid < 0) {
+    fprintf(stderr, "Fork failed\n");
+    exit(-1);
+  }
+
+#ifdef DEBUG
+  fprintf(stderr, "Fork child process %d\n", child_pid);
+#endif
+
+  if (child_pid == 0) {
+    /* Child process */
+
+    if (dup2(procIN, 0) == -1) {
+      fprintf(stderr, "Dup2 failed for stdin of child\n");
+      exit(-1);
+    }
+
+    if (dup2(procOUT, 1) == -1) {
+      fprintf(stderr, "Dup2 failed for stdout of child\n");
+      exit(-1);
+    }
+
+    execvp(argv[0], argv);
+    fprintf(stderr, "Exec failed for command %s\n", argv[0]);
+    exit(-1);
+  }
+
+  /* Set up polling to read from parent STDIN and child STDOUT */
+  pollFD[0].fd = 0;
+  pollFD[0].events = POLLIN;
+  pollFD[1].fd = pipeOUT;
+  pollFD[1].events = POLLIN;
+
+  while ( (pollCode=poll(pollFD,nfds,-1)) >= 0) {
+
+    if (pollFD[0].revents != 0) {
+      /* Read character from parent STDIN and write to child STDIN */
+      ch = getchar();
+
+      /* Exit poll loop if a null (Control-@) is read */
+      if (ch == 0) break;
+
+      if (write(pipeIN, &ch, 1) != 1) {
+        fprintf(stderr, "Error in writing to child STDIN\n");
+        exit(-1);
+      }
+
+    }
+
+    if (pollFD[1].revents != 0) {
+      /* Read character from child STDOUT and write to parent STDOUT */
+
+      if ( (n_read=read(pipeOUT, &ch, 1)) < 0) {
+        fprintf(stderr, "Error in reading from child STDOUT\n");
+        if (echofd >= 0) close(echofd);
+        exit(-1);
+      }
+
+      if (n_read == 0) { /* End of file */
+        if (echofd >= 0) close(echofd);
+        exit(0);
+      }
+
+      if (echofd >= 0) {
+        /* Echo output to another TTY */
+        if (ch == 0x7F) {
+          write(echofd, "\\DEL", 4);
+        } else if (ch == 0x1B) {
+          write(echofd, "\\ESC", 4);
+        } else if (ch < 0x20) {
+          temstr[1]= ch+'@';
+          write(echofd, temstr, 2);
+        } else {
+          write(echofd, &ch, 1);
+        }
+      }
+
+      if (write(1, &ch, 1) != 1) {
+        fprintf(stderr, "Error in writing to parent STDOUT\n");
+        exit(-1);
+      }
+
+      /*
+      if (ioctl(1, I_FLUSH, FLUSHRW) == -1) {
+        fprintf(stderr, "Error return from ioctl\n");
+        exit(-1);
+      }
+      */
+
+    }
+
+  }
+
+  if (kill(child_pid, SIGKILL) == -1) {
+    fprintf(stderr, "Error return from kill\n");
+    exit(-1);
+  }
+
+  if (pollCode != 0) {
+    fprintf(stderr, "Error return from poll\n");
+    exit(-1);
+  }
+
+  /* Close pipes (assumed unidirectional) */
+  close(pipeIN);
+  close(pipeOUT);
+  close(procIN);
+  close(procOUT);
+
+}
diff --git a/mozilla/extensions/xmlterm/linetest/remake b/mozilla/extensions/xmlterm/linetest/remake
new file mode 100755
index 00000000000..7c41b8f8651
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/remake
@@ -0,0 +1,7 @@
+#!/bin/csh
+set echo
+
+pushd ../base
+make STAND_ALONE=1 export libs
+popd
+make STAND_ALONE=1 $*
diff --git a/mozilla/extensions/xmlterm/linetest/temncurses.c b/mozilla/extensions/xmlterm/linetest/temncurses.c
new file mode 100644
index 00000000000..735e87b04bb
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/temncurses.c
@@ -0,0 +1,32 @@
+
+  /* Move cursor and display string */
+  x = 2;
+  y = 4;
+
+  /* if (scanf("%d %d", &y, &x) == EOF) break; */
+
+  /* Display string at specified location and advance cursor */
+  mvaddnstr(y, x, "test 1", 6);
+
+  attron(A_BOLD);
+  mvaddnstr(y, x+6, "test2 ", 6);
+  attroff(A_BOLD);
+
+  refresh();
+
+  for (;;) {
+    c = getch();
+    if (c == KEY_MOUSE) {
+      if (getmouse(&mev) == OK) {
+        move(mev.y, mev.x);
+        addnstr("MEV ", 4);
+        refresh();
+
+        /* Delete top line, and move up (if +1, insert top line, move down) */
+        move(0,0);
+        insdelln(-1);
+
+      }
+    }
+  }
+
diff --git a/mozilla/extensions/xmlterm/linetest/testunistr.c b/mozilla/extensions/xmlterm/linetest/testunistr.c
new file mode 100644
index 00000000000..afe996e1048
--- /dev/null
+++ b/mozilla/extensions/xmlterm/linetest/testunistr.c
@@ -0,0 +1,138 @@
+/* testunistr.c: Test driver for Unicode strings module unistring.c */
+
+/* public declarations */
+#include "unistring.h"
+
+#include "assert.h"
+
+int main(int argc, char *argv[])
+{
+  int argNo, ucs16_opt, utf8_opt, j;
+  int result, remaining, encoded, decoded;
+
+  if (argc < 2) {
+    printf("Usage: %s (-ucs16 |-utf8 |)\n",
+           argv[0]);
+    exit(1);
+  }
+
+  ucs16_opt = 0;
+  utf8_opt = 0;
+  argNo = 1;
+
+  if (argc > 1) {
+    argNo = 2;
+    if (strcmp(argv[1],"-ucs16") == 0) {
+      ucs16_opt = 1;
+    } else if (strcmp(argv[1],"-utf8") == 0) {
+      utf8_opt = 1;
+    }
+  }
+
+  if (ucs16_opt) {
+    char* tems = argv[argNo];
+    int nus = strlen(argv[argNo])/4;
+    int ns = 3*nus;
+    UNICHAR* us = (UNICHAR*) malloc((nus+1)*sizeof(UNICHAR));
+    unsigned char* s = (unsigned char*) malloc(ns+1);
+    char temus[5] = {0,0,0,0,0};
+
+    for (j=0; j
+
+int main(void)
+{
+  char ch;
+
+  /* XMLTerm escape sequence signalling start of a HTML document */
+  printf("\033{0;1S\007");
+
+  printf("  \
+
\ + \ + Please click a button
\ + \ + \ + \ +
\ +"); + + /* XMLTerm escape sequence signalling end of stream */ + printf("%c", '\0'); + + while((ch = getchar())){ /* Poll for data generated by button click events */ + switch (ch) { + case 'b': + printf("\033{S\007Hello World!
%c", '\0'); + break; + case 'e': + printf("\033{S\007Hello World!
%c", '\0'); + break; + case 'q': + return 0; + break; + default: + break; + } + } + + return 0; +} diff --git a/mozilla/extensions/xmlterm/tests/HelloWorld.c b/mozilla/extensions/xmlterm/tests/HelloWorld.c new file mode 100644 index 00000000000..a3d200f3188 --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/HelloWorld.c @@ -0,0 +1,40 @@ +/* HelloWorld.c: Simple demo program for "pagelets" */ + +#include + +int main(void) +{ + char ch; + printf("\033{S\007"); /* XMLTerm escape sequence signalling start of HTML */ + + printf("
\ + \ + Please click a button
\ + \ + \ + \ +
"); + + printf("%c", '\0'); /* XMLTerm escape sequence signalling end of HTML */ + + while((ch = getchar())){ /* Poll for data generated by button click events */ + switch (ch) { + case 'b': + printf("\033{S\007Hello World!
%c", '\0'); + break; + case 'e': + printf("\033{S\007Hello World!
%c", '\0'); + break; + case 'q': + return 0; + break; + default: + break; + } + } + + return 0; +} diff --git a/mozilla/extensions/xmlterm/tests/Makefile.in b/mozilla/extensions/xmlterm/tests/Makefile.in new file mode 100644 index 00000000000..8a86c74534e --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/Makefile.in @@ -0,0 +1,67 @@ +#!gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# makefile for xmlterm/tests directory + +ifdef STAND_ALONE +DEPTH = .. +topsrcdir = .. +srcdir = . +include $(topsrcdir)/config/autoconf.mk +else +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +include $(DEPTH)/config/autoconf.mk +endif + +# Debug option +DEBUG = 1 + +# C Sources +CSRCS = escape.c teststream.c HelloWorld.c DocStream.c + +# Program +SIMPLE_PROGRAMS = escape teststream HelloWorld DocStream + +# Defines +DEFINES = + +# Libraries to be linked +LIBS = + +include $(topsrcdir)/config/config.mk + +include ../config/xmlterm_config.mk + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/extensions/xmlterm/tests/README b/mozilla/extensions/xmlterm/tests/README new file mode 100644 index 00000000000..fa883397f54 --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/README @@ -0,0 +1 @@ +tests --- Test programs for XMLterm diff --git a/mozilla/extensions/xmlterm/tests/escape.c b/mozilla/extensions/xmlterm/tests/escape.c new file mode 100644 index 00000000000..c7823985f9d --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/escape.c @@ -0,0 +1,56 @@ +/* escape.c: Generates XMLterm/LineTerm escape sequences */ + +#include + +int main(int argc, char *argv[]) +{ + int nparam, j; + char *param1, *param2, *param3, *code, *sparam; + + param1 = NULL; + param2 = NULL; + param3 = NULL; + code = NULL; + sparam = ""; + nparam = 0; + + for (j=1; j= '0') && (*argv[j] <= '9')) { + if (j == 1) { + param1 = argv[j]; + nparam = 1; + } else if (j == 2) { + param2 = argv[j]; + nparam = 2; + } else if (j == 3) { + param3 = argv[j]; + nparam = 3; + } + } else if (code == NULL) { + code = argv[j]; + } else { + sparam = argv[j]; + } + } + + if (code == NULL) { + fprintf(stderr, "Usage: %s [ [ []]] [] \n", argv[0]); + return 1; + } + + if (nparam == 0) { + fprintf(stderr, "ESC{%s%sBEL\n", code, sparam); + fprintf(stdout, "\033{%s%s\007", code, sparam); + } else if (nparam == 1) { + fprintf(stderr, "ESC{%s%s%sBEL\n", param1, code, sparam); + fprintf(stdout, "\033{%s%s%s\007", param1, code, sparam); + } else if (nparam == 2) { + fprintf(stderr, "ESC{%s;%s%s%sBEL\n", param1, param2, code, sparam); + fprintf(stdout, "\033{%s;%s%s%s\007", param1, param2, code, sparam); + } else { + fprintf(stderr, "ESC{%s;%s;%s%s%sBEL\n", param1, param2, param3, code, sparam); + fprintf(stdout, "\033{%s;%s;%s%s%s\007", param1, param2, param3, code, sparam); + } + + return 0; +} diff --git a/mozilla/extensions/xmlterm/tests/teststream.c b/mozilla/extensions/xmlterm/tests/teststream.c new file mode 100644 index 00000000000..69b65c599d8 --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/teststream.c @@ -0,0 +1,20 @@ +/* teststream.c: Test driver to generate escaped stream data */ + +#include + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage: %s []\n",argv[0]); + return 1; + } + + if (argc > 2) { + /* fprintf(stderr, "{ESCS%sBEL%s%s", argv[2], argv[1], argv[2]); */ + fprintf(stdout, "\033{S%s\007%s%s", argv[2], argv[1], argv[2]); + + } else { + fprintf(stdout, "\033{S\007%s%c", argv[1], '\0'); + } + + return 0; +} diff --git a/mozilla/extensions/xmlterm/tests/xls b/mozilla/extensions/xmlterm/tests/xls new file mode 100755 index 00000000000..226df4c0e77 --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/xls @@ -0,0 +1,84 @@ +#!/usr/bin/perl +# xls: an XMLterm wrapper for the UNIX "ls" command +# Usage: xls [-c|--cols] [-h|help] [-i||--iconic] [-w|--window] + +use Cwd; +use Getopt::Long; + +Getopt::Long::config('bundling'); + +$options = "@ARGV"; + +&GetOptions("cols|c=i", "help|h!", "iconic|i!", "window|w!"); + +if ($opt_help) { + print "Usage: xls [-c|--cols] [-i|--iconic] [-w|--window]\n"; + exit; +} + +# Icon details +#$imgdir="chrome://xmlterm/skin/default/images" +$imgdir = "file:/usr/share/pixmaps/mc"; + +($img{'directory'}, $img{'executable'}, $img{'plainfile'}) = + ('i-directory.png', 'i-executable.png', 'i-regular.png'); + +$ncols = 5; +$ncols = $opt_cols if ($opt_cols); + +print "\e{S\a"; # HTML stream escape sequence +print ""; +print ""; + +$dir = cwd(); +$rowimg = ""; +$rowtxt = ""; +$nfile = 0; +foreach $file (glob("$dir/*")) { # for each file in current directory + if (-d $file) { # directory + $filetype = "directory"; + $sendtxt = "cd $file; xls $options"; + $sendimg = "file:/usr/share/pixmaps/mc/i-directory.png"; + + } elsif (-x $file) { # executable + $filetype = "executable"; + $sendtxt = "$file"; + + } else { # plain file + $filetype = "plainfile"; + $sendtxt = ""; + } + + @comps = split(m./.,$file); + $tail = $comps[$#comps]; # file name + + if ($opt_window) { + $sendcmd = "createln"; + } else { + $sendcmd = "sendln"; + } + + $clickcmd = qq%onclick="return clickXMLTerm('$sendcmd',-1,'$sendtxt')"%; + + $rowimg .= "$rowimg" if ($opt_iconic) ; + print "$rowtxt"; + $rowimg = ""; + $rowtxt = ""; + } + +} + +if (length($rowtxt) != 0) { + print "$rowimg" if ($opt_iconic) ; + print "$rowtxt"; +} + +print "
"; + $rowtxt .= ""; + $rowtxt .= "$tail"; + $nfile++; + + if (($nfile % $ncols) == 0) { # print complete table row + print "
"; +print "\000"; # Terminate HTML stream + diff --git a/mozilla/extensions/xmlterm/tests/xls.csh b/mozilla/extensions/xmlterm/tests/xls.csh new file mode 100755 index 00000000000..a5f5a9addd7 --- /dev/null +++ b/mozilla/extensions/xmlterm/tests/xls.csh @@ -0,0 +1,81 @@ +#!/bin/csh +# xls.csh: a C-shell XMLterm wrapper for the UNIX "ls" command +# Usage: xls.csh [-i] [-x] + +set files=(`/bin/ls -d $cwd/*`) +set ncols=4 + +##set echocmd="/usr/bin/echo" +set echocmd="/bin/echo -e" + +set iconic=0 +set create=0 + +set options="" +foreach arg ($*) + switch ($arg) + case "-i": + set iconic=1 + set options=($options $arg) + breaksw + case "-c": + set create=1 + set options=($options $arg) + breaksw + endsw +end + +$echocmd '\033{S\007\c' +$echocmd '' +$echocmd "" + +set rowimg="" +set rowtxt="" +set nfile=0 +foreach file ($files) + if (-d $file) then #directory + set filetype="directory" + set sendtxt="cd $file; xls $options" + set sendimg="file:/usr/share/pixmaps/mc/i-directory.png" +# set sendimg="chrome://xmlterm/skin/default/images/ficon3.gif" + else if (-x $file) then #executable + set filetype="executable" + set sendtxt="$file" + set sendimg="file:/usr/share/pixmaps/mc/i-executable.png" + else #plain file + set filetype="plainfile" + set sendtxt="" + set sendimg="file:/usr/share/pixmaps/mc/i-regular.png" + endif + + set tail=${file:t} + + if ($create) then + set cmd="createln" + else + set cmd="sendln" + endif + set clickcmd="onclick="'"'"return clickXMLTerm('$cmd',-1,'$sendtxt')"'"' + + set rowimg="${rowimg}$rowimg" + $echocmd "$rowtxt" + set rowimg="" + set rowtxt="" + endif + +end + +if ("$rowtxt" != "") then + if ($iconic) $echocmd "$rowimg" + $echocmd "$rowtxt" +endif + +$echocmd '
" + set rowtxt="${rowtxt}" + set rowtxt="${rowtxt}$tail" +@ nfile++ + + if (($nfile % $ncols) == 0) then + if ($iconic) $echocmd "
' +$echocmd '\000\c' + diff --git a/mozilla/extensions/xmlterm/ui/Makefile.in b/mozilla/extensions/xmlterm/ui/Makefile.in new file mode 100644 index 00000000000..5b1fb7cd585 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/Makefile.in @@ -0,0 +1,57 @@ +#!gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# makefile for xmlterm/ui directory + +ifdef STAND_ALONE +DEPTH = . +topsrcdir = . +VPATH = . +srcdir = . +include $(topsrcdir)/config/autoconf.mk +else +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ +include $(DEPTH)/config/autoconf.mk +endif + +DIRS = content skin + +include $(topsrcdir)/config/config.mk + +include ../config/xmlterm_config.mk + +include $(topsrcdir)/config/rules.mk + diff --git a/mozilla/extensions/xmlterm/ui/README b/mozilla/extensions/xmlterm/ui/README new file mode 100644 index 00000000000..3a63d5ad812 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/README @@ -0,0 +1 @@ +ui --- User Interface stuff for XMLterm diff --git a/mozilla/extensions/xmlterm/ui/content/Makefile.in b/mozilla/extensions/xmlterm/ui/content/Makefile.in new file mode 100644 index 00000000000..1cfcf447a99 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/content/Makefile.in @@ -0,0 +1,61 @@ +#!gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# makefile for xmlterm/ui/content directory + +ifdef STAND_ALONE +DEPTH = . +topsrcdir = . +VPATH = . +srcdir = . +include $(topsrcdir)/config/autoconf.mk +else +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ +include $(DEPTH)/config/autoconf.mk +endif + +include $(topsrcdir)/config/config.mk + +include ../../config/xmlterm_config.mk + +include $(topsrcdir)/config/rules.mk + +EXPORT_RESOURCE_CONTENT = \ + $(srcdir)/xmlterm.html \ + $(NULL) + +install:: + $(INSTALL) $(EXPORT_RESOURCE_CONTENT) $(DIST)/bin/chrome/xmlterm/content/default diff --git a/mozilla/extensions/xmlterm/ui/content/README b/mozilla/extensions/xmlterm/ui/content/README new file mode 100644 index 00000000000..92d35581409 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/content/README @@ -0,0 +1,5 @@ +content --- XUL, Javascript, and HTML for user interface + +xmlterm.html XMLterm startup file containing HTML and Javascript + Uses mozIXMLTermShell to create XMLterm + Uses ../skin/xmlterm.css for stylesheets diff --git a/mozilla/extensions/xmlterm/ui/content/xmlterm.html b/mozilla/extensions/xmlterm/ui/content/xmlterm.html new file mode 100644 index 00000000000..0ecfccc6ab0 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/content/xmlterm.html @@ -0,0 +1,239 @@ + + + + XMLterm Test Page + + + + + + + + + + + +
+
+ + + +
+ History Buffer Size: + + +
+
+ + + +
+
+ + + diff --git a/mozilla/extensions/xmlterm/ui/skin/Makefile.in b/mozilla/extensions/xmlterm/ui/skin/Makefile.in new file mode 100644 index 00000000000..ba085217362 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/skin/Makefile.in @@ -0,0 +1,66 @@ +#!gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "MPL"); you may not use this file +# except in compliance with the MPL. You may obtain a copy of +# the MPL at http://www.mozilla.org/MPL/ +# +# Software distributed under the MPL is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the MPL for the specific language governing +# rights and limitations under the MPL. +# +# The Original Code is lineterm. +# +# The Initial Developer of the Original Code is Ramalingam Saravanan. +# Portions created by Ramalingam Saravanan are +# Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License (the "GPL"), in which case +# the provisions of the GPL are applicable instead of +# those above. If you wish to allow use of your version of this +# file only under the terms of the GPL and not to allow +# others to use your version of this file under the MPL, indicate +# your decision by deleting the provisions above and replace them +# with the notice and other provisions required by the GPL. +# If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +# makefile for xmlterm/ui/skin directory + +ifdef STAND_ALONE +DEPTH = . +topsrcdir = . +VPATH = . +srcdir = . +include $(topsrcdir)/config/autoconf.mk +else +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ +include $(DEPTH)/config/autoconf.mk +endif + +include $(topsrcdir)/config/config.mk + +include ../../config/xmlterm_config.mk + +include $(topsrcdir)/config/rules.mk + +EXPORT_RESOURCE_SKIN = \ + $(srcdir)/xmlterm.css \ + $(NULL) + +EXPORT_RESOURCE_TOOLBAR = \ + $(srcdir)/images/ficon.gif \ + $(NULL) + +install:: + $(INSTALL) $(EXPORT_RESOURCE_SKIN) $(DIST)/bin/chrome/xmlterm/skin/default + $(INSTALL) $(EXPORT_RESOURCE_TOOLBAR) $(DIST)/bin/chrome/xmlterm/skin/default/images diff --git a/mozilla/extensions/xmlterm/ui/skin/README b/mozilla/extensions/xmlterm/ui/skin/README new file mode 100644 index 00000000000..cb4d20fa0eb --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/skin/README @@ -0,0 +1,5 @@ +skin --- CSS stylesheets and images for user interface + +xmlterm.css Stylesheet for XMLterm startup file ../content/xmlterm.html + + diff --git a/mozilla/extensions/xmlterm/ui/skin/images/README b/mozilla/extensions/xmlterm/ui/skin/images/README new file mode 100644 index 00000000000..a72293d0700 --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/skin/images/README @@ -0,0 +1 @@ +images --- Icons and images for user interface diff --git a/mozilla/extensions/xmlterm/ui/skin/images/ficon.gif b/mozilla/extensions/xmlterm/ui/skin/images/ficon.gif new file mode 100644 index 0000000000000000000000000000000000000000..ba022c1c110d1dcd1503a5bebfd17e34977a3abe GIT binary patch literal 161 zcmZ?wbhEHbRAG={SjYeZB^eAaE-?K6|6lPRpKoGHszP~YNrr;Er*8m*;!hSvE(T@> z9gsSZ4hE)#IsGe7zvW*%XUnbM4fkRmGqXJMU~9OvG*e;AJM9^s5!Y0Dj;jkj`}cm* z$A|+;J{(F?(>WU)g-~ZmhXd`S#J4n2$ep^UiL5@o83W?fkXdcFnyK N_VW8m|D_BJ)&R*jMqU5_ literal 0 HcmV?d00001 diff --git a/mozilla/extensions/xmlterm/ui/skin/xmlterm.css b/mozilla/extensions/xmlterm/ui/skin/xmlterm.css new file mode 100644 index 00000000000..bc645b041ab --- /dev/null +++ b/mozilla/extensions/xmlterm/ui/skin/xmlterm.css @@ -0,0 +1,19 @@ +/* xmlterm.css: XMLterm default style sheet */ + +BODY { font-family: monaco, courier, elite, monospace; + background-color: #FFFFFF; + } + +DIV, PRE, SPAN { margin: 0; padding-top: 0; padding-bottom: 0 } + +PRE { font-family: monaco; + line-height: 120% } + +/* Input components */ +SPAN.prompt { color: blue } +SPAN.command { color: blue } + +/* Directory display */ +SPAN.plainfile { font-family: monaco} +SPAN.directory { font-family: monaco; color: blue; cursor: hand } +SPAN.executable { font-family: monaco; color: blue; cursor: hand }