Skip to content

Commit

Permalink
Updating first part of the dev guide to Lanterna 3
Browse files Browse the repository at this point in the history
  • Loading branch information
mabe02 committed Apr 30, 2017
1 parent fd5e3b1 commit 0a2ea84
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 141 deletions.
71 changes: 55 additions & 16 deletions docs/introduction.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,64 @@
## Introduction ##
This document will give you a general introduction to how text terminals work and how Lanterna interacts with them. In the sub-documents, you can find specific guides on how to program each one of the layers. You are encouraged to read them all and in order to get the full picture.
## Introduction
This document will give you a general introduction to how text terminals work and how Lanterna interacts with them.
In the sub-documents, you can find specific guides on how to program each one of the layers.
You are encouraged to read them all and in order to get the full picture.

## About terminals ##
### TERM and terminfo ###
The way terminals work make things difficult when you want to create a portable text GUI. Initially, way back, each computer system might have its own set of control characters, a kind of escape sequence, that signalled to the screen that a special action (such as setting the text color to red) what about to happen. With different systems and different environment, it was tough to write a program that would work everywhere and have the same appearance (well, if you stick to just printing text, that's probably fine, but if you wanted to make use of more advanced commands such as moving the cursor, setting the color of the text, making the text blink or change to bold font, etc, then you had a bit of a problem.
## About terminals
### TERM and terminfo
The way terminals work make things difficult when you want to create a portable text GUI. Initially, way back, each
computer system might have its own set of control characters, a kind of escape sequence, that signalled to the screen
that a special action (such as setting the text color to red) what about to happen. With different systems and different
environment, it was tough to write a program that would work everywhere and have the same appearance (well, if you stick
to just printing text, that's probably fine, but if you wanted to make use of more advanced commands such as moving the
cursor, setting the color of the text, making the text blink or change to bold font, etc, then you had a bit of a
problem.

There was then an idea that when a terminal logs on to a system, it will set the TERM environmental variable to a particular value that represented which standard it supported. On the system is then a database with different standards and so any program using text magic can look up the TERM value in this database and get a list of commands supported and how to execute them. There is however no guarantee that the terminal will set this variable and there is no guarantee that the system will have the value in its database. Also, there may be discrepancies when, for example, several implementations of `xterm` exists, which one do you store in your database (the implementations mostly agree on the control characters, but not completely)?
There was then an idea that when a terminal logs on to a system, it will set the TERM environmental variable to a
particular value that represented which standard it supported. On the system is then a database with different standards
and so any program using text magic can look up the TERM value in this database and get a list of commands supported and
how to execute them. There is however no guarantee that the terminal will set this variable and there is no guarantee
that the system will have the value in its database. Also, there may be discrepancies when, for example, several
implementations of `xterm` exists, which one do you store in your database (the implementations mostly agree on the
control characters, but not completely)?

Today, most terminals will identify themselves as `xterm` through the TERM environmental variable and for the most part support this. There is also an [ANSI standard](http://en.wikipedia.org/wiki/ANSI_escape_code) for escape codes and this is very much in line with what most terminal emulators supports. Incompatibilities arises mostly when it comes to special keys on the keyboard, such as insert, home, end, page up, and so on, what the terminal emulator will send on standard input when those keys are pressed.
Today, most terminals will identify themselves as `xterm` through the TERM environmental variable and for the most part
support this. There is also an [ANSI standard](http://en.wikipedia.org/wiki/ANSI_escape_code) for escape codes and this
is very much in line with what most terminal emulators supports. Incompatibilities arises mostly when it comes to
special keys on the keyboard, such as insert, home, end, page up, and so on, what the terminal emulator will send on
standard input when those keys are pressed.

### Lanterna ###
Lanterna will use the **xterm** standard as most terminals understands it, which is basically the standard [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code). Furthermore, only the [standard 8 colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) with 8 brighter versions are supported. As notes in the previous passage, where terminals diverge most from the **xterm** spec is with the escape codes for all special keyboard keys. At the moment, Lantern tries to accommodate for all of them by adding 'input profiles' for each known type. As new terminal (emulators) are added, the profiles might need to be updated. So far, as a developer you shouldn't need to mess around with these profiles as there are no key collisions and we'll try to add any popular terminal emulator out there. The idea is that Lanterna should work right out of the box, without any tweaking to make it work with your favourite terminal emulator.
### Lanterna
Lanterna will use the `xterm` standard as most terminals understands it, which is basically the standard
[ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code). As notes in the previous passage, where terminals
diverge most from the `xterm` spec is with the escape codes for all the special keyboard keys. At the moment, Lantern
tries to accommodate for all of them by adding 'input profiles' for each known type. As new terminal (emulators) are
added, the profiles might need to be updated. So far, as a developer you shouldn't need to mess around with these
profiles as there are no key collisions and we'll try to add any popular terminal emulator out there. The idea is that
Lanterna should work right out of the box, without any tweaking to make it work with your favourite terminal emulator.

### Encoding ###
Another problem is the encoding, where terminals may or may not support UTF-8 no matter how you tweak it. By default, Lanterna will use the system property **file.encoding**, which is setup automatically by the JVM. This seems to be sufficient with most terminals, but you may want to present the user with an option to force either UTF-8 or iso-8859-1, maybe through a command-line argument.
Some more exotic extensions are also supported, such as mouse support and colors above the standard ANSI 8+8. When using
this functionality though, it's likely that your application will have compatibility issues with some common terminal
emulators used in the wild. A good rule of thumb is that if it works with vanilla `xterm`, it will probably be
relatively well-supported.

## How big is the terminal? ##
Yet another problem is how to know the size of the terminal. There are ways of figuring this out through C APIs for most platforms but since Lanterna is intended to be 100% Java code, we can't do that. Instead, Lanterna is doing a bit of a hack by memorizing the cursor location, then moving it to 5000x5000 and asking the terminal to print the position. Since most terminal won't be that big, the cursor will end up in the bottom right corner and report this position when we ask to print it. This will be the size of the terminal.
### Encoding
Another problem is the encoding, where terminals may or may not support UTF-8 no matter how you tweak it. By default,
Lanterna will use the system property `file.encoding`, which is setup automatically by the JVM. This seems to be
sufficient with most terminals, but you may want to present the user with an option to force either UTF-8 or iso-8859-1
(or whatever you see suitable), maybe through a command-line argument.

### What if it doesn't work? ###
## How big is the terminal?
Yet another problem is how to know the size of the terminal. There are ways of figuring this out through C APIs for most
platforms but since Lanterna is intended to be 100% Java code, we can't do that. Instead, Lanterna is doing a bit of a
hack by memorizing the cursor location, then moving it to 5000x5000 and asking the terminal to print the position. Since
most terminal won't be that big, the cursor will end up in the bottom right corner and report this position when we ask
to print it. This will be the size of the terminal.

### What if it doesn't work?
Let us know!

### What happens if the user resizes the window? ###
There is a special Unix signal to notify an application that the terminal has been resized and that one is WINCH. This is currently implemented using `sun.misc.SignalHandler` which is SUN JRE specific code and probably not portable. Still, catching signals without invoking native code seems difficult and relying on JNI calls is something we don't want to do. This will probably be changed to be done through Java reflections through autodetection of the JVM.
### What happens if the user resizes the window?
There is a special Unix signal to notify an application that the terminal has been resized and that one is WINCH. This
is currently implemented using `sun.misc.SignalHandler` which is SUN JRE specific code and probably not portable. Still,
catching signals without invoking native code seems difficult and relying on JNI calls is something we don't want to do.
This will probably be changed to be done through Java reflections through auto-detection by the JVM.
Loading

0 comments on commit 0a2ea84

Please sign in to comment.