Change build scripts
[jvcard.git] / src / com / googlecode / lanterna / terminal / Terminal.java
1 /*
2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
3 *
4 * lanterna is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Copyright (C) 2010-2015 Martin
18 */
19 package com.googlecode.lanterna.terminal;
20
21 import com.googlecode.lanterna.SGR;
22 import com.googlecode.lanterna.TerminalSize;
23 import com.googlecode.lanterna.TextColor;
24 import com.googlecode.lanterna.graphics.TextGraphics;
25 import com.googlecode.lanterna.input.InputProvider;
26 import java.io.IOException;
27 import java.util.concurrent.TimeUnit;
28
29 /**
30 * This is the main terminal interface, at the lowest level supported by Lanterna. You can write your own
31 * implementation of this if you want to target an exotic text terminal specification or another graphical environment
32 * (like SWT), but you should probably extend {@code AbstractTerminal} instead of implementing this interface directly.
33 * <p>
34 * The normal way you interact in Java with a terminal is through the standard output (System.out) and standard error
35 * (System.err) and it's usually through printing text only. This interface abstracts a terminal at a more fundamental
36 * level, expressing methods for not only printing text but also changing colors, moving the cursor new positions,
37 * enable special modifiers and get notified when the terminal's size has changed.
38 * <p>
39 * If you want to write an application that has a very precise control of the terminal, this is the
40 * interface you should be programming against.
41 *
42 * @author Martin
43 */
44 public interface Terminal extends InputProvider {
45
46 /**
47 * Calling this method will, where supported, give your terminal a private area to use, separate from what was there
48 * before. Some terminal emulators will preserve the terminal history and restore it when you exit private mode.
49 * Some terminals will just clear the screen and put the cursor in the top-left corner. Typically, if you terminal
50 * supports scrolling, going into private mode will disable the scrolling and leave you with a fixed screen, which
51 * can be useful if you don't want to deal with what the terminal buffer will look like if the user scrolls up.
52 *
53 * @throws java.io.IOException If there was an underlying I/O error
54 * @throws IllegalStateException If you are already in private mode
55 */
56 void enterPrivateMode() throws IOException;
57
58 /**
59 * If you have previously entered private mode, this method will exit this and, depending on implementation, maybe
60 * restore what the terminal looked like before private mode was entered. If the terminal doesn't support a
61 * secondary buffer for private mode, it will probably make a new line below the private mode and place the cursor
62 * there.
63 *
64 * @throws java.io.IOException If there was an underlying I/O error
65 * @throws IllegalStateException If you are not in private mode
66 */
67 void exitPrivateMode() throws IOException;
68
69 /**
70 * Removes all the characters, colors and graphics from the screen and leaves you with a big empty space. Text
71 * cursor position is undefined after this call (depends on platform and terminal) so you should always call
72 * {@code moveCursor} next. Some terminal implementations doesn't reset color and modifier state so it's also good
73 * practise to call {@code resetColorAndSGR()} after this.
74 * @throws java.io.IOException If there was an underlying I/O error
75 */
76 void clearScreen() throws IOException;
77
78 /**
79 * Moves the text cursor to a new location on the terminal. The top-left corner has coordinates 0 x 0 and the bottom-
80 * right corner has coordinates terminal_width-1 x terminal_height-1. You can retrieve the size of the terminal by
81 * calling getTerminalSize().
82 *
83 * @param x The 0-indexed column to place the cursor at
84 * @param y The 0-indexed row to place the cursor at
85 * @throws java.io.IOException If there was an underlying I/O error
86 */
87 void setCursorPosition(int x, int y) throws IOException;
88
89 /**
90 * Hides or shows the text cursor, but not all terminal (-emulators) supports this. The text cursor is normally a
91 * text block or an underscore, sometimes blinking, which shows the user where keyboard-entered text is supposed to
92 * show up.
93 *
94 * @param visible Hides the text cursor if {@code false} and shows it if {@code true}
95 * @throws java.io.IOException If there was an underlying I/O error
96 */
97 void setCursorVisible(boolean visible) throws IOException;
98
99 /**
100 * Prints one character to the terminal at the current cursor location. Please note that the cursor will then move
101 * one column to the right, so multiple calls to {@code putCharacter} will print out a text string without the need
102 * to reposition the text cursor. If you reach the end of the line while putting characters using this method, you
103 * can expect the text cursor to move to the beginning of the next line.
104 * <p>
105 * You can output CJK (Chinese, Japanese, Korean) characters (as well as other regional scripts) but remember that
106 * the terminal that the user is using might not have the required font to render it. Also worth noticing is that
107 * CJK (and some others) characters tend to take up 2 columns per character, simply because they are a square in
108 * their construction as opposed to the somewhat rectangular shape we fit latin characters in. As it's very
109 * difficult to create a monospace font for CJK with a 2:1 height-width proportion, it seems like the implementers
110 * back in the days simply gave up and made each character take 2 column. It causes issues for the random terminal
111 * programmer because you can't really trust 1 character = 1 column, but I suppose it's "しょうがない".
112 *
113 * @param c Character to place on the terminal
114 * @throws java.io.IOException If there was an underlying I/O error
115 */
116 void putCharacter(char c) throws IOException;
117
118 /**
119 * Creates a new TextGraphics object that uses this Terminal directly when outputting. Keep in mind that you are
120 * probably better off to switch to a Screen to make advanced text graphics more efficient. Also, this TextGraphics
121 * implementation will not call {@code .flush()} after any operation, so you'll need to do that on your own.
122 * @return TextGraphics implementation that draws directly using this Terminal interface
123 */
124 TextGraphics newTextGraphics() throws IOException;
125
126 /**
127 * Activates an {@code SGR} (Selected Graphic Rendition) code. This code modifies a state inside the terminal
128 * that will apply to all characters written afterwards, such as bold, italic, blinking code and so on.
129 *
130 * @param sgr SGR code to apply
131 * @throws java.io.IOException If there was an underlying I/O error
132 * @see SGR
133 * @see <a href="http://www.vt100.net/docs/vt510-rm/SGR">http://www.vt100.net/docs/vt510-rm/SGR</a>
134 */
135 void enableSGR(SGR sgr) throws IOException;
136
137 /**
138 * Deactivates an {@code SGR} (Selected Graphic Rendition) code which has previously been activated through {@code
139 * enableSGR(..)}.
140 *
141 * @param sgr SGR code to apply
142 * @throws java.io.IOException If there was an underlying I/O error
143 * @see SGR
144 * @see <a href="http://www.vt100.net/docs/vt510-rm/SGR">http://www.vt100.net/docs/vt510-rm/SGR</a>
145 */
146 void disableSGR(SGR sgr) throws IOException;
147
148 /**
149 * Removes all currently active SGR codes and sets foreground and background colors back to default.
150 *
151 * @throws java.io.IOException If there was an underlying I/O error
152 * @see SGR
153 * @see <a href="http://www.vt100.net/docs/vt510-rm/SGR">http://www.vt100.net/docs/vt510-rm/SGR</a>
154 */
155 void resetColorAndSGR() throws IOException;
156
157 /**
158 * Changes the foreground color for all the following characters put to the terminal. The foreground color is what
159 * color to draw the text in, as opposed to the background color which is the color surrounding the characters.
160 * <p>
161 * This overload is using the TextColor class to define a color, which is a layer of abstraction above the three
162 * different color formats supported (ANSI, indexed and RGB). The other setForegroundColor(..) overloads gives
163 * you direct access to set one of those three.
164 * <p>
165 * Note to implementers of this interface, just make this method call <b>color.applyAsForeground(this);</b>
166 *
167 * @param color Color to use for foreground
168 * @throws java.io.IOException If there was an underlying I/O error
169 */
170 void setForegroundColor(TextColor color) throws IOException;
171
172 /**
173 * Changes the background color for all the following characters put to the terminal. The background color is the
174 * color surrounding the text being printed.
175 * <p>
176 * This overload is using the TextColor class to define a color, which is a layer of abstraction above the three
177 * different color formats supported (ANSI, indexed and RGB). The other setBackgroundColor(..) overloads gives
178 * you direct access to set one of those three.
179 * <p>
180 * Note to implementers of this interface, just make this method call <b>color.applyAsBackground(this);</b>
181 *
182 * @param color Color to use for the background
183 * @throws java.io.IOException If there was an underlying I/O error
184 */
185 void setBackgroundColor(TextColor color) throws IOException;
186
187 /**
188 * Adds a {@code ResizeListener} to be called when the terminal has changed size. There is no guarantee that this
189 * listener will really be invoked when the terminal has changed size, at all depends on the terminal emulator
190 * implementation. Normally on Unix systems the WINCH signal will be sent to the process and lanterna can intercept
191 * this.
192 * <p>
193 * There are no guarantees on what thread the call will be made on, so please be careful with what kind of operation
194 * you perform in this callback. You should probably not take too long to return.
195 *
196 * @see ResizeListener
197 * @param listener Listener object to be called when the terminal has been changed
198 */
199 void addResizeListener(ResizeListener listener);
200
201 /**
202 * Removes a {@code ResizeListener} from the list of listeners to be notified when the terminal has changed size
203 *
204 * @see ResizeListener
205 * @param listener Listener object to remove
206 */
207 void removeResizeListener(ResizeListener listener);
208
209 /**
210 * Returns the size of the terminal, expressed as a {@code TerminalSize} object. Please bear in mind that depending
211 * on the {@code Terminal} implementation, this may or may not be accurate. See the implementing classes for more
212 * information. Most commonly, calling getTerminalSize() will involve some kind of hack to retrieve the size of the
213 * terminal, like moving the cursor to position 5000x5000 and then read back the location, unless the terminal
214 * implementation has a more smooth way of getting this data. Keep this in mind and see if you can avoid calling
215 * this method too often. There is a helper class, SimpleTerminalResizeListener, that you can use to cache the size
216 * and update it only when resize events are received (which depends on if a resize is detectable, which they are not
217 * on all platforms).
218 *
219 * @return Size of the terminal
220 * @throws java.io.IOException if there was an I/O error trying to retrieve the size of the terminal
221 */
222 TerminalSize getTerminalSize() throws IOException;
223
224 /**
225 * Retrieves optional information from the terminal by printing the ENQ ({@literal \}u005) character. Terminals and terminal
226 * emulators may or may not respond to this command, sometimes it's configurable.
227 *
228 * @param timeout How long to wait for the talk-back message, if there's nothing immediately available on the input
229 * stream, you should probably set this to a somewhat small value to prevent unnecessary blockage on the input stream
230 * but large enough to accommodate a round-trip to the user's terminal (~300 ms if you are connection across the globe).
231 * @param timeoutUnit What unit to use when interpreting the {@code timeout} parameter
232 * @return Answer-back message from the terminal or empty if there was nothing
233 * @throws java.io.IOException If there was an I/O error while trying to read the enquiry reply
234 */
235 byte[] enquireTerminal(int timeout, TimeUnit timeoutUnit) throws IOException;
236
237 /**
238 * Calls {@code flush()} on the underlying {@code OutputStream} object, or whatever other implementation this
239 * terminal is built around. Some implementing classes of this interface (like SwingTerminal) doesn't do anything
240 * as it doesn't really apply to them.
241 * @throws java.io.IOException If there was an underlying I/O error
242 */
243 void flush() throws IOException;
244 }