Commit | Line | Data |
---|---|---|
a3b510ab NR |
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 | } |