KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jline > WindowsTerminal


1 /**
2  * jline - Java console input library
3  * Copyright (c) 2002,2003 Marc Prud'hommeaux mwp1@cornell.edu
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 package jline;
20
21 import java.io.*;
22 import java.util.*;
23
24 // TODO: handle arrow keys, which might require completely implementing the
25
// console input reading in the .dll. For example, see:
26
// http://cvs.sourceforge.net/viewcvs.py/lifelines/lifelines/win32/mycurses.c?rev=1.28
27

28 /**
29  * <p>
30  * Terminal implementation for Microsoft Windows. Terminal initialization
31  * in {@link #initializeTerminal} is accomplished by extracting the
32  * <code>jline_<i>version</i>.dll</code>, saving it to the system temporary
33  * directoy (determined by the setting of the <code>java.io.tmpdir</code>
34  * System property), loading the library, and then calling the Win32 APIs
35  * <a HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/setconsolemode.asp">SetConsoleMode</a>
36  * and
37  * <a HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getconsolemode.asp">GetConsoleMode</a>
38  * to disable character echoing.
39  * </p>
40  *
41  * @author <a HREF="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
42  */

43 public class WindowsTerminal
44     extends Terminal
45 {
46     // constants copied from wincon.h
47

48     /**
49      * The ReadFile or ReadConsole function returns only when
50      * a carriage return character is read. If this mode is disable,
51      * the functions return when one or more characters are
52      * available.
53      */

54     private static final int ENABLE_LINE_INPUT = 2;
55
56
57     /**
58      * Characters read by the ReadFile or ReadConsole function
59      * are written to the active screen buffer as they are read.
60      * This mode can be used only if the ENABLE_LINE_INPUT mode
61      * is also enabled.
62      */

63     private static final int ENABLE_ECHO_INPUT = 4;
64
65
66     /**
67      * CTRL+C is processed by the system and is not placed
68      * in the input buffer. If the input buffer is being read
69      * by ReadFile or ReadConsole, other control keys are processed
70      * by the system and are not returned in the ReadFile or ReadConsole
71      * buffer. If the ENABLE_LINE_INPUT mode is also enabled,
72      * backspace, carriage return, and linefeed characters are
73      * handled by the system.
74      */

75     private static final int ENABLE_PROCESSED_INPUT = 1;
76
77
78     /**
79      * User interactions that change the size of the console
80      * screen buffer are reported in the console's input buffee.
81      * Information about these events can be read from the input
82      * buffer by applications using theReadConsoleInput function,
83      * but not by those using ReadFile orReadConsole.
84      */

85     private static final int ENABLE_WINDOW_INPUT = 8;
86
87
88     /**
89      * If the mouse pointer is within the borders of the console
90      * window and the window has the keyboard focus, mouse events
91      * generated by mouse movement and button presses are placed
92      * in the input buffer. These events are discarded by ReadFile
93      * or ReadConsole, even when this mode is enabled.
94      */

95     private static final int ENABLE_MOUSE_INPUT = 16;
96
97
98     /**
99      * When enabled, text entered in a console window will
100      * be inserted at the current cursor location and all text
101      * following that location will not be overwritten. When disabled,
102      * all following text will be overwritten. An OR operation
103      * must be performed with this flag and the ENABLE_EXTENDED_FLAGS
104      * flag to enable this functionality.
105      */

106     private static final int ENABLE_PROCESSED_OUTPUT = 1;
107
108
109     /**
110      * This flag enables the user to use the mouse to select
111      * and edit text. To enable this option, use the OR to combine
112      * this flag with ENABLE_EXTENDED_FLAGS.
113      */

114     private static final int ENABLE_WRAP_AT_EOL_OUTPUT = 2;
115
116
117
118     private native int getConsoleMode ();
119
120     private native void setConsoleMode (int mode);
121
122
123     public void initializeTerminal ()
124         throws Exception JavaDoc
125     {
126         loadLibrary ("jline");
127
128         final int originalMode = getConsoleMode ();
129
130         setConsoleMode (originalMode & ~ENABLE_ECHO_INPUT);
131
132         // set the console to raw mode
133
int newMode = originalMode
134             & ~(ENABLE_LINE_INPUT
135                 | ENABLE_ECHO_INPUT
136                 | ENABLE_PROCESSED_INPUT
137                 | ENABLE_WINDOW_INPUT);
138         setConsoleMode (newMode);
139
140         // at exit, restore the original tty configuration (for JDK 1.3+)
141
try
142         {
143             Runtime.getRuntime ().addShutdownHook (new Thread JavaDoc ()
144             {
145                 public void start ()
146                 {
147                     // restore the old console mode
148
setConsoleMode (originalMode);
149                 }
150             });
151         }
152         catch (AbstractMethodError JavaDoc ame)
153         {
154             // JDK 1.3+ only method. Bummer.
155
}
156     }
157
158
159     private void loadLibrary (String JavaDoc name)
160         throws IOException
161     {
162         // store the DLL in the temporary directory for the System
163
String JavaDoc version = getClass ().getPackage ().getImplementationVersion ();
164         if (version == null)
165             version = "";
166         version = version.replace ('.', '_');
167
168         File f = new File (System.getProperty ("java.io.tmpdir"),
169             name + "_" + version + ".dll");
170         boolean exists = f.isFile (); // check if it already exists
171

172         // extract the embedded jline.dll file from the jar and save
173
// it to the current directory
174
InputStream in = new BufferedInputStream (getClass ()
175             .getResourceAsStream (name + ".dll"));
176
177         try
178         {
179             OutputStream fout = new BufferedOutputStream (
180                 new FileOutputStream (f));
181             byte[] bytes = new byte [1024 * 10];
182             for (int n = 0; n != -1; n = in.read (bytes))
183                 fout.write (bytes, 0, n);
184
185             fout.close ();
186         }
187         catch (IOException ioe)
188         {
189             // We might get an IOException trying to overwrite an existing
190
// jline.dll file if there is another process using the DLL.
191
// If this happens, ignore errors.
192
if (!exists)
193                 throw ioe;
194         }
195
196         // try to clean up the DLL after the JVM exits
197
f.deleteOnExit ();
198
199         // now actually load the DLL
200
System.load (f.getAbsolutePath ());
201     }
202
203
204     public boolean isSupported ()
205     {
206         return true;
207     }
208
209
210     public boolean getEcho ()
211     {
212         return false;
213     }
214
215
216     /**
217      * Unsupported; return the default.
218      *
219      * @see Terminal#getTerminalWidth
220      */

221     public int getTerminalWidth ()
222     {
223         return 80;
224     }
225
226
227     /**
228      * Unsupported; return the default.
229      *
230      * @see Terminal#getTerminalHeight
231      */

232     public int getTerminalHeight ()
233     {
234         return 24;
235     }
236 }
237
238
Popular Tags