From 951ec6a0793a74b2f2a518addbda8b7c9ce2b4ad Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 8 Jan 2025 16:45:25 +0100 Subject: [PATCH] Cleanup - moving to jdk.internal.le --- .../share/classes/java/io/Console.java | 4 +- .../jdk/internal/io/JdkConsoleImpl.java | 175 ++++++++++- .../jdk/internal/io/JdkConsoleProvider.java | 2 +- src/java.base/share/classes/module-info.java | 4 +- .../console}/BaseNativeConsoleReader.java | 2 +- .../jdk/internal/console/JdkConsoleImpl.java | 280 ++++++++++++++++++ .../console}/NativeConsoleReader.java | 2 +- .../console}/SimpleConsoleReader.java | 2 +- .../jdk/internal/console}/Attributes.java | 2 +- .../jdk/internal/console}/CLibrary.java | 2 +- .../console}/NativeConsoleReaderImpl.java | 2 +- .../jdk/internal/console}/Kernel32.java | 2 +- .../console}/NativeConsoleReaderImpl.java | 30 +- 13 files changed, 467 insertions(+), 42 deletions(-) rename src/{java.base/share/classes/jdk/internal/io => jdk.internal.le/share/classes/jdk/internal/console}/BaseNativeConsoleReader.java (99%) create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/console/JdkConsoleImpl.java rename src/{java.base/share/classes/jdk/internal/io => jdk.internal.le/share/classes/jdk/internal/console}/NativeConsoleReader.java (97%) rename src/{java.base/share/classes/jdk/internal/io => jdk.internal.le/share/classes/jdk/internal/console}/SimpleConsoleReader.java (99%) rename src/{java.base/share/classes/jdk/internal/io => jdk.internal.le/unix/classes/jdk/internal/console}/Attributes.java (99%) rename src/{java.base/share/classes/jdk/internal/io => jdk.internal.le/unix/classes/jdk/internal/console}/CLibrary.java (99%) rename src/{java.base/unix/classes/jdk/internal/io => jdk.internal.le/unix/classes/jdk/internal/console}/NativeConsoleReaderImpl.java (99%) rename src/{java.base/windows/classes/jdk/internal/io => jdk.internal.le/windows/classes/jdk/internal/console}/Kernel32.java (99%) rename src/{java.base/windows/classes/jdk/internal/io => jdk.internal.le/windows/classes/jdk/internal/console}/NativeConsoleReaderImpl.java (92%) diff --git a/src/java.base/share/classes/java/io/Console.java b/src/java.base/share/classes/java/io/Console.java index 8104a7214ec43..4f919c064b942 100644 --- a/src/java.base/share/classes/java/io/Console.java +++ b/src/java.base/share/classes/java/io/Console.java @@ -669,8 +669,8 @@ private static Console instantiateConsole() { * If no providers are available, or instantiation failed, java.base built-in * Console implementation is used. */ - var consModName = "java.base";//System.getProperty("jdk.console", -// JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME); + var consModName = System.getProperty("jdk.console", + JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME); for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) { if (consModName.equals(jcp.getClass().getModule().getName())) { diff --git a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java index f75014630736c..3c0afd2005cb1 100644 --- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java +++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.io.Reader; import java.io.Writer; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.Formatter; import java.util.Locale; import java.util.Objects; @@ -168,15 +169,14 @@ public char[] readPassword(Locale locale, String format, Object ... args) { ioe.addSuppressed(x); } if (ioe != null) { - //TODO: -// Arrays.fill(passwd, ' '); -// try { -// if (reader instanceof LineReader lr) { -// lr.zeroOut(); -// } -// } catch (IOException _) { -// // ignore -// } + Arrays.fill(passwd, ' '); + try { + if (reader instanceof LineReader lr) { + lr.zeroOut(); + } + } catch (IOException _) { + // ignore + } throw ioe; } } @@ -235,14 +235,42 @@ public Charset charset() { private final Object restoreEchoLock; private final Reader reader; private final Writer out; - private final NativeConsoleReader nativeConsoleReader; private final PrintWriter pw; private final Formatter formatter; + private char[] rcb; private boolean restoreEcho; private boolean shutdownHookInstalled; private char[] readline(boolean zeroOut) throws IOException { - return nativeConsoleReader.readline(reader, out, zeroOut); + int len = reader.read(rcb, 0, rcb.length); + if (len < 0) + return null; //EOL + if (rcb[len-1] == '\r') + len--; //remove CR at end; + else if (rcb[len-1] == '\n') { + len--; //remove LF at end; + if (len > 0 && rcb[len-1] == '\r') + len--; //remove the CR, if there is one + } + char[] b = new char[len]; + if (len > 0) { + System.arraycopy(rcb, 0, b, 0, len); + if (zeroOut) { + Arrays.fill(rcb, 0, len, ' '); + if (reader instanceof LineReader lr) { + lr.zeroOut(); + } + } + } + return b; + } + + private char[] grow() { + assert Thread.holdsLock(readLock); + char[] t = new char[rcb.length * 2]; + System.arraycopy(rcb, 0, t, 0, rcb.length); + rcb = t; + return rcb; } /* @@ -254,6 +282,122 @@ private char[] readline(boolean zeroOut) throws IOException { */ private static native boolean echo(boolean on) throws IOException; + class LineReader extends Reader { + private final Reader in; + private final char[] cb; + private int nChars, nextChar; + boolean leftoverLF; + LineReader(Reader in) { + this.in = in; + cb = new char[1024]; + nextChar = nChars = 0; + leftoverLF = false; + } + public void zeroOut() throws IOException { + if (in instanceof StreamDecoder sd) { + sd.fillZeroToPosition(); + } + } + public void close () {} + public boolean ready() throws IOException { + //in.ready synchronizes on readLock already + return in.ready(); + } + + public int read(char[] cbuf, int offset, int length) + throws IOException + { + int off = offset; + int end = offset + length; + if (offset < 0 || offset > cbuf.length || length < 0 || + end < 0 || end > cbuf.length) { + throw new IndexOutOfBoundsException(); + } + synchronized(readLock) { + boolean eof = false; + char c; + for (;;) { + if (nextChar >= nChars) { //fill + int n; + do { + n = in.read(cb, 0, cb.length); + } while (n == 0); + if (n > 0) { + nChars = n; + nextChar = 0; + if (n < cb.length && + cb[n-1] != '\n' && cb[n-1] != '\r') { + /* + * we're in canonical mode so each "fill" should + * come back with an eol. if there is no lf or nl at + * the end of returned bytes we reached an eof. + */ + eof = true; + } + } else { /*EOF*/ + if (off - offset == 0) + return -1; + return off - offset; + } + } + if (leftoverLF && cbuf == rcb && cb[nextChar] == '\n') { + /* + * if invoked by our readline, skip the leftover, otherwise + * return the LF. + */ + nextChar++; + } + leftoverLF = false; + while (nextChar < nChars) { + c = cbuf[off++] = cb[nextChar]; + cb[nextChar++] = 0; + if (c == '\n') { + return off - offset; + } else if (c == '\r') { + if (off == end) { + /* no space left even the next is LF, so return + * whatever we have if the invoker is not our + * readLine() + */ + if (cbuf == rcb) { + cbuf = grow(); + } else { + leftoverLF = true; + return off - offset; + } + } + if (nextChar == nChars && in.ready()) { + /* + * we have a CR and we reached the end of + * the read in buffer, fill to make sure we + * don't miss a LF, if there is one, it's possible + * that it got cut off during last round reading + * simply because the read in buffer was full. + */ + nChars = in.read(cb, 0, cb.length); + nextChar = 0; + } + if (nextChar < nChars && cb[nextChar] == '\n') { + cbuf[off++] = '\n'; + nextChar++; + } + return off - offset; + } else if (off == end) { + if (cbuf == rcb) { + cbuf = grow(); + end = cbuf.length; + } else { + return off - offset; + } + } + } + if (eof) + return off - offset; + } + } + } + } + public JdkConsoleImpl(Charset charset) { Objects.requireNonNull(charset); this.charset = charset; @@ -269,11 +413,10 @@ public void close() { } }; formatter = new Formatter(out); - reader = /*new LineReader(*/StreamDecoder.forInputStreamReader( + reader = new LineReader(StreamDecoder.forInputStreamReader( new FileInputStream(FileDescriptor.in), readLock, - charset);//); - nativeConsoleReader = NativeConsoleReaderImpl.create(readLock); + charset)); + rcb = new char[1024]; } - } diff --git a/src/java.base/share/classes/jdk/internal/io/JdkConsoleProvider.java b/src/java.base/share/classes/jdk/internal/io/JdkConsoleProvider.java index ae1992012dee9..26e59c84e2318 100644 --- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleProvider.java +++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleProvider.java @@ -33,7 +33,7 @@ public interface JdkConsoleProvider { /** * The module name of the JdkConsole default provider. */ - String DEFAULT_PROVIDER_MODULE_NAME = "java.base"; + String DEFAULT_PROVIDER_MODULE_NAME = "jdk.internal.le"; /** * {@return the Console instance, or {@code null} if not available} diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 2904f66573211..fd5974f152a9b 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -168,6 +168,7 @@ java.management, java.rmi, jdk.charsets, + jdk.internal.le, jdk.jartool, jdk.jlink, jdk.jfr, @@ -306,7 +307,8 @@ jdk.net, jdk.sctp; exports sun.nio.cs to - jdk.charsets; + jdk.charsets, + jdk.internal.le; exports sun.nio.fs to jdk.net; exports sun.reflect.annotation to diff --git a/src/java.base/share/classes/jdk/internal/io/BaseNativeConsoleReader.java b/src/jdk.internal.le/share/classes/jdk/internal/console/BaseNativeConsoleReader.java similarity index 99% rename from src/java.base/share/classes/jdk/internal/io/BaseNativeConsoleReader.java rename to src/jdk.internal.le/share/classes/jdk/internal/console/BaseNativeConsoleReader.java index bbf356ff2f542..ded32e3d99f04 100644 --- a/src/java.base/share/classes/jdk/internal/io/BaseNativeConsoleReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/console/BaseNativeConsoleReader.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.internal.io; +package jdk.internal.console; import java.io.IOException; import java.io.Reader; diff --git a/src/jdk.internal.le/share/classes/jdk/internal/console/JdkConsoleImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/console/JdkConsoleImpl.java new file mode 100644 index 0000000000000..8ff9536c1e8e3 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/console/JdkConsoleImpl.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.console; + +import java.io.IOError; +import java.io.IOException; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Formatter; +import java.util.Locale; +import java.util.Objects; + +import jdk.internal.access.SharedSecrets; +import jdk.internal.io.JdkConsole; +import sun.nio.cs.StreamDecoder; +import sun.nio.cs.StreamEncoder; + +/** + * JdkConsole implementation based on the platform's TTY. + */ +public final class JdkConsoleImpl implements JdkConsole { + @Override + public PrintWriter writer() { + return pw; + } + + @Override + public Reader reader() { + return reader; + } + + @Override + public JdkConsole println(Object obj) { + pw.println(obj); + // automatic flushing covers println + return this; + } + + @Override + public JdkConsole print(Object obj) { + pw.print(obj); + pw.flush(); // automatic flushing does not cover print + return this; + } + + @Override + public String readln(String prompt) { + String line = null; + synchronized (writeLock) { + synchronized(readLock) { + pw.print(prompt); + pw.flush(); // automatic flushing does not cover print + try { + char[] ca = readline(false); + if (ca != null) + line = new String(ca); + } catch (IOException x) { + throw new IOError(x); + } + } + } + return line; + } + + @Override + public String readln() { + String line = null; + synchronized(readLock) { + try { + char[] ca = readline(false); + if (ca != null) + line = new String(ca); + } catch (IOException x) { + throw new IOError(x); + } + } + return line; + } + + @Override + public JdkConsole format(Locale locale, String format, Object ... args) { + formatter.format(locale, format, args).flush(); + return this; + } + + @Override + public String readLine(Locale locale, String format, Object ... args) { + String line = null; + synchronized (writeLock) { + synchronized(readLock) { + if (!format.isEmpty()) + pw.format(locale, format, args); + try { + char[] ca = readline(false); + if (ca != null) + line = new String(ca); + } catch (IOException x) { + throw new IOError(x); + } + } + } + return line; + } + + @Override + public String readLine() { + return readLine(Locale.getDefault(Locale.Category.FORMAT), ""); + } + + @Override + public char[] readPassword(Locale locale, String format, Object ... args) { + char[] passwd = null; + synchronized (writeLock) { + synchronized(readLock) { + installShutdownHook(); + try { + synchronized(restoreEchoLock) { + restoreEcho = echo(false); + } + } catch (IOException x) { + throw new IOError(x); + } + IOError ioe = null; + try { + if (!format.isEmpty()) + pw.format(locale, format, args); + passwd = readline(true); + } catch (IOException x) { + ioe = new IOError(x); + } finally { + try { + synchronized(restoreEchoLock) { + if (restoreEcho) { + restoreEcho = echo(true); + } + } + } catch (IOException x) { + if (ioe == null) + ioe = new IOError(x); + else + ioe.addSuppressed(x); + } + if (ioe != null) { + //TODO: +// Arrays.fill(passwd, ' '); +// try { +// if (reader instanceof LineReader lr) { +// lr.zeroOut(); +// } +// } catch (IOException _) { +// // ignore +// } + throw ioe; + } + } + pw.println(); + } + } + return passwd; + } + + private void installShutdownHook() { + if (shutdownHookInstalled) + return; + try { + // Add a shutdown hook to restore console's echo state should + // it be necessary. + SharedSecrets.getJavaLangAccess() + .registerShutdownHook(0 /* shutdown hook invocation order */, + false /* only register if shutdown is not in progress */, + new Runnable() { + public void run() { + try { + synchronized(restoreEchoLock) { + if (restoreEcho) { + echo(true); + } + } + } catch (IOException _) { } + } + }); + } catch (IllegalStateException _) { + // shutdown is already in progress and readPassword is first used + // by a shutdown hook + } + shutdownHookInstalled = true; + } + + @Override + public char[] readPassword() { + return readPassword(Locale.getDefault(Locale.Category.FORMAT), ""); + } + + @Override + public void flush() { + pw.flush(); + } + + @Override + public Charset charset() { + return charset; + } + + private final Charset charset; + private final Object readLock; + private final Object writeLock; + // Must not block while holding this. It is used in the shutdown hook. + private final Object restoreEchoLock; + private final Reader reader; + private final Writer out; + private final NativeConsoleReader nativeConsoleReader; + private final PrintWriter pw; + private final Formatter formatter; + private boolean restoreEcho; + private boolean shutdownHookInstalled; + + private char[] readline(boolean zeroOut) throws IOException { + return nativeConsoleReader.readline(reader, out, zeroOut); + } + + /* + * Sets the console echo status to {@code on} and returns the previous + * console on/off status. + * @param on the echo status to set to. {@code true} for echo on and + * {@code false} for echo off + * @return true if the previous console echo status is on + */ + private static native boolean echo(boolean on) throws IOException; + + public JdkConsoleImpl(Charset charset) { + Objects.requireNonNull(charset); + this.charset = charset; + readLock = new Object(); + writeLock = new Object(); + restoreEchoLock = new Object(); + out = StreamEncoder.forOutputStreamWriter( + new FileOutputStream(FileDescriptor.out), + writeLock, + charset); + pw = new PrintWriter(out, true) { + public void close() { + } + }; + formatter = new Formatter(out); + reader = /*new LineReader(*/StreamDecoder.forInputStreamReader( + new FileInputStream(FileDescriptor.in), + readLock, + charset);//); + nativeConsoleReader = NativeConsoleReaderImpl.create(readLock); + } + +} diff --git a/src/java.base/share/classes/jdk/internal/io/NativeConsoleReader.java b/src/jdk.internal.le/share/classes/jdk/internal/console/NativeConsoleReader.java similarity index 97% rename from src/java.base/share/classes/jdk/internal/io/NativeConsoleReader.java rename to src/jdk.internal.le/share/classes/jdk/internal/console/NativeConsoleReader.java index ee0b75868cd59..ecb3e4fcea0a9 100644 --- a/src/java.base/share/classes/jdk/internal/io/NativeConsoleReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/console/NativeConsoleReader.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.internal.io; +package jdk.internal.console; import java.io.IOException; import java.io.Reader; diff --git a/src/java.base/share/classes/jdk/internal/io/SimpleConsoleReader.java b/src/jdk.internal.le/share/classes/jdk/internal/console/SimpleConsoleReader.java similarity index 99% rename from src/java.base/share/classes/jdk/internal/io/SimpleConsoleReader.java rename to src/jdk.internal.le/share/classes/jdk/internal/console/SimpleConsoleReader.java index 820259212473f..bca6c0de0f3e4 100644 --- a/src/java.base/share/classes/jdk/internal/io/SimpleConsoleReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/console/SimpleConsoleReader.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.internal.io; +package jdk.internal.console; import java.io.IOException; import java.io.Reader; diff --git a/src/java.base/share/classes/jdk/internal/io/Attributes.java b/src/jdk.internal.le/unix/classes/jdk/internal/console/Attributes.java similarity index 99% rename from src/java.base/share/classes/jdk/internal/io/Attributes.java rename to src/jdk.internal.le/unix/classes/jdk/internal/console/Attributes.java index 7191f6bfb5e62..76fe9d0337533 100644 --- a/src/java.base/share/classes/jdk/internal/io/Attributes.java +++ b/src/jdk.internal.le/unix/classes/jdk/internal/console/Attributes.java @@ -6,7 +6,7 @@ * * https://opensource.org/licenses/BSD-3-Clause */ -package jdk.internal.io; +package jdk.internal.console; import java.util.EnumMap; import java.util.EnumSet; diff --git a/src/java.base/share/classes/jdk/internal/io/CLibrary.java b/src/jdk.internal.le/unix/classes/jdk/internal/console/CLibrary.java similarity index 99% rename from src/java.base/share/classes/jdk/internal/io/CLibrary.java rename to src/jdk.internal.le/unix/classes/jdk/internal/console/CLibrary.java index adf07573e4954..1a9669de63cff 100644 --- a/src/java.base/share/classes/jdk/internal/io/CLibrary.java +++ b/src/jdk.internal.le/unix/classes/jdk/internal/console/CLibrary.java @@ -6,7 +6,7 @@ * * https://opensource.org/licenses/BSD-3-Clause */ -package jdk.internal.io; +package jdk.internal.console; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/src/java.base/unix/classes/jdk/internal/io/NativeConsoleReaderImpl.java b/src/jdk.internal.le/unix/classes/jdk/internal/console/NativeConsoleReaderImpl.java similarity index 99% rename from src/java.base/unix/classes/jdk/internal/io/NativeConsoleReaderImpl.java rename to src/jdk.internal.le/unix/classes/jdk/internal/console/NativeConsoleReaderImpl.java index 18488413667d9..cefda0097136c 100644 --- a/src/java.base/unix/classes/jdk/internal/io/NativeConsoleReaderImpl.java +++ b/src/jdk.internal.le/unix/classes/jdk/internal/console/NativeConsoleReaderImpl.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.internal.io; +package jdk.internal.console; import java.io.IOException; import java.io.Reader; diff --git a/src/java.base/windows/classes/jdk/internal/io/Kernel32.java b/src/jdk.internal.le/windows/classes/jdk/internal/console/Kernel32.java similarity index 99% rename from src/java.base/windows/classes/jdk/internal/io/Kernel32.java rename to src/jdk.internal.le/windows/classes/jdk/internal/console/Kernel32.java index ae3ba7fd2c179..7fb32b95cf33e 100644 --- a/src/java.base/windows/classes/jdk/internal/io/Kernel32.java +++ b/src/jdk.internal.le/windows/classes/jdk/internal/console/Kernel32.java @@ -6,7 +6,7 @@ * * https://opensource.org/licenses/BSD-3-Clause */ -package jdk.internal.io; +package jdk.internal.console; import java.io.IOException; import java.lang.foreign.MemoryLayout; diff --git a/src/java.base/windows/classes/jdk/internal/io/NativeConsoleReaderImpl.java b/src/jdk.internal.le/windows/classes/jdk/internal/console/NativeConsoleReaderImpl.java similarity index 92% rename from src/java.base/windows/classes/jdk/internal/io/NativeConsoleReaderImpl.java rename to src/jdk.internal.le/windows/classes/jdk/internal/console/NativeConsoleReaderImpl.java index ac3e4042183aa..bb17d5949f6bd 100644 --- a/src/java.base/windows/classes/jdk/internal/io/NativeConsoleReaderImpl.java +++ b/src/jdk.internal.le/windows/classes/jdk/internal/console/NativeConsoleReaderImpl.java @@ -1,4 +1,4 @@ -package jdk.internal.io; +package jdk.internal.console; import java.io.Reader; import java.io.Writer; @@ -8,20 +8,20 @@ import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.util.concurrent.atomic.AtomicInteger; -import static jdk.internal.io.Kernel32.ALT_FLAG; -import jdk.internal.io.Kernel32.CONSOLE_SCREEN_BUFFER_INFO; -import static jdk.internal.io.Kernel32.CTRL_FLAG; -import jdk.internal.io.Kernel32.INPUT_RECORD; -import static jdk.internal.io.Kernel32.INVALID_HANDLE_VALUE; -import static jdk.internal.io.Kernel32.KEY_EVENT; -import jdk.internal.io.Kernel32.KEY_EVENT_RECORD; -import static jdk.internal.io.Kernel32.LEFT_ALT_PRESSED; -import static jdk.internal.io.Kernel32.LEFT_CTRL_PRESSED; -import static jdk.internal.io.Kernel32.RIGHT_ALT_PRESSED; -import static jdk.internal.io.Kernel32.RIGHT_CTRL_PRESSED; -import static jdk.internal.io.Kernel32.SHIFT_FLAG; -import static jdk.internal.io.Kernel32.SHIFT_PRESSED; -import static jdk.internal.io.Kernel32.WINDOW_BUFFER_SIZE_EVENT; +import static jdk.internal.console.Kernel32.ALT_FLAG; +import jdk.internal.console.Kernel32.CONSOLE_SCREEN_BUFFER_INFO; +import static jdk.internal.console.Kernel32.CTRL_FLAG; +import jdk.internal.console.Kernel32.INPUT_RECORD; +import static jdk.internal.console.Kernel32.INVALID_HANDLE_VALUE; +import static jdk.internal.console.Kernel32.KEY_EVENT; +import jdk.internal.console.Kernel32.KEY_EVENT_RECORD; +import static jdk.internal.console.Kernel32.LEFT_ALT_PRESSED; +import static jdk.internal.console.Kernel32.LEFT_CTRL_PRESSED; +import static jdk.internal.console.Kernel32.RIGHT_ALT_PRESSED; +import static jdk.internal.console.Kernel32.RIGHT_CTRL_PRESSED; +import static jdk.internal.console.Kernel32.SHIFT_FLAG; +import static jdk.internal.console.Kernel32.SHIFT_PRESSED; +import static jdk.internal.console.Kernel32.WINDOW_BUFFER_SIZE_EVENT; //partly based on JLine: /*