fd03487a61d7f092950d31fb7d7ba4dbbc0ce6fa
2 * Jexer - Java Text User Interface
4 * License: LGPLv3 or later
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
10 * Copyright (C) 2015 Kevin Lamonte
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
33 import java
.awt
.event
.KeyListener
;
34 import java
.awt
.event
.KeyEvent
;
35 import java
.awt
.event
.MouseListener
;
36 import java
.awt
.event
.WindowListener
;
37 import java
.util
.List
;
38 import java
.util
.LinkedList
;
40 import jexer
.TKeypress
;
41 import jexer
.bits
.Color
;
42 import jexer
.event
.TInputEvent
;
43 import jexer
.event
.TKeypressEvent
;
44 import jexer
.event
.TMouseEvent
;
45 import jexer
.event
.TResizeEvent
;
46 import jexer
.session
.SessionInfo
;
47 import jexer
.session
.TSessionInfo
;
48 import static jexer
.TKeypress
.*;
51 * This class reads keystrokes and mouse events from an AWT Frame.
53 public final class AWTTerminal
implements KeyListener
{
58 private AWTScreen screen
;
61 * The session information.
63 private SessionInfo sessionInfo
;
66 * Getter for sessionInfo.
68 * @return the SessionInfo
70 public SessionInfo
getSessionInfo() {
75 * The event queue, filled up by a thread reading on input.
77 private List
<TInputEvent
> eventQueue
;
80 * If true, we want the reader thread to exit gracefully.
82 private boolean stopReaderThread
;
87 private Thread readerThread
;
90 * true if mouse1 was down. Used to report mouse1 on the release event.
92 private boolean mouse1
;
95 * true if mouse2 was down. Used to report mouse2 on the release event.
97 private boolean mouse2
;
100 * true if mouse3 was down. Used to report mouse3 on the release event.
102 private boolean mouse3
;
105 * Check if there are events in the queue.
107 * @return if true, getEvents() has something to return to the backend
109 public boolean hasEvents() {
110 synchronized (eventQueue
) {
111 return (eventQueue
.size() > 0);
116 * Constructor sets up state for getEvent().
118 * @param screen the top-level AWT frame
120 public AWTTerminal(final AWTScreen screen
) {
121 this.screen
= screen
;
125 stopReaderThread
= false;
126 sessionInfo
= new TSessionInfo();
127 eventQueue
= new LinkedList
<TInputEvent
>();
129 screen
.frame
.addKeyListener(this);
133 * Restore terminal to normal state.
135 public void shutdown() {
136 // System.err.println("=== shutdown() ==="); System.err.flush();
137 screen
.frame
.dispose();
141 * Return any events in the IO queue.
143 * @param queue list to append new events to
145 public void getEvents(final List
<TInputEvent
> queue
) {
146 synchronized (eventQueue
) {
147 if (eventQueue
.size() > 0) {
148 synchronized (queue
) {
149 queue
.addAll(eventQueue
);
157 * Return any events in the IO queue due to timeout.
159 * @param queue list to append new events to
161 public void getIdleEvents(final List
<TInputEvent
> queue
) {
163 // Insert any polling action here...
165 // Return any events that showed up
166 synchronized (eventQueue
) {
167 if (eventQueue
.size() > 0) {
168 synchronized (queue
) {
169 queue
.addAll(eventQueue
);
177 * Pass AWT keystrokes into the event queue.
179 * @param key keystroke received
182 public void keyReleased(final KeyEvent key
) {
183 // Ignore release events
187 * Pass AWT keystrokes into the event queue.
189 * @param key keystroke received
192 public void keyTyped(final KeyEvent key
) {
193 // Ignore typed events
197 * Pass AWT keystrokes into the event queue.
199 * @param key keystroke received
202 public void keyPressed(final KeyEvent key
) {
204 boolean shift
= false;
205 boolean ctrl
= false;
207 boolean isKey
= false;
209 if (key
.isActionKey()) {
212 ch
= key
.getKeyChar();
214 alt
= key
.isAltDown();
215 ctrl
= key
.isControlDown();
216 shift
= key
.isShiftDown();
219 System.err.printf("AWT Key: %s\n", key);
220 System.err.printf(" isKey: %s\n", isKey);
221 System.err.printf(" alt: %s\n", alt);
222 System.err.printf(" ctrl: %s\n", ctrl);
223 System.err.printf(" shift: %s\n", shift);
224 System.err.printf(" ch: %s\n", ch);
227 // Special case: not return the bare modifier presses
228 switch (key
.getKeyCode()) {
229 case KeyEvent
.VK_ALT
:
231 case KeyEvent
.VK_ALT_GRAPH
:
233 case KeyEvent
.VK_CONTROL
:
235 case KeyEvent
.VK_SHIFT
:
237 case KeyEvent
.VK_META
:
243 TKeypress keypress
= null;
245 switch (key
.getKeyCode()) {
247 keypress
= new TKeypress(true, TKeypress
.F1
, ' ',
251 keypress
= new TKeypress(true, TKeypress
.F2
, ' ',
255 keypress
= new TKeypress(true, TKeypress
.F3
, ' ',
259 keypress
= new TKeypress(true, TKeypress
.F4
, ' ',
263 keypress
= new TKeypress(true, TKeypress
.F5
, ' ',
267 keypress
= new TKeypress(true, TKeypress
.F6
, ' ',
271 keypress
= new TKeypress(true, TKeypress
.F7
, ' ',
275 keypress
= new TKeypress(true, TKeypress
.F8
, ' ',
279 keypress
= new TKeypress(true, TKeypress
.F9
, ' ',
282 case KeyEvent
.VK_F10
:
283 keypress
= new TKeypress(true, TKeypress
.F10
, ' ',
286 case KeyEvent
.VK_F11
:
287 keypress
= new TKeypress(true, TKeypress
.F11
, ' ',
290 case KeyEvent
.VK_F12
:
291 keypress
= new TKeypress(true, TKeypress
.F12
, ' ',
294 case KeyEvent
.VK_HOME
:
295 keypress
= new TKeypress(true, TKeypress
.HOME
, ' ',
298 case KeyEvent
.VK_END
:
299 keypress
= new TKeypress(true, TKeypress
.END
, ' ',
302 case KeyEvent
.VK_PAGE_UP
:
303 keypress
= new TKeypress(true, TKeypress
.PGUP
, ' ',
306 case KeyEvent
.VK_PAGE_DOWN
:
307 keypress
= new TKeypress(true, TKeypress
.PGDN
, ' ',
310 case KeyEvent
.VK_INSERT
:
311 keypress
= new TKeypress(true, TKeypress
.INS
, ' ',
314 case KeyEvent
.VK_DELETE
:
315 keypress
= new TKeypress(true, TKeypress
.F1
, ' ',
318 case KeyEvent
.VK_RIGHT
:
319 keypress
= new TKeypress(true, TKeypress
.RIGHT
, ' ',
322 case KeyEvent
.VK_LEFT
:
323 keypress
= new TKeypress(true, TKeypress
.LEFT
, ' ',
327 keypress
= new TKeypress(true, TKeypress
.UP
, ' ',
330 case KeyEvent
.VK_DOWN
:
331 keypress
= new TKeypress(true, TKeypress
.DOWN
, ' ',
334 case KeyEvent
.VK_TAB
:
335 // Special case: distinguish TAB vs BTAB
337 keypress
= kbShiftTab
;
342 case KeyEvent
.VK_ENTER
:
343 keypress
= new TKeypress(true, TKeypress
.ENTER
, ' ',
346 case KeyEvent
.VK_ESCAPE
:
347 keypress
= new TKeypress(true, TKeypress
.ESC
, ' ',
350 case KeyEvent
.VK_BACK_SPACE
:
351 // Special case: return it as kbBackspace (Ctrl-H)
352 keypress
= new TKeypress(false, 0, 'H', false, true, false);
355 // Unsupported, ignore
360 if (keypress
== null) {
363 keypress
= kbBackspace
;
372 if (!alt
&& ctrl
&& !shift
) {
373 ch
= key
.getKeyText(key
.getKeyCode()).charAt(0);
375 // Not a special key, put it together
376 keypress
= new TKeypress(false, 0, ch
, alt
, ctrl
, shift
);
380 // Save it and we are done.
381 synchronized (eventQueue
) {
382 eventQueue
.add(new TKeypressEvent(keypress
));