-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use WriteConsoleW to write to Windows console
Code pages in the Windows console are a mess: The default code page on most Windows systems doesn't support Unicode characters, and even changing the code page manually to UTF-8 results in broken output on some systems (e.g. for Chinese characters, see #164). JLine avoids this problem for the input mechanism by using the Windows API to read Unicode input. Consequently, input was usually working correctly, but the input wasn't displayed correctly in the console. Fortunately, a similar way can be applied for console output. The Windows API provides WriteConsoleW as a way to write unicode text to the console window, bypassing all problems with the current ode page. Unicode characters are given directly to the API instead of being encoded and written to standard output. Note: Unicode works only when using Terminal.writer() to write characters. For compatibility reasons, Terminal.output() decodes written bytes using the current code page and then redirects them to the Writer.
- Loading branch information
1 parent
3fc333b
commit 96c5e0f
Showing
11 changed files
with
240 additions
and
105 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
terminal-jansi/src/main/java/org/jline/terminal/impl/jansi/win/JansiWinConsoleWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) 2002-2017, the original author or authors. | ||
* | ||
* This software is distributable under the BSD license. See the terms of the | ||
* BSD license in the documentation provided with this software. | ||
* | ||
* http://www.opensource.org/licenses/bsd-license.php | ||
*/ | ||
package org.jline.terminal.impl.jansi.win; | ||
|
||
import org.fusesource.jansi.internal.WindowsSupport; | ||
|
||
import java.io.IOException; | ||
import java.io.Writer; | ||
|
||
import static org.fusesource.jansi.internal.Kernel32.GetStdHandle; | ||
import static org.fusesource.jansi.internal.Kernel32.STD_OUTPUT_HANDLE; | ||
import static org.fusesource.jansi.internal.Kernel32.WriteConsoleW; | ||
|
||
class JansiWinConsoleWriter extends Writer { | ||
|
||
private static final long console = GetStdHandle(STD_OUTPUT_HANDLE); | ||
|
||
@Override | ||
public void write(char[] cbuf, int off, int len) throws IOException { | ||
char[] text = cbuf; | ||
if (off != 0) { | ||
text = new char[len]; | ||
System.arraycopy(cbuf, off, text, 0, len); | ||
} | ||
|
||
if (WriteConsoleW(console, text, len, new int[1], 0) == 0) { | ||
throw new IOException("Failed to write to console: " + WindowsSupport.getLastErrorMessage()); | ||
} | ||
} | ||
|
||
@Override | ||
public void flush() throws IOException { | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
terminal-jna/src/main/java/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (c) 2002-2017, the original author or authors. | ||
* | ||
* This software is distributable under the BSD license. See the terms of the | ||
* BSD license in the documentation provided with this software. | ||
* | ||
* http://www.opensource.org/licenses/bsd-license.php | ||
*/ | ||
package org.jline.terminal.impl.jna.win; | ||
|
||
import com.sun.jna.LastErrorException; | ||
import com.sun.jna.Pointer; | ||
import com.sun.jna.ptr.IntByReference; | ||
|
||
import java.io.IOException; | ||
import java.io.Writer; | ||
|
||
class JnaWinConsoleWriter extends Writer { | ||
|
||
private final Pointer consoleHandle; | ||
|
||
JnaWinConsoleWriter(Pointer consoleHandle) { | ||
this.consoleHandle = consoleHandle; | ||
} | ||
|
||
@Override | ||
public synchronized void write(char[] cbuf, int off, int len) throws IOException { | ||
char[] text = cbuf; | ||
if (off != 0) { | ||
text = new char[len]; | ||
System.arraycopy(cbuf, off, text, 0, len); | ||
} | ||
|
||
try { | ||
Kernel32.INSTANCE.WriteConsoleW(this.consoleHandle, text, len, new IntByReference(), null); | ||
} catch (LastErrorException e) { | ||
throw new IOException("Failed to write to console", e); | ||
} | ||
} | ||
|
||
@Override | ||
public void flush() { | ||
} | ||
|
||
@Override | ||
public void close() { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.