/**
* Last character printed.
*/
- private char repCh;
+ private int repCh;
/**
* VT100-style line wrapping: a character is placed in column 80 (or
char [] readBufferUTF8 = null;
byte [] readBuffer = null;
if (utf8) {
- readBufferUTF8 = new char[128];
+ readBufferUTF8 = new char[2048];
} else {
- readBuffer = new byte[128];
+ readBuffer = new byte[2048];
}
while (!done && !stopReaderThread) {
}
if (n == 0) {
try {
- Thread.sleep(2);
+ Thread.sleep(10);
} catch (InterruptedException e) {
// SQUASH
}
} else {
// Don't step on UI events
synchronized (this) {
- for (int i = 0; i < rc; i++) {
- int ch = 0;
- if (utf8) {
- ch = readBufferUTF8[i];
- } else {
- ch = readBuffer[i];
+ if (utf8) {
+ for (int i = 0; i < rc;) {
+ int ch = Character.codePointAt(readBufferUTF8,
+ i);
+ i += Character.charCount(ch);
+ consume(ch);
+ }
+ } else {
+ for (int i = 0; i < rc; i++) {
+ consume(readBuffer[i]);
}
-
- consume((char) ch);
}
}
// Permit my enclosing UI to know that I updated.
*
* @param ch character to display
*/
- private void printCharacter(final char ch) {
+ private void printCharacter(final int ch) {
int rightMargin = this.rightMargin;
if (StringUtils.width(ch) == 2) {
* the remote side.
*/
if (keypress.getChar() < 0x20) {
- handleControlChar(keypress.getChar());
+ handleControlChar((char) keypress.getChar());
} else {
// Local echo for everything else
printCharacter(keypress.getChar());
// Handle control characters
if ((keypress.isCtrl()) && (!keypress.isFnKey())) {
StringBuilder sb = new StringBuilder();
- char ch = keypress.getChar();
+ int ch = keypress.getChar();
ch -= 0x40;
- sb.append(ch);
+ sb.append(Character.toChars(ch));
return sb.toString();
}
// Handle alt characters
if ((keypress.isAlt()) && (!keypress.isFnKey())) {
StringBuilder sb = new StringBuilder("\033");
- char ch = keypress.getChar();
- sb.append(ch);
+ int ch = keypress.getChar();
+ sb.append(Character.toChars(ch));
return sb.toString();
}
// Non-alt, non-ctrl characters
if (!keypress.isFnKey()) {
StringBuilder sb = new StringBuilder();
- sb.append(keypress.getChar());
+ sb.append(Character.toChars(keypress.getChar()));
return sb.toString();
}
return "";
* @param charsetGr character set defined for GR
* @return character to display on the screen
*/
- private char mapCharacterCharset(final char ch,
+ private char mapCharacterCharset(final int ch,
final CharacterSet charsetGl,
final CharacterSet charsetGr) {
* @param ch either 8-bit or Unicode character from the remote side
* @return character to display on the screen
*/
- private char mapCharacter(final char ch) {
+ private int mapCharacter(final int ch) {
if (ch >= 0x100) {
// Unicode character, just return it
return ch;
* DECALN - Screen alignment display.
*/
private void decaln() {
- Cell newCell = new Cell();
- newCell.setChar('E');
+ Cell newCell = new Cell('E');
for (DisplayLine line: display) {
for (int i = 0; i < line.length(); i++) {
line.replace(i, newCell);
int i = getCsiParam(0, 0);
if (!xtermPrivateModeFlag) {
- if (i == 14) {
- // Report xterm window in pixels as CSI 4 ; height ; width t
+ switch (i) {
+ case 14:
+ // Report xterm text area size in pixels as CSI 4 ; height ;
+ // width t
writeRemote(String.format("\033[4;%d;%dt", textHeight * height,
textWidth * width));
+ break;
+ case 16:
+ // Report character size in pixels as CSI 6 ; height ; width
+ // t
+ writeRemote(String.format("\033[6;%d;%dt", textHeight,
+ textWidth));
+ break;
+ case 18:
+ // Report the text are size in characters as CSI 8 ; height ;
+ // width t
+ writeRemote(String.format("\033[8;%d;%dt", height, width));
+ break;
+ default:
+ break;
}
}
}
*
* @param ch character from the remote side
*/
- private void consume(char ch) {
+ private void consume(int ch) {
// DEBUG
// System.err.printf("%c STATE = %s\n", ch, scanState);
// Special case for VT10x: 7-bit characters only
if ((type == DeviceType.VT100) || (type == DeviceType.VT102)) {
- ch = (char)(ch & 0x7F);
+ ch = (ch & 0x7F);
}
// Special "anywhere" states
// 00-17, 19, 1C-1F --> execute
// 80-8F, 91-9A, 9C --> execute
if ((ch <= 0x1F) || ((ch >= 0x80) && (ch <= 0x9F))) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
}
// 20-7F --> print
case ESCAPE:
// 00-17, 19, 1C-1F --> execute
if (ch <= 0x1F) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
return;
}
// 20-2F --> collect, then switch to ESCAPE_INTERMEDIATE
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.ESCAPE_INTERMEDIATE;
return;
}
case ESCAPE_INTERMEDIATE:
// 00-17, 19, 1C-1F --> execute
if (ch <= 0x1F) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
}
// 20-2F --> collect
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
}
// 30-7E --> dispatch, then switch to GROUND
case CSI_ENTRY:
// 00-17, 19, 1C-1F --> execute
if (ch <= 0x1F) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
}
// 20-2F --> collect, then switch to CSI_INTERMEDIATE
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.CSI_INTERMEDIATE;
}
// 3C-3F --> collect, then switch to CSI_PARAM
if ((ch >= 0x3C) && (ch <= 0x3F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.CSI_PARAM;
}
case CSI_PARAM:
// 00-17, 19, 1C-1F --> execute
if (ch <= 0x1F) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
}
// 20-2F --> collect, then switch to CSI_INTERMEDIATE
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.CSI_INTERMEDIATE;
}
case CSI_INTERMEDIATE:
// 00-17, 19, 1C-1F --> execute
if (ch <= 0x1F) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
}
// 20-2F --> collect
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
}
// 0x30-3F goes to CSI_IGNORE
case CSI_IGNORE:
// 00-17, 19, 1C-1F --> execute
if (ch <= 0x1F) {
- handleControlChar(ch);
+ handleControlChar((char) ch);
}
// 20-2F --> collect
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
}
// 40-7E --> ignore, then switch to GROUND
// 0x1B 0x5C goes to GROUND
if (ch == 0x1B) {
- collect(ch);
+ collect((char) ch);
}
if (ch == 0x5C) {
if ((collectBuffer.length() > 0)
// 20-2F --> collect, then switch to DCS_INTERMEDIATE
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.DCS_INTERMEDIATE;
}
// 3C-3F --> collect, then switch to DCS_PARAM
if ((ch >= 0x3C) && (ch <= 0x3F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.DCS_PARAM;
}
// 0x1B 0x5C goes to GROUND
if (ch == 0x1B) {
- collect(ch);
+ collect((char) ch);
}
if (ch == 0x5C) {
if ((collectBuffer.length() > 0)
// 0x1B 0x5C goes to GROUND
if (ch == 0x1B) {
- collect(ch);
+ collect((char) ch);
}
if (ch == 0x5C) {
if ((collectBuffer.length() > 0)
// 20-2F --> collect, then switch to DCS_INTERMEDIATE
if ((ch >= 0x20) && (ch <= 0x2F)) {
- collect(ch);
+ collect((char) ch);
scanState = ScanState.DCS_INTERMEDIATE;
}
// 0x1B 0x5C goes to GROUND
if (ch == 0x1B) {
- collect(ch);
+ collect((char) ch);
}
if (ch == 0x5C) {
if ((collectBuffer.length() > 0)
// 0x1B 0x5C goes to GROUND
if (ch == 0x1B) {
- collect(ch);
+ collect((char) ch);
}
if (ch == 0x5C) {
if ((collectBuffer.length() > 0)
// 00-17, 19, 1C-1F, 20-7E --> put
if (ch <= 0x17) {
- sixelParseBuffer.append(ch);
+ sixelParseBuffer.append((char) ch);
return;
}
if (ch == 0x19) {
- sixelParseBuffer.append(ch);
+ sixelParseBuffer.append((char) ch);
return;
}
if ((ch >= 0x1C) && (ch <= 0x1F)) {
- sixelParseBuffer.append(ch);
+ sixelParseBuffer.append((char) ch);
return;
}
if ((ch >= 0x20) && (ch <= 0x7E)) {
- sixelParseBuffer.append(ch);
+ sixelParseBuffer.append((char) ch);
return;
}
// Special case for Jexer: PM can pass one control character
if (ch == 0x1B) {
- pmPut(ch);
+ pmPut((char) ch);
}
if ((ch >= 0x20) && (ch <= 0x7F)) {
- pmPut(ch);
+ pmPut((char) ch);
}
// 0x9C goes to GROUND
case OSC_STRING:
// Special case for Xterm: OSC can pass control characters
if ((ch == 0x9C) || (ch == 0x07) || (ch == 0x1B)) {
- oscPut(ch);
+ oscPut((char) ch);
}
// 00-17, 19, 1C-1F --> ignore
// 20-7F --> osc_put
if ((ch >= 0x20) && (ch <= 0x7F)) {
- oscPut(ch);
+ oscPut((char) ch);
}
// 0x9C goes to GROUND
case VT52_DIRECT_CURSOR_ADDRESS:
// This is a special case for the VT52 sequence "ESC Y l c"
if (collectBuffer.length() == 0) {
- collect(ch);
+ collect((char) ch);
} else if (collectBuffer.length() == 1) {
// We've got the two characters, one in the buffer and the
// other in ch.
* @param ch the character to draw
*/
private void drawHalves(final int leftX, final int leftY,
- final int rightX, final int rightY, final char ch) {
+ final int rightX, final int rightY, final int ch) {
// System.err.println("drawHalves(): " + Integer.toHexString(ch));
lastTextHeight = textHeight;
}
- Cell cell = new Cell(ch);
- cell.setAttr(currentState.attr);
+ Cell cell = new Cell(ch, currentState.attr);
BufferedImage image = glyphMaker.getImage(cell, textWidth * 2,
textHeight);
BufferedImage leftImage = image.getSubimage(0, 0, textWidth,
BufferedImage rightImage = image.getSubimage(textWidth, 0, textWidth,
textHeight);
- Cell left = new Cell();
- left.setTo(cell);
+ Cell left = new Cell(cell);
left.setImage(leftImage);
left.setWidth(Cell.Width.LEFT);
display.get(leftY).replace(leftX, left);
- Cell right = new Cell();
- right.setTo(cell);
+ Cell right = new Cell(cell);
right.setImage(rightImage);
right.setWidth(Cell.Width.RIGHT);
display.get(rightY).replace(rightX, right);