| <!-- |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| --> |
| |
| <html> |
| <head> |
| <title>High level functional description of a Terminal Emulator, Term</title> |
| <LINK REL="Stylesheet" HREF="../../../../../prose.css" TYPE="text/css" TITLE="NetBeans OpenSource Style"> |
| |
| </head> |
| <body> |
| |
| <h1> |
| High level functional description of an ANSI Terminal Emulator, Term |
| <hr> |
| </h1> |
| |
| <p><b>Author:</b> |
| <p><i> |
| <a href="mailto:ivan.solimanipour@eng.sun.com">Ivan Soleimanipour</a>, |
| Sun Microsystems. |
| </i> |
| <hr> |
| |
| |
| <p><b>Abstract:</b> |
| A highly configurable ANSI terminal emulator. |
| <br><b>Version:</b> |
| 4 of |
| Wed Oct 24 2001 |
| <hr> |
| <p><b>Table of contents:</b> |
| <ul> |
| <li> <a href="#motivation">Motivation</a> |
| <li> <a href="#features">User visible and API Features (as implemented currently)</a> |
| <li> <a href="#covenant">Covenant</a> |
| <li> <a href="#rfe">RFE queue</a> |
| <li> <a href="#performance">Performance</a> |
| <li> <a href="#hypertext">Use as a hypertext widget</a> |
| <li> <a href="#design_issues">Design issues</a> |
| <li> <a href="#source_code">Source code and demos</a> |
| <ul> |
| <li> <a href="#demo_build">Build tool demo</a> |
| <li> <a href="#demo_telnet">Telnet demo</a> |
| </ul> |
| </ul> |
| |
| <hr> |
| |
| <a name="motivation"> |
| <h2> |
| Motivation |
| </h2> |
| The original impetus for Term was the need for a terminal |
| emulator for use by adaptations of NetBeans for non-Java development. |
| These tools need a proper terminal emulator in at least three areas: |
| <ul> |
| <li> |
| A window for program io, for programs being run under the debugger. |
| These programs will be traditional unix programs and may utilize |
| various levels of terminal manipulation, programs like 'more', |
| 'top', 'vi' and 'ksh'. |
| <li> |
| A window for the debugger (e.g. dbx) command io. The dbx command |
| interpreter is a ksh variant and as such allows input history editing |
| or execution of any unix program (like 'vi'). |
| <li> |
| A window for running alternative text editors, 'vi' or 'vim' under. |
| More on this later. |
| </ul> |
| |
| The NetBeans community had expressed interest in such a component as a |
| candidate for the NetBeans build and other output windows. |
| The package was |
| <a href= |
| "http://www.netbeans.org/servlets/ReadMsg?msgId=141308&listName=contrib"> |
| contributed</a> |
| to the NB source base circa Aug 2001. |
| <p> |
| |
| A terminal emulator can also be used as a within-nb shell or telnet window. |
| See the |
| <a href="#demo_telnet">source code for a telnet demo</a>. |
| |
| <a name="features"> |
| <h2> |
| User visible and API Features (as implemented currently) |
| </h2> |
| |
| <ul> |
| <li> |
| The base Term class handles "dumb" operations, putting characters |
| on a screen and forwarding keystrokes. |
| |
| <p><li> |
| ANSI operations for cursor control, line manipulation etc. |
| <li> |
| ANSI color and other character attribute escape processing. |
| <br> |
| Not All sequences are implemented yet. |
| <p> |
| As references I used |
| <a href="http://www.fh-jena.de/~gmueller/Kurs_halle/esc_vt100.html"> |
| Robert Frees spec</a> |
| and |
| <a href="http://enterprise.aacc.cc.md.us/~rhs/ansi.html"> |
| this |
| </a> |
| as well as the DtTerm(3) man page from Solaris. |
| <p> |
| <li> |
| The interpretation of characters is done by an abstract |
| <a name="interpreter">interpreter</a>. |
| |
| A set of classes are provided for |
| <a href="interpreter.html">interpreter construction</a> |
| using state machines. |
| |
| The current default interpreter is a simple ANSI interpreter, polluted |
| with some DtTerm extensions. |
| |
| <p> |
| <li> |
| Selection service in character, word and line modes modelled on xterm with |
| configurable word boundary detection. |
| <br> |
| This should work particularly well under X-windows with JDK1.4 where they |
| have fixed X-windows selections. |
| <li> |
| Auto-scrolling for the selection when the mouse moves outside of the view. |
| |
| <p> |
| <li> |
| History buffer and vertical scrolling. |
| The history can be traversed using a ... |
| |
| <li> |
| <list>LogicalLineVistor</list> |
| <br> |
| Provides access to whole history buffer contents and facilitates |
| searches and contents dumps etc. Suitable information and mechanisms are |
| provided for mapping a logical line to screen coordinates to facilitate |
| highlighting and resumption of search for example. |
| |
| <p> |
| <li> |
| Horizontal scrolling. |
| |
| <p> |
| <li> |
| Pluggable "line discipline". |
| <p> |
| Unlike other termulators Term does not |
| do things like line buffering, echoing, CR/LF processing and so on. |
| Since it is predominantly intended for use under Unix and since |
| under Unix all this stuff is done by the kernel (accessed through |
| pty's) Term doesn't bother with any of this. |
| <p> |
| However, there is a mechanism analogous to SVR4 io streams, or |
| pushable network stack elements, that allows customization of |
| character processing on other systems. A generic simple |
| stream module, <list>LineDiscipline</list> is provided in this package. |
| <p> |
| Stream modules can be used for other purposes like recording of the io |
| to some history file or for testing purposes. |
| |
| <p> |
| <li> |
| Mechanisms for dealing with resizing for interaction with ptys and |
| telnet protocols. |
| |
| <p> |
| <li> |
| "editor and glyph support". The original Solaris Workshop used an |
| enhanced DtTerm (The CDE termulator widget) that provided for |
| improved interaction with vi and the rest of the IDE. |
| So does Term: |
| <ul> |
| <li> |
| Ability to render glyphs in a "glyph gutter". |
| |
| <li> |
| Ability to convert mouse clicks to row/col coordinates and even |
| the underlying text. For use by "balloon evaluation" for example. |
| |
| <li> |
| Colored per-line background stripes, independent of ANSI |
| color escapes and the selection feedback. |
| </ul> |
| |
| <p> |
| <li> |
| Term interacts with the rest of the world using functions that send and |
| receive char arrays. A subclass, StreamTerm allows hooking up of |
| java.io Streams. Other subclasses could be derived which connect the |
| Term to telnet clients or pty streams (which naturally requires JNI |
| code and is therefore not part of this package). |
| |
| <p> |
| <li> |
| Choice of click-to-type or follow-mouse focus. |
| <li> |
| Choice of XOR or Swing style selection feedback. |
| |
| <p> |
| <li> |
| Handles Sun keyboard Cut, Copy, Paste keys. Since they _are_ available |
| as AWT key codes. |
| <p> |
| <li> |
| Methods for querying and setting cursor location. |
| <br> |
| This can be used, for example, to ensure that a horizontal line |
| starts on column 0. |
| |
| <p> |
| <li> |
| Consuming key events. |
| <br> |
| Because of it's nature, Term, by default, consumes all of the keystrokes |
| it gets and passes them through to the output stream. |
| <p> |
| A set of <list>KeyStrokes</list> may be registered with Term though to |
| allow passing through of keystrokes of the clients choice. |
| |
| </ul> |
| |
| Note that there are two important differences between this widget and |
| traditional Java text widgets: |
| <ul> |
| <li> |
| Because of the focus on cursor addressability it only works with |
| fixed-width fonts. It will accept any font setting but will |
| mutate it into a monospaced one. |
| <br> |
| Although there is some discussion to relax this considering the dearth of |
| monospaced unicode fonts. |
| <p><li> |
| It doesn't view documents; it's an input stream viewer. |
| This leads to some |
| <a href="#interesting_design_issues"> |
| interesting design issues |
| </a> |
| . |
| </ul> |
| |
| <p> |
| The UI ... is just too simple to be worth a picture. |
| <br> |
| It's just a screen area where text appears and a Swing scrollbar |
| in whatever is the current L&F. |
| |
| <p> |
| This proposal comes with |
| <a href="../package-summary.html">Javadoc API documentation</a> |
| and a |
| <a href="properties.html">properties table</a> |
| . |
| |
| <a name="covenant"> |
| <h2> |
| Covenant |
| </h2> |
| (A covenant is a part of a property deed that puts restrictions on the use |
| of the property on all future owners) |
| <p> |
| |
| <ul> |
| <li> |
| No additional dependencies. I would like Term to be usable outside |
| of NetBeans and therefore it should not depend on packages like |
| openide and so on. |
| </ul> |
| |
| <a name="rfe"> |
| <h2> |
| RFE queue |
| </h2> |
| These are things that are planned but not implemented yet. |
| <ul> |
| <p><li> |
| Misc. terminal things like ... |
| <ul> |
| <li> |
| Control of cursor style. |
| <li> |
| Bell: audible/visible. |
| <li> |
| Margin warning. |
| </ul> |
| <p><li> |
| Resize tooltip so you can get your columns and rows just they way you want them. |
| <p><li> |
| Line re-breaking. |
| <br> |
| You average terminal emulator will keep line breaks (due to wrapping) |
| at the original column when the width of the emulator changes. |
| It should be possible to re-break them as the width changes. |
| |
| <p><li> |
| Accessibility. |
| <br> |
| This used to be an "issue" mainly because I hadn't learned much about it. |
| |
| Term will implement the Accessible interface. The class Accessible is |
| really just a front gate to a whole host of other stuff that needs to |
| be implemented. |
| </ul> |
| |
| <a name="performance"> |
| <h2> |
| Performance |
| </h2> |
| Term is made up of the two main subsystems: |
| <dl> |
| <dt>Buffer maintenance |
| <dd> |
| This is the process of processing input characters and adding |
| them to the buffer, advancing the position of the cursor, |
| adding new lines at the bottom and taking away lines at the top. |
| <p> |
| The information is stored in a Vector of Lines. Each Line has a |
| an array of 'char's for character storage and an Array of 'int's |
| for attribute storage. These two arrays grow together (which is |
| more efficient than having two separate Vectors or StringBuffers). |
| However the attribute array may be null if all the characters in the |
| line have no attributes. |
| <p> |
| In order to prevent needless copying, these buffers are directly |
| available to the paint functions. |
| |
| <p> |
| <dt>Painting |
| <dd> |
| This is he process of drawing the view of the buffer unto a canvas. |
| On each refresh the _whole_ view is redrawn! Since Swing's |
| refresh manager already provides a double buffered image there is |
| no user visible flickering. |
| <p> |
| Lines w/o attributes are rendered using Graphics.drawChars() in |
| the double buffered image setup by default by Swing and AWT. |
| <p> |
| Lines with attributes are rendered a "run" at a time. A run is |
| a sequence of characters all of which have the same attributes. |
| <p> |
| There are also various adornments to be rendered, like the cursor, |
| slection highlight, glyphs and so on. |
| <dd> |
| </dl> |
| The following points may be made: |
| <ul> |
| <li> |
| Redrawing the whole screen at the slightest excuse seems like a |
| bad idea. But it's premature to do anyting about this yet since |
| Term interaction with JScrollPane has not yet been finalized. |
| <li> |
| Regardlass of the the use of runs, use of attributes will always have a |
| slightly higher overhead in both buffer memory use and painting time. |
| </ul> |
| When measuring or comparing performance attention should be paid to the |
| following: |
| <dl> |
| <a name="buffering"> |
| <dt>Buffering |
| <dd> |
| A repaint request is posted on every call to Term.putChar() and |
| every call to Term.putChars(). Obviously things are going to go |
| through much faster if you buffer 1000 characters and send them |
| via putChars() instead of calling putChar() 1000 times. The |
| first implementation of LineDiscipline() actually made this mistake. |
| |
| <a name="batching"> |
| <dt>Batching of refreshes |
| <dd> |
| The Swing (AWT?) repaint manager has it's own batching |
| which will compensate a bit for a high frequency of repaint |
| requests. |
| <dd> |
| |
| <dt>Jump scrolling |
| <dd> |
| If you 'cat' a large file into a termulator you can have you choice |
| of two extremes, seeing every line go by and waiting for it all |
| to go by or having the printing finish quickly and seeing |
| "jumps" in the output (while the history buffer retains everything). |
| <p> |
| These two alternatives are usually controlled by a property known as |
| "jump scrolling". Term doesn't have it but the effect can |
| be achieved by appropriately buffering the input and or internally |
| using paintImmediately(). |
| </dl> |
| Having said all of this, in my experience with the current implementation, |
| painting completely dominates buffer maintenance, so when you're |
| comparing Term with something else make sure they have comparable |
| refreshes/bytes-of-input. |
| |
| <a name="hypertext"> |
| <h2> |
| Use as a hypertext widget |
| </h2> |
| Term has facilities that allow it to be used as a reasonable styled |
| language and hypertext widget. |
| <ul> |
| <li> |
| Styled text can be rendered using ANSI color and font escapes, or |
| method calls, like <l>Term.setCharacterAttribute()</l>. |
| One can even concieve of an |
| <a href="#interpreter">Intepreter</a> |
| that interprets HTML. |
| |
| <p><li> |
| An "Active Region" can be delineated through extended character |
| escapes or method calls (<l>Term.getRegionManager().beginRegion()</l>). |
| Active regions may be nested and the region manager can map a given |
| cursor (or pointer) position to the regions. This is the minimal |
| functionlaity with which a client can associate user data and actions with |
| active regions and highlight a region when a pointer passes over it, |
| execute an action on a click, or pop up a menu. |
| |
| <p><li> |
| History can be "anchored" so that the beginning of a "page" of hypertext |
| doesn't vanish even if it's length exceeds the history size. |
| In other words, |
| when anchored, the history is temporarily expanded to accomodate the page. |
| </ul> |
| |
| |
| <a name="design_issues"> |
| <h2> |
| Design issues |
| </h2> |
| I've been working off of O'Reilly publishers "JAVA Swing" by Eckstein, Loy |
| and Wood. |
| Many of the issues here are in the context of that book. |
| <p> |
| The issues often have to do with my ignorance or lack of good guidelines on a |
| subject and are really a plea for suggestions, education and discussion. |
| <p> |
| |
| <dl> |
| <dt> |
| <b> |
| Swing Model and UI Delegate |
| </b> |
| <dd> |
| In ch 28 it is said that a proper swing widget has to have a |
| Model and a UI Delegate. Term currently has neither. |
| <p> |
| |
| <dl> |
| <dt> |
| Why not a UIDelegate? |
| <dd> |
| Term used to have no "artwork" that needed to be drawn depending on a |
| specific look and feel. But now it has at least the following |
| properties that could be construed as L&F specific: |
| |
| <dl> |
| <p><dt>selectionXOR<dd> |
| You can control whether selections are done using Swing |
| style (background highlighting) or using the more |
| traditional XOR style. |
| One could couch this as a L&F controllable setting with the XOR |
| style going to the Motif L&F. |
| <p><dt>autoCopy<dd> |
| On unix selections usually go to the primary selection. On |
| windows they go into the clipboard and only if a Copy action |
| was requested. |
| <p><dt>clickToType<dd> |
| Windows users live in the ClickToType (focus) world. |
| Unix people (i expect) prefer the "follow mouse" style |
| of focus control. |
| </dl> |
| |
| <p> |
| Also, term is a "composite" widget and it is unclear to me how |
| one implements UIDelegates for composites, or whether one is |
| even needed. |
| |
| <p> |
| <a name="interesting_design_issues"> |
| <dt> |
| Why not a Model? |
| </a> |
| <dd> |
| In any text rendering widget the model is typically a "document". |
| The equivalent of this in a termulator would be the history buffer, |
| or if no history, just the screen backing storage. |
| <p> |
| However, this is really an internal implementation and a terminal |
| really interacts with the external world through it's io lines, |
| so the model is conceptually a "connection". |
| <p> |
| But a connection doesn't fit in with things like model-changed |
| events and such ... the data stored in the screen |
| backing store is ephemeral, it soon winks out of the history buffer. |
| So, I"m not exactly sure what a model would be for a termulator. |
| <p> |
| One candidate is the concept of sessions (A concept used in the |
| KDE 'konsole') where a single widget can multiplex between |
| multiple connections and the corresponding history buffers. |
| While such a feature should definitely be on the rfe list, |
| again, I'm not sure whether the Swing concept of a Model is |
| appropriate here. |
| <br> |
| To that end the current implementation has a Document class used |
| internally, but there's still a bit to go. |
| </dl> |
| |
| |
| |
| <p> |
| <dt> |
| <b> |
| Working with JScrollPane |
| </b> |
| <dd> |
| Term is a composite and carries it's own scrollbar. |
| <br> |
| It is not JScrollPane-friendly. |
| <br> |
| Here's why ... |
| <p> |
| Initially it seems obvious that it should, like every other good Swing |
| component, implement Scrollable, work properly under a JScrollPane and |
| not contain it's own scrollbar, but this is not neccessarily a good idea. |
| <p> |
| Usually the size of a component refers to it's visible size. |
| But when the component is placed under a JScrollPane, it's size starts |
| referring to it's "virtual" size over which the user scrolls. |
| While this makes complete sense for tables, lists, and text documents, |
| in the case of a terminal emulator we don't want this. We want size |
| to still govern the visible screen size! |
| <p> |
| It is perhaps possible to design a Term that works under JScrollPane such |
| that resizes communicate the viewport size via TermListener.sizeChanged() |
| and setRows() sets the viewports size (this I actually can't figure how |
| to do). But this requires that Term discover that it's under a |
| JScrollPane and things become progressively more complex from there on. |
| <p> |
| Another argument can be made from a utility standpoint. |
| <br> |
| Most termulator applications (xterm) and widgets (DtTerm) have a property |
| that governs whether and where they have a scrollbar. It would be much more |
| convenient to retain this as a runtime controllable property of |
| Term itself (read <i>user option</i>) instead of |
| having the <i>container</i> of Term manage that; |
| create a JScrollPane, put Term under it etc. in response to user |
| option toggling. |
| |
| <p> |
| <dt> |
| <b> |
| Reuse of and differences from standard Swing text components |
| </b> |
| <dd> |
| Why write a text rendering widget from scratch? Following are some reasons. |
| Some of them probably stem more from my ignorance of Swing or the NIH |
| syndrome, but others I believe are fair justifications for a new component. |
| |
| <ul> |
| |
| <p> |
| <li> |
| Speed. |
| <br> |
| In my experience Swing text components just can't handle |
| the volumes of stuff coming into them that you typically get |
| in consoles. |
| <p> |
| I believe this is not so much because of the complex Document and Element |
| structures but due to the same reasons that could make Term slow, and |
| that is control over buffering and batching, or rather lack thereof. |
| Read the |
| <a href="#performance">section on performance</a> to see |
| what I mean. |
| |
| <p> |
| <li> |
| The selection and the cursor are strongly tied together in Swing. With Term |
| the selection is independent of the cursor. |
| |
| <p> |
| <li> |
| Swing provides a whole infrastructure for Actions, KeyMaps, undoing etc. |
| Which are neccessary for it's functioning as a document "editor". Term, |
| while internally maintaining a document and performing "edits" on it, is |
| not fundamentally an editor and can dispense with all of the above. |
| |
| <p> |
| <li> |
| Swing uses offsets as opposed to cartesian coordinates. Since the |
| bulk of the operations of terminal emulators involves cartesian |
| cursor motion and such, in order to reuse a Swing text component a |
| fair amount of machinery has to be added to convert between the two. |
| <br> |
| Some ideas I've tossed out: |
| <p> |
| <dl> |
| <dt>Pad lines with spaces |
| <dd>... so every "line" is 80 characters wide, making it easier |
| to do arithmetic. But then selection will absorb those spaces |
| which have to be thrown out etc. |
| |
| <dt>Track line boundaries |
| <dd> |
| Using Positions for evey line? Expensive. |
| Tracking edits and maintaining my own map? Exspensive. |
| |
| <dt>Use "Line" Elements. |
| <dd>Expensive but more importantly means we forego using Elements |
| for more useful delineations. |
| |
| </dl> |
| |
| <p> |
| <li> |
| Swing Elements are very similar to Terms ActiveRegions. |
| They differ in the following respects though: |
| <ul> |
| <p> |
| <li> |
| Elements use Positions. While ActiveRegions use Coords. |
| Positions are "marks" and entail a fair amount of overhead, |
| while Coords are like offsets. |
| <p> |
| The offsets used by Term are actually valid as regions go out |
| of history. This because "absolute coordinates" are used where |
| each line put into Terms history gets a serial row number which |
| only grows. Term correctly handles the case where the 32-bit |
| absolute row number wraps. At a continuous rate of output of |
| 4000 lines/sec the wrapping will happenin about 4 days. |
| |
| <p> |
| <li> |
| Elements and AttributeSets are tightly bound, while with Term |
| Character attributes are set completely independently of Active |
| Regions. |
| |
| <p> |
| <li> |
| Elements are strictly nested. That is, there is no gap between |
| the beginning of a branch Element and the beginning of it's first |
| child. ActiveRegions can be arranged more flexibly. |
| </ul> |
| |
| <p> |
| <li> |
| CaretEvent gets fired everytime the cursor moves. Imagine what this does |
| to massive amounts of text being hurled at a terminal emulator, even |
| if no-one is listening. |
| |
| <p> |
| <li> |
| Swings 'int offset' is "between" characters, while termulators work |
| with coordinates "on" characters. I"m not sure that Position's BIAS |
| would help here. (This is perhaps a red herring since you can adopt |
| the convention that a caret's position implies a cursor on the character |
| following it). |
| |
| </ul> |
| |
| <p> |
| <dt> |
| <b> |
| Key tables |
| </b> |
| <dd> |
| (NOTE: This is not the same as Swings KeyMaps). |
| <br> |
| Term currently doesn't have a key map table. Most other termulators do. |
| The thing is I haven't yet seen the need. Lot of the usual type |
| of processing that key maps do seems to be absorbed by Swing and |
| AWT, so my initial hope was to just piggy-back on that. Same |
| thing for byte to char conversions. |
| <p> |
| There have been a few glitches like AWT converting a CR to a LF |
| that are currently being worked around in ad-hoc manner. |
| </dl> |
| |
| <a name="source_code"> |
| <h2> |
| Source code and demos |
| </h2> |
| </a> |
| The source code for Term is in the NB CVS repository under |
| <pre> |
| core/libsrc/org/netbeans/lib/terminalemulator. |
| </pre> |
| |
| Two demo's are available: |
| <br> |
| (<b>Actually they are not!</b> I'm not sure whether it is appropriate |
| to put them into the CVS repository). |
| |
| <a name="demo_build"> |
| <h3> |
| Build tool demo |
| </h3> |
| <img src="snapshot.gif" alt="Snapshot of DemoBuild"> |
| <br> |
| This is to showcase the capabilities of ActiveTerm and how it can be |
| used to annotate output, say from a build script. |
| <p> |
| A fair amount of the code has to do with the gui setup, javac Process |
| setup and capture of it's output. |
| Once the output is received it is processed line-by-line. A crude pattern |
| is used to detect the first line of a javac error message and a new |
| ActiveRegion is begun, while the previous one is ended. These active regions |
| have their feedback attribute set which means that they will be highlighted |
| as the mouse moves over them. Anyone who has had to decipher a |
| wrapped compilation line and error line from 'make' would appreciate this. |
| <p> |
| The sourcefilename and line number are also extracted using simple patterns |
| and put in their own ActiveRegions as HTML-style links, which if clicked will |
| bring up the right line # in some editor, or rather fake it using a popup. |
| <p> |
| The beginning of each error message is also tagged with a simple |
| glyph in the glyph gutter. |
| <p> |
| Please keep in mind that this is strictly a Term feature demo. |
| I"m not advocating using glyphs to tag error messasges, or that textual |
| pattern recognition should be used for detecting distinct error |
| messages and their component, nor is capturing of Process output is as |
| trivial as it seems here (if the demo had instead used 'make' you'd |
| see some reordering of output because some comes from stdout and |
| some comes from stderr). |
| |
| <a name="demo_telnet"> |
| <h3> |
| Telnet demo |
| </h3> |
| For a telnet client it uses portions of |
| <a href="http://www.mud.de/se/jta/"> |
| The Java(tm) Telnet Application/Applet |
| </a> |
| by Matthias L. Jugel and Marcus Meisner. |
| I haven't included that stuff here to save space but you only need |
| <pre> |
| de/mud/ternet/ScriptHandler.java |
| de/mud/ternet/TelnetProtocolHandler.java |
| de/mud/ternet/TelnetWrapper.java |
| </pre> |
| You'll have to tweak the settings in the Makefile and the 'telnet' wrapper |
| script. |
| |
| |
| </body> |
| </html> |