mirror of
https://gitlab.com/AutumnMeowMeow/jexer
synced 2024-09-19 11:50:19 -06:00
AWT keyboard barely working
This commit is contained in:
parent
1ac2ccb131
commit
84614868e6
7 changed files with 528 additions and 64 deletions
10
build.xml
10
build.xml
|
@ -30,10 +30,11 @@
|
|||
|
||||
<project name="jexer" basedir="." default="run">
|
||||
|
||||
<property name="src.dir" value="src"/>
|
||||
<property name="build.dir" value="build"/>
|
||||
<property name="classes.dir" value="${build.dir}/classes"/>
|
||||
<property name="jar.dir" value="${build.dir}/jar"/>
|
||||
<property name="src.dir" value="src"/>
|
||||
<property name="resources.dir" value="resources"/>
|
||||
<property name="build.dir" value="build"/>
|
||||
<property name="classes.dir" value="${build.dir}/classes"/>
|
||||
<property name="jar.dir" value="${build.dir}/jar"/>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}"/>
|
||||
|
@ -49,6 +50,7 @@
|
|||
<mkdir dir="${jar.dir}"/>
|
||||
<jar destfile="${jar.dir}/${ant.project.name}.jar"
|
||||
basedir="${classes.dir}">
|
||||
<fileset dir="${resources.dir}"/>
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="jexer.demos.Demo1"/>
|
||||
</manifest>
|
||||
|
|
97
resources/terminus-ttf-4.39/COPYING
Normal file
97
resources/terminus-ttf-4.39/COPYING
Normal file
|
@ -0,0 +1,97 @@
|
|||
Copyright (c) 2010 Dimitar Toshkov Zhekov,
|
||||
with Reserved Font Name "Terminus Font".
|
||||
|
||||
Copyright (c) 2011 Tilman Blumenbach,
|
||||
with Reserved Font Name "Terminus (TTF)".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
resources/terminus-ttf-4.39/TerminusTTF-4.39.ttf
Normal file
BIN
resources/terminus-ttf-4.39/TerminusTTF-4.39.ttf
Normal file
Binary file not shown.
BIN
resources/terminus-ttf-4.39/TerminusTTF-Bold-4.39.ttf
Normal file
BIN
resources/terminus-ttf-4.39/TerminusTTF-Bold-4.39.ttf
Normal file
Binary file not shown.
BIN
resources/terminus-ttf-4.39/TerminusTTF-Italic-4.39.ttf
Normal file
BIN
resources/terminus-ttf-4.39/TerminusTTF-Italic-4.39.ttf
Normal file
Binary file not shown.
|
@ -39,18 +39,72 @@ import java.awt.Font;
|
|||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* This Screen implementation draws to a Java AWT Frame.
|
||||
*/
|
||||
public final class AWTScreen extends Screen {
|
||||
|
||||
private static Color MYBLACK;
|
||||
private static Color MYRED;
|
||||
private static Color MYGREEN;
|
||||
private static Color MYYELLOW;
|
||||
private static Color MYBLUE;
|
||||
private static Color MYMAGENTA;
|
||||
private static Color MYCYAN;
|
||||
private static Color MYWHITE;
|
||||
|
||||
private static Color MYBOLD_BLACK;
|
||||
private static Color MYBOLD_RED;
|
||||
private static Color MYBOLD_GREEN;
|
||||
private static Color MYBOLD_YELLOW;
|
||||
private static Color MYBOLD_BLUE;
|
||||
private static Color MYBOLD_MAGENTA;
|
||||
private static Color MYBOLD_CYAN;
|
||||
private static Color MYBOLD_WHITE;
|
||||
|
||||
private static boolean dosColors = false;
|
||||
|
||||
/**
|
||||
* Setup AWT colors to match DOS color palette.
|
||||
*/
|
||||
private static void setDOSColors() {
|
||||
if (dosColors) {
|
||||
return;
|
||||
}
|
||||
MYBLACK = new Color(0x00, 0x00, 0x00);
|
||||
MYRED = new Color(0xa8, 0x00, 0x00);
|
||||
MYGREEN = new Color(0x00, 0xa8, 0x00);
|
||||
MYYELLOW = new Color(0xa8, 0x54, 0x00);
|
||||
MYBLUE = new Color(0x00, 0x00, 0xa8);
|
||||
MYMAGENTA = new Color(0xa8, 0x00, 0xa8);
|
||||
MYCYAN = new Color(0x00, 0xa8, 0xa8);
|
||||
MYWHITE = new Color(0xa8, 0xa8, 0xa8);
|
||||
MYBOLD_BLACK = new Color(0x54, 0x54, 0x54);
|
||||
MYBOLD_RED = new Color(0xfc, 0x54, 0x54);
|
||||
MYBOLD_GREEN = new Color(0x54, 0xfc, 0x54);
|
||||
MYBOLD_YELLOW = new Color(0xfc, 0xfc, 0x54);
|
||||
MYBOLD_BLUE = new Color(0x54, 0x54, 0xfc);
|
||||
MYBOLD_MAGENTA = new Color(0xfc, 0x54, 0xfc);
|
||||
MYBOLD_CYAN = new Color(0x54, 0xfc, 0xfc);
|
||||
MYBOLD_WHITE = new Color(0xfc, 0xfc, 0xfc);
|
||||
|
||||
dosColors = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* AWTFrame is our top-level hook into the AWT system.
|
||||
*/
|
||||
class AWTFrame extends Frame {
|
||||
|
||||
/**
|
||||
* The terminus font resource filename.
|
||||
*/
|
||||
private static final String FONTFILE = "terminus-ttf-4.39/TerminusTTF-Bold-4.39.ttf";
|
||||
|
||||
/**
|
||||
* The TUI Screen data.
|
||||
*/
|
||||
|
@ -66,41 +120,165 @@ public final class AWTScreen extends Screen {
|
|||
*/
|
||||
private int textHeight = 1;
|
||||
|
||||
/**
|
||||
* Descent of a character cell.
|
||||
*/
|
||||
private int maxDescent = 0;
|
||||
|
||||
/**
|
||||
* Top pixel value.
|
||||
*/
|
||||
private int top = 30;
|
||||
|
||||
|
||||
/**
|
||||
* Left pixel value.
|
||||
*/
|
||||
private int left = 30;
|
||||
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
private Color attrToForegroundColor(final CellAttributes attr) {
|
||||
/*
|
||||
* TODO:
|
||||
* reverse
|
||||
* blink
|
||||
* underline
|
||||
*/
|
||||
if (attr.getBold()) {
|
||||
if (attr.getForeColor().equals(jexer.bits.Color.BLACK)) {
|
||||
return MYBOLD_BLACK;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.RED)) {
|
||||
return MYBOLD_RED;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.BLUE)) {
|
||||
return MYBOLD_BLUE;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.GREEN)) {
|
||||
return MYBOLD_GREEN;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.YELLOW)) {
|
||||
return MYBOLD_YELLOW;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.CYAN)) {
|
||||
return MYBOLD_CYAN;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.MAGENTA)) {
|
||||
return MYBOLD_MAGENTA;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.WHITE)) {
|
||||
return MYBOLD_WHITE;
|
||||
}
|
||||
} else {
|
||||
if (attr.getForeColor().equals(jexer.bits.Color.BLACK)) {
|
||||
return MYBLACK;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.RED)) {
|
||||
return MYRED;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.BLUE)) {
|
||||
return MYBLUE;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.GREEN)) {
|
||||
return MYGREEN;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.YELLOW)) {
|
||||
return MYYELLOW;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.CYAN)) {
|
||||
return MYCYAN;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.MAGENTA)) {
|
||||
return MYMAGENTA;
|
||||
} else if (attr.getForeColor().equals(jexer.bits.Color.WHITE)) {
|
||||
return MYWHITE;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid color: " + attr.getForeColor().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
private Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
/*
|
||||
* TODO:
|
||||
* reverse
|
||||
* blink
|
||||
* underline
|
||||
*/
|
||||
if (attr.getBackColor().equals(jexer.bits.Color.BLACK)) {
|
||||
return MYBLACK;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.RED)) {
|
||||
return MYRED;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.BLUE)) {
|
||||
return MYBLUE;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.GREEN)) {
|
||||
return MYGREEN;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.YELLOW)) {
|
||||
return MYYELLOW;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.CYAN)) {
|
||||
return MYCYAN;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.MAGENTA)) {
|
||||
return MYMAGENTA;
|
||||
} else if (attr.getBackColor().equals(jexer.bits.Color.WHITE)) {
|
||||
return MYWHITE;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid color: " + attr.getBackColor().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @param screen the Screen that Backend talks to
|
||||
*/
|
||||
public AWTFrame() {
|
||||
public AWTFrame(final AWTScreen screen) {
|
||||
this.screen = screen;
|
||||
setDOSColors();
|
||||
|
||||
setTitle("Jexer Application");
|
||||
setBackground(java.awt.Color.black);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
|
||||
setFont(new Font("Liberation Mono", Font.BOLD, 16));
|
||||
// setFont(new Font("Liberation Mono", Font.BOLD, 16));
|
||||
// setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16));
|
||||
setSize(100, 100);
|
||||
|
||||
try {
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
InputStream in = loader.getResourceAsStream(FONTFILE);
|
||||
Font terminusRoot = Font.createFont(Font.TRUETYPE_FONT, in);
|
||||
Font terminus = terminusRoot.deriveFont(Font.PLAIN, 22);
|
||||
setFont(terminus);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// setFont(new Font("Liberation Mono", Font.PLAIN, 24));
|
||||
setFont(new Font(Font.MONOSPACED, Font.PLAIN, 24));
|
||||
}
|
||||
setVisible(true);
|
||||
resizeToScreen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize to font dimensions.
|
||||
*/
|
||||
public void resizeToScreen() {
|
||||
Graphics gr = getGraphics();
|
||||
FontMetrics fm = gr.getFontMetrics();
|
||||
textWidth = fm.charWidth('m');
|
||||
textHeight = fm.getHeight();
|
||||
setSize((textWidth + 1) * screen.width + (2 * left),
|
||||
(textHeight + 1) * screen.height + (2 * top));
|
||||
Graphics gr = getGraphics();
|
||||
FontMetrics fm = gr.getFontMetrics();
|
||||
maxDescent = fm.getMaxDescent();
|
||||
Rectangle2D bounds = fm.getMaxCharBounds(gr);
|
||||
int leading = fm.getLeading();
|
||||
textWidth = (int)Math.round(bounds.getWidth());
|
||||
textHeight = (int)Math.round(bounds.getHeight()) - maxDescent;
|
||||
// This also produces the same number, but works better for ugly
|
||||
// monospace.
|
||||
textHeight = fm.getMaxAscent() + maxDescent - leading;
|
||||
|
||||
System.err.printf("W: %d H: %d\n", textWidth, textHeight);
|
||||
// Figure out the thickness of borders and use that to set the
|
||||
// final size.
|
||||
Insets insets = getInsets();
|
||||
left = insets.left;
|
||||
top = insets.top;
|
||||
|
||||
setSize(textWidth * screen.width + insets.left + insets.right,
|
||||
textHeight * screen.height + insets.top + insets.bottom);
|
||||
|
||||
/*
|
||||
System.err.printf("W: %d H: %d MD: %d L: %d\n", textWidth,
|
||||
textHeight, maxDescent, leading);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,60 +287,27 @@ public final class AWTScreen extends Screen {
|
|||
* @param gr the AWT Graphics context
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics gr) {
|
||||
public void paint(final Graphics gr) {
|
||||
|
||||
for (int y = 0; y < screen.height; y++) {
|
||||
for (int x = 0; x < screen.width; x++) {
|
||||
Cell lCell = screen.logical[x][y];
|
||||
Cell pCell = screen.physical[x][y];
|
||||
|
||||
int xPixel = x * (textWidth + 1) + left;
|
||||
int yPixel = y * (textHeight + 1) + top - y;
|
||||
int xPixel = x * textWidth + left;
|
||||
int yPixel = y * textHeight + top;
|
||||
|
||||
if (!lCell.equals(pCell)) {
|
||||
|
||||
// Draw the background rectangle, then the foreground
|
||||
// character.
|
||||
if (lCell.getBackColor().equals(jexer.bits.Color.BLACK)) {
|
||||
gr.setColor(Color.black);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.RED)) {
|
||||
gr.setColor(Color.red);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.BLUE)) {
|
||||
gr.setColor(Color.blue);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.GREEN)) {
|
||||
gr.setColor(Color.green);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.YELLOW)) {
|
||||
gr.setColor(Color.yellow);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.CYAN)) {
|
||||
gr.setColor(Color.cyan);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.MAGENTA)) {
|
||||
gr.setColor(Color.magenta);
|
||||
} else if (lCell.getBackColor().equals(jexer.bits.Color.WHITE)) {
|
||||
gr.setColor(Color.white);
|
||||
}
|
||||
gr.fillRect(xPixel, yPixel, textWidth + 1,
|
||||
textHeight + 2);
|
||||
|
||||
if (lCell.getForeColor().equals(jexer.bits.Color.BLACK)) {
|
||||
gr.setColor(Color.black);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.RED)) {
|
||||
gr.setColor(Color.red);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.BLUE)) {
|
||||
gr.setColor(Color.blue);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.GREEN)) {
|
||||
gr.setColor(Color.green);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.YELLOW)) {
|
||||
gr.setColor(Color.yellow);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.CYAN)) {
|
||||
gr.setColor(Color.cyan);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.MAGENTA)) {
|
||||
gr.setColor(Color.magenta);
|
||||
} else if (lCell.getForeColor().equals(jexer.bits.Color.WHITE)) {
|
||||
gr.setColor(Color.white);
|
||||
}
|
||||
gr.setColor(attrToBackgroundColor(lCell));
|
||||
gr.fillRect(xPixel, yPixel, textWidth, textHeight);
|
||||
gr.setColor(attrToForegroundColor(lCell));
|
||||
char [] chars = new char[1];
|
||||
chars[0] = lCell.getChar();
|
||||
gr.drawChars(chars, 0, 1, xPixel,
|
||||
yPixel + textHeight - 2);
|
||||
yPixel + textHeight - maxDescent);
|
||||
|
||||
// Physical is always updated
|
||||
physical[x][y].setTo(lCell);
|
||||
|
@ -173,17 +318,15 @@ public final class AWTScreen extends Screen {
|
|||
}
|
||||
|
||||
/**
|
||||
* The raw AWT Frame.
|
||||
* The raw AWT Frame. Note package private access.
|
||||
*/
|
||||
private AWTFrame frame;
|
||||
AWTFrame frame;
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*/
|
||||
public AWTScreen() {
|
||||
frame = new AWTFrame();
|
||||
frame.screen = this;
|
||||
frame.resizeToScreen();
|
||||
frame = new AWTFrame(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
*/
|
||||
package jexer.io;
|
||||
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
|
@ -46,7 +50,12 @@ import static jexer.TKeypress.*;
|
|||
/**
|
||||
* This class reads keystrokes and mouse events from an AWT Frame.
|
||||
*/
|
||||
public final class AWTTerminal {
|
||||
public final class AWTTerminal implements KeyListener {
|
||||
|
||||
/**
|
||||
* The backend Screen.
|
||||
*/
|
||||
private AWTScreen screen;
|
||||
|
||||
/**
|
||||
* The session information.
|
||||
|
@ -106,15 +115,18 @@ public final class AWTTerminal {
|
|||
/**
|
||||
* Constructor sets up state for getEvent().
|
||||
*
|
||||
* @param screen the top-level AWT frame
|
||||
* @param screen the top-level AWT frame
|
||||
*/
|
||||
public AWTTerminal(final AWTScreen screen) {
|
||||
this.screen = screen;
|
||||
mouse1 = false;
|
||||
mouse2 = false;
|
||||
mouse3 = false;
|
||||
stopReaderThread = false;
|
||||
sessionInfo = new TSessionInfo();
|
||||
eventQueue = new LinkedList<TInputEvent>();
|
||||
|
||||
screen.frame.addKeyListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,6 +134,7 @@ public final class AWTTerminal {
|
|||
*/
|
||||
public void shutdown() {
|
||||
// System.err.println("=== shutdown() ==="); System.err.flush();
|
||||
screen.frame.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,4 +173,213 @@ public final class AWTTerminal {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass AWT keystrokes into the event queue.
|
||||
*
|
||||
* @param key keystroke received
|
||||
*/
|
||||
@Override
|
||||
public void keyReleased(final KeyEvent key) {
|
||||
// Ignore release events
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass AWT keystrokes into the event queue.
|
||||
*
|
||||
* @param key keystroke received
|
||||
*/
|
||||
@Override
|
||||
public void keyTyped(final KeyEvent key) {
|
||||
// Ignore typed events
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass AWT keystrokes into the event queue.
|
||||
*
|
||||
* @param key keystroke received
|
||||
*/
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent key) {
|
||||
boolean alt = false;
|
||||
boolean shift = false;
|
||||
boolean ctrl = false;
|
||||
char ch = ' ';
|
||||
boolean isKey = false;
|
||||
int fnKey = 0;
|
||||
if (key.isActionKey()) {
|
||||
isKey = true;
|
||||
} else {
|
||||
ch = key.getKeyChar();
|
||||
}
|
||||
alt = key.isAltDown();
|
||||
ctrl = key.isControlDown();
|
||||
shift = key.isShiftDown();
|
||||
|
||||
/*
|
||||
System.err.printf("AWT Key: %s\n", key);
|
||||
System.err.printf(" isKey: %s\n", isKey);
|
||||
System.err.printf(" alt: %s\n", alt);
|
||||
System.err.printf(" ctrl: %s\n", ctrl);
|
||||
System.err.printf(" shift: %s\n", shift);
|
||||
System.err.printf(" ch: %s\n", ch);
|
||||
*/
|
||||
|
||||
// Special case: not return the bare modifier presses
|
||||
switch (key.getKeyCode()) {
|
||||
case KeyEvent.VK_ALT:
|
||||
return;
|
||||
case KeyEvent.VK_ALT_GRAPH:
|
||||
return;
|
||||
case KeyEvent.VK_CONTROL:
|
||||
return;
|
||||
case KeyEvent.VK_SHIFT:
|
||||
return;
|
||||
case KeyEvent.VK_META:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TKeypress keypress = null;
|
||||
if (isKey) {
|
||||
switch (key.getKeyCode()) {
|
||||
case KeyEvent.VK_F1:
|
||||
keypress = new TKeypress(true, TKeypress.F1, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F2:
|
||||
keypress = new TKeypress(true, TKeypress.F2, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F3:
|
||||
keypress = new TKeypress(true, TKeypress.F3, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F4:
|
||||
keypress = new TKeypress(true, TKeypress.F4, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F5:
|
||||
keypress = new TKeypress(true, TKeypress.F5, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F6:
|
||||
keypress = new TKeypress(true, TKeypress.F6, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F7:
|
||||
keypress = new TKeypress(true, TKeypress.F7, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F8:
|
||||
keypress = new TKeypress(true, TKeypress.F8, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F9:
|
||||
keypress = new TKeypress(true, TKeypress.F9, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F10:
|
||||
keypress = new TKeypress(true, TKeypress.F10, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F11:
|
||||
keypress = new TKeypress(true, TKeypress.F11, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_F12:
|
||||
keypress = new TKeypress(true, TKeypress.F12, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_HOME:
|
||||
keypress = new TKeypress(true, TKeypress.HOME, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_END:
|
||||
keypress = new TKeypress(true, TKeypress.END, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_PAGE_UP:
|
||||
keypress = new TKeypress(true, TKeypress.PGUP, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_PAGE_DOWN:
|
||||
keypress = new TKeypress(true, TKeypress.PGDN, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_INSERT:
|
||||
keypress = new TKeypress(true, TKeypress.INS, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_DELETE:
|
||||
keypress = new TKeypress(true, TKeypress.F1, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
keypress = new TKeypress(true, TKeypress.RIGHT, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_LEFT:
|
||||
keypress = new TKeypress(true, TKeypress.LEFT, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_UP:
|
||||
keypress = new TKeypress(true, TKeypress.UP, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_DOWN:
|
||||
keypress = new TKeypress(true, TKeypress.DOWN, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_TAB:
|
||||
// Special case: distinguish TAB vs BTAB
|
||||
if (shift) {
|
||||
keypress = kbShiftTab;
|
||||
} else {
|
||||
keypress = kbTab;
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_ENTER:
|
||||
keypress = new TKeypress(true, TKeypress.ENTER, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
keypress = new TKeypress(true, TKeypress.ESC, ' ',
|
||||
alt, ctrl, shift);
|
||||
break;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
// Special case: return it as kbBackspace (Ctrl-H)
|
||||
keypress = new TKeypress(false, 0, 'H', false, true, false);
|
||||
break;
|
||||
default:
|
||||
// Unsupported, ignore
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keypress == null) {
|
||||
switch (ch) {
|
||||
case 0x08:
|
||||
keypress = kbBackspace;
|
||||
break;
|
||||
case 0x0A:
|
||||
keypress = kbEnter;
|
||||
break;
|
||||
case 0x0D:
|
||||
keypress = kbEnter;
|
||||
break;
|
||||
default:
|
||||
if (!alt && ctrl && !shift) {
|
||||
ch = key.getKeyText(key.getKeyCode()).charAt(0);
|
||||
}
|
||||
// Not a special key, put it together
|
||||
keypress = new TKeypress(false, 0, ch, alt, ctrl, shift);
|
||||
}
|
||||
}
|
||||
|
||||
// Save it and we are done.
|
||||
synchronized (eventQueue) {
|
||||
eventQueue.add(new TKeypressEvent(keypress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue