JDK 11 jdk.internal.le.jmod - Internal Line Editing Module

JDK 11 jdk.internal.le.jmod is the JMOD file for JDK 11 Internal Line Editing module.

JDK 11 Internal Line Editing module compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.internal.le.jmod.

JDK 11 Internal Line Editing module compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.

JDK 11 Internal Line Editing module source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\jdk.internal.le.

You can click and view the content of each source code file in the list below.

✍: FYIcenter

jdk/internal/jline/WindowsTerminal.java

/*
 * Copyright (c) 2002-2016, 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 jdk.internal.jline;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import jdk.internal.jline.extra.AnsiInterpretingOutputStream;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream.BufferState;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream.Performer;
import jdk.internal.jline.internal.Configuration;
import jdk.internal.jline.internal.Log;
//import org.fusesource.jansi.internal.WindowsSupport;
//import org.fusesource.jansi.internal.Kernel32;
//import static org.fusesource.jansi.internal.Kernel32.*;

import static jdk.internal.jline.WindowsTerminal.ConsoleMode.ENABLE_ECHO_INPUT;
import static jdk.internal.jline.WindowsTerminal.ConsoleMode.ENABLE_LINE_INPUT;
import static jdk.internal.jline.WindowsTerminal.ConsoleMode.ENABLE_PROCESSED_INPUT;
import static jdk.internal.jline.WindowsTerminal.ConsoleMode.ENABLE_WINDOW_INPUT;

/**
 * Terminal implementation for Microsoft Windows. Terminal initialization in
 * {@link #init} is accomplished by extracting the
 * <em>jline_<i>version</i>.dll</em>, saving it to the system temporary
 * directoy (determined by the setting of the <em>java.io.tmpdir</em> System
 * property), loading the library, and then calling the Win32 APIs <a
 * href="http://msdn.microsoft.com/library/default.asp?
 * url=/library/en-us/dllproc/base/setconsolemode.asp">SetConsoleMode</a> and
 * <a href="http://msdn.microsoft.com/library/default.asp?
 * url=/library/en-us/dllproc/base/getconsolemode.asp">GetConsoleMode</a> to
 * disable character echoing.
 * <p/>
 * <p>
 * By default, the {@link #wrapInIfNeeded(java.io.InputStream)} method will attempt
 * to test to see if the specified {@link InputStream} is {@link System#in} or a wrapper
 * around {@link FileDescriptor#in}, and if so, will bypass the character reading to
 * directly invoke the readc() method in the JNI library. This is so the class
 * can read special keys (like arrow keys) which are otherwise inaccessible via
 * the {@link System#in} stream. Using JNI reading can be bypassed by setting
 * the <code>jline.WindowsTerminal.directConsole</code> system property
 * to <code>false</code>.
 * </p>
 *
 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
 * @since 2.0
 */
public class WindowsTerminal
    extends TerminalSupport
{
    public static final String DIRECT_CONSOLE = WindowsTerminal.class.getName() + ".directConsole";

    public static final String ANSI = WindowsTerminal.class.getName() + ".ansi";

    private boolean directConsole;

    private int originalMode;

    public WindowsTerminal() throws Exception {
        super(true);
    }

    @Override
    public void init() throws Exception {
        super.init();

//        setAnsiSupported(Configuration.getBoolean(ANSI, true));
        setAnsiSupported(true);

        //
        // FIXME: Need a way to disable direct console and sysin detection muck
        //

        setDirectConsole(Configuration.getBoolean(DIRECT_CONSOLE, true));

        this.originalMode = getConsoleMode();
        setConsoleMode(originalMode & ~ENABLE_ECHO_INPUT.code);
        setEchoEnabled(false);
    }

    /**
     * Restore the original terminal configuration, which can be used when
     * shutting down the console reader. The ConsoleReader cannot be
     * used after calling this method.
     */
    @Override
    public void restore() throws Exception {
        // restore the old console mode
        setConsoleMode(originalMode);
        super.restore();
    }

    @Override
    public int getWidth() {
        int w = getWindowsTerminalWidth();
        return w < 1 ? DEFAULT_WIDTH : w;
    }

    @Override
    public int getHeight() {
        int h = getWindowsTerminalHeight();
        return h < 1 ? DEFAULT_HEIGHT : h;
    }

    @Override
    public void setEchoEnabled(final boolean enabled) {
        // Must set these four modes at the same time to make it work fine.
        if (enabled) {
            setConsoleMode(getConsoleMode() |
                ENABLE_ECHO_INPUT.code |
                ENABLE_LINE_INPUT.code |
                ENABLE_WINDOW_INPUT.code);
        }
        else {
            setConsoleMode(getConsoleMode() &
                ~(ENABLE_LINE_INPUT.code |
                    ENABLE_ECHO_INPUT.code |
                    ENABLE_WINDOW_INPUT.code));
        }
        super.setEchoEnabled(enabled);
    }

    public void disableInterruptCharacter() {
        setConsoleMode(getConsoleMode() &
            ~(ENABLE_PROCESSED_INPUT.code));
    }

    public void enableInterruptCharacter() {
        setConsoleMode(getConsoleMode() |
            ENABLE_PROCESSED_INPUT.code);
    }

    /**
     * Whether or not to allow the use of the JNI console interaction.
     */
    public void setDirectConsole(final boolean flag) {
        this.directConsole = flag;
        Log.debug("Direct console: ", flag);
    }

    /**
     * Whether or not to allow the use of the JNI console interaction.
     */
    public Boolean getDirectConsole() {
        return directConsole;
    }


    @Override
    public InputStream wrapInIfNeeded(InputStream in) throws IOException {
        if (directConsole && isSystemIn(in)) {
            return new InputStream() {
                private byte[] buf = null;
                int bufIdx = 0;

                @Override
                public int read() throws IOException {
                    while (buf == null || bufIdx == buf.length) {
                        buf = readConsoleInput();
                        bufIdx = 0;
                    }
                    int c = buf[bufIdx] & 0xFF;
                    bufIdx++;
                    return c;
                }
            };
        } else {
            return super.wrapInIfNeeded(in);
        }
    }

    protected boolean isSystemIn(final InputStream in) throws IOException {
        if (in == null) {
            return false;
        }
        else if (in == System.in) {
            return true;
        }
        else if (in instanceof FileInputStream && ((FileInputStream) in).getFD() == FileDescriptor.in) {
            return true;
        }

        return false;
    }

    @Override
    public OutputStream wrapOutIfNeeded(OutputStream out) {
        return new AnsiInterpretingOutputStream(getOutputEncoding(), out, new Performer() {
            @Override
            public BufferState getBufferState() throws IOException {
                out.flush();
                return WindowsTerminal.this.getBufferState();
            }
            @Override
            public void setCursorPosition(int cursorX, int cursorY) throws IOException {
                out.flush();
                WindowsTerminal.this.setCursorPosition(cursorX, cursorY);
            }
        });
    }

    @Override
    public String getOutputEncoding() {
        int codepage = getConsoleOutputCodepage();
        //http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html
        String charsetMS = "ms" + codepage;
        if (java.nio.charset.Charset.isSupported(charsetMS)) {
            return charsetMS;
        }
        String charsetCP = "cp" + codepage;
        if (java.nio.charset.Charset.isSupported(charsetCP)) {
            return charsetCP;
        }
        Log.debug("can't figure out the Java Charset of this code page (" + codepage + ")...");
        return super.getOutputEncoding();
    }

    //
    // Original code:
    //
//    private int getConsoleMode() {
//        return WindowsSupport.getConsoleMode();
//    }
//
//    private void setConsoleMode(int mode) {
//        WindowsSupport.setConsoleMode(mode);
//    }
//
//    private byte[] readConsoleInput() {
//        // XXX does how many events to read in one call matter?
//        INPUT_RECORD[] events = null;
//        try {
//            events = WindowsSupport.readConsoleInput(1);
//        } catch (IOException e) {
//            Log.debug("read Windows console input error: ", e);
//        }
//        if (events == null) {
//            return new byte[0];
//        }
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0; i < events.length; i++ ) {
//            KEY_EVENT_RECORD keyEvent = events[i].keyEvent;
//            //Log.trace(keyEvent.keyDown? "KEY_DOWN" : "KEY_UP", "key code:", keyEvent.keyCode, "char:", (long)keyEvent.uchar);
//            if (keyEvent.keyDown) {
//                if (keyEvent.uchar > 0) {
//                    // support some C1 control sequences: ALT + [@-_] (and [a-z]?) => ESC <ascii>
//                    // http://en.wikipedia.org/wiki/C0_and_C1_control_codes#C1_set
//                    final int altState = KEY_EVENT_RECORD.LEFT_ALT_PRESSED | KEY_EVENT_RECORD.RIGHT_ALT_PRESSED;
//                    // Pressing "Alt Gr" is translated to Alt-Ctrl, hence it has to be checked that Ctrl is _not_ pressed,
//                    // otherwise inserting of "Alt Gr" codes on non-US keyboards would yield errors
//                    final int ctrlState = KEY_EVENT_RECORD.LEFT_CTRL_PRESSED | KEY_EVENT_RECORD.RIGHT_CTRL_PRESSED;
//                    if (((keyEvent.uchar >= '@' && keyEvent.uchar <= '_') || (keyEvent.uchar >= 'a' && keyEvent.uchar <= 'z'))
//                        && ((keyEvent.controlKeyState & altState) != 0) && ((keyEvent.controlKeyState & ctrlState) == 0)) {
//                        sb.append('\u001B'); // ESC
//                    }
//
//                    sb.append(keyEvent.uchar);
//                    continue;
//                }
//                // virtual keycodes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
//                // just add support for basic editing keys (no control state, no numpad keys)
//                String escapeSequence = null;
//                switch (keyEvent.keyCode) {
//                case 0x21: // VK_PRIOR PageUp
//                    escapeSequence = "\u001B[5~";
//                    break;
//                case 0x22: // VK_NEXT PageDown
//                    escapeSequence = "\u001B[6~";
//                    break;
//                case 0x23: // VK_END
//                    escapeSequence = "\u001B[4~";
//                    break;
//                case 0x24: // VK_HOME
//                    escapeSequence = "\u001B[1~";
//                    break;
//                case 0x25: // VK_LEFT
//                    escapeSequence = "\u001B[D";
//                    break;
//                case 0x26: // VK_UP
//                    escapeSequence = "\u001B[A";
//                    break;
//                case 0x27: // VK_RIGHT
//                    escapeSequence = "\u001B[C";
//                    break;
//                case 0x28: // VK_DOWN
//                    escapeSequence = "\u001B[B";
//                    break;
//                case 0x2D: // VK_INSERT
//                    escapeSequence = "\u001B[2~";
//                    break;
//                case 0x2E: // VK_DELETE
//                    escapeSequence = "\u001B[3~";
//                    break;
//                default:
//                    break;
//                }
//                if (escapeSequence != null) {
//                    for (int k = 0; k < keyEvent.repeatCount; k++) {
//                        sb.append(escapeSequence);
//                    }
//                }
//            } else {
//                // key up event
//                // support ALT+NumPad input method
//                if (keyEvent.keyCode == 0x12/*VK_MENU ALT key*/ && keyEvent.uchar > 0) {
//                    sb.append(keyEvent.uchar);
//                }
//            }
//        }
//        return sb.toString().getBytes();
//    }
//
//    private int getConsoleOutputCodepage() {
//        return Kernel32.GetConsoleOutputCP();
//    }
//
//    private int getWindowsTerminalWidth() {
//        return WindowsSupport.getWindowsTerminalWidth();
//    }
//
//    private int getWindowsTerminalHeight() {
//        return WindowsSupport.getWindowsTerminalHeight();
//    }

    //
    // Native Bits
    //
    static {
        System.loadLibrary("le");
        initIDs();
    }

    private static native void initIDs();

    protected native int getConsoleMode();

    protected native void setConsoleMode(int mode);

    private byte[] readConsoleInput() {
        KEY_EVENT_RECORD keyEvent = readKeyEvent();

        return convertKeys(keyEvent).getBytes();
    }

    public static String convertKeys(KEY_EVENT_RECORD keyEvent) {
        if (keyEvent == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        if (keyEvent.keyDown) {
            if (keyEvent.uchar > 0) {
                // support some C1 control sequences: ALT + [@-_] (and [a-z]?) => ESC <ascii>
                // http://en.wikipedia.org/wiki/C0_and_C1_control_codes#C1_set
                final int altState = KEY_EVENT_RECORD.ALT_PRESSED;
                // Pressing "Alt Gr" is translated to Alt-Ctrl, hence it has to be checked that Ctrl is _not_ pressed,
                // otherwise inserting of "Alt Gr" codes on non-US keyboards would yield errors
                final int ctrlState = KEY_EVENT_RECORD.CTRL_PRESSED;

                boolean handled = false;

                if ((keyEvent.controlKeyState & ctrlState) != 0) {
                    switch (keyEvent.keyCode) {
                        case 0x43: //Ctrl-C
                            sb.append("\003");
                            handled = true;
                            break;
                    }
                }

                if ((keyEvent.controlKeyState & KEY_EVENT_RECORD.SHIFT_PRESSED) != 0) {
                    switch (keyEvent.keyCode) {
                        case 0x09: //Shift-Tab
                            sb.append("\033\133\132");
                            handled = true;
                            break;
                    }
                }

                if (!handled) {
                    if (((keyEvent.uchar >= '@' && keyEvent.uchar <= '_') || (keyEvent.uchar >= 'a' && keyEvent.uchar <= 'z'))
                        && ((keyEvent.controlKeyState & altState) != 0) && ((keyEvent.controlKeyState & ctrlState) == 0)) {
                        sb.append('\u001B'); // ESC
                    }

                    sb.append(keyEvent.uchar);
                }
            } else {
                // virtual keycodes: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
                // xterm escape codes: E. Moy, S. Gildea and T. Dickey, "XTerm Control Sequences":
                // http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
                // http://xorg.freedesktop.org/releases/X11R6.8.1/PDF/ctlseqs.pdf
                // just add support for basic editing keys and function keys
                String escapeSequence = null;
                switch (keyEvent.keyCode) {
                case 0x21: // VK_PRIOR PageUp
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[5~", "\u001B[5;%d~");
                    break;
                case 0x22: // VK_NEXT PageDown
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[6~", "\u001B[6;%d~");
                    break;
                case 0x23: // VK_END
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[4~", "\u001B[4;%d~");
                    break;
                case 0x24: // VK_HOME
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[1~", "\u001B[1;%d~");
                    break;
                case 0x25: // VK_LEFT
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[D", "\u001B[1;%dD");
                    break;
                case 0x26: // VK_UP
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[A", "\u001B[1;%dA");
                    break;
                case 0x27: // VK_RIGHT
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[C", "\u001B[1;%dC");
                    break;
                case 0x28: // VK_DOWN
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[B", "\u001B[1;%dB");
                    break;
                case 0x2D: // VK_INSERT
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[2~", "\u001B[2;%d~");
                    break;
                case 0x2E: // VK_DELETE
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[3~", "\u001B[3;%d~");
                    break;
                case 0x70: // VK_F1
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001BOP", "\u001BO%dP");
                    break;
                case 0x71: // VK_F2
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001BOQ", "\u001BO%dQ");
                    break;
                case 0x72: // VK_F3
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001BOR", "\u001BO%dR");
                    break;
                case 0x73: // VK_F4
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001BOS", "\u001BO%dS");
                    break;
                case 0x74: // VK_F5
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[15~", "\u001B[15;%d~");
                    break;
                case 0x75: // VK_F6
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[17~", "\u001B[17;%d~");
                    break;
                case 0x76: // VK_F7
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[18~", "\u001B[18;%d~");
                    break;
                case 0x77: // VK_F8
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[19~", "\u001B[19;%d~");
                    break;
                case 0x78: // VK_F9
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[20~", "\u001B[20;%d~");
                    break;
                case 0x79: // VK_F10
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[21~", "\u001B[21;%d~");
                    break;
                case 0x7A: // VK_F11
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[23~", "\u001B[23;%d~");
                    break;
                case 0x7B: // VK_F12
                    escapeSequence = escapeSequence(keyEvent.controlKeyState, "\u001B[24~", "\u001B[24;%d~");
                    break;
                default:
                    break;
                }
                if (escapeSequence != null) {
                    for (int k = 0; k < keyEvent.repeatCount; k++) {
                        sb.append(escapeSequence);
                    }
                }
            }
        } else {
            // key up event
            // support ALT+NumPad input method
            if (keyEvent.keyCode == 0x12/*VK_MENU ALT key*/ && keyEvent.uchar > 0) {
                sb.append(keyEvent.uchar);
            }
        }
        return sb.toString();
    }

    private static String escapeSequence(int controlKeyState, String noControlSequence, String withControlSequence) {
        int controlNum = 1;

        if ((controlKeyState & KEY_EVENT_RECORD.SHIFT_PRESSED) != 0) {
            controlNum += 1;
        }

        if ((controlKeyState & KEY_EVENT_RECORD.ALT_PRESSED) != 0) {
            controlNum += 2;
        }

        if ((controlKeyState & KEY_EVENT_RECORD.CTRL_PRESSED) != 0) {
            controlNum += 4;
        }

        if (controlNum > 1) {
            return String.format(withControlSequence, controlNum);
        } else {
            return noControlSequence;
        }
    }

    private native KEY_EVENT_RECORD readKeyEvent();

    public static class KEY_EVENT_RECORD {
        public final static int ALT_PRESSED = 0x3;
        public final static int CTRL_PRESSED = 0xC;
        public final static int SHIFT_PRESSED = 0x10;
        public final boolean keyDown;
        public final char uchar;
        public final int controlKeyState;
        public final int keyCode;
        public final int repeatCount;

        public KEY_EVENT_RECORD(boolean keyDown, char uchar, int controlKeyState, int keyCode, int repeatCount) {
            this.keyDown = keyDown;
            this.uchar = uchar;
            this.controlKeyState = controlKeyState;
            this.keyCode = keyCode;
            this.repeatCount = repeatCount;
        }

    }

    private native int getConsoleOutputCodepage();

    private native int getWindowsTerminalWidth();

    private native int getWindowsTerminalHeight();

    private native BufferState getBufferState();

    private native void setCursorPosition(int x, int y);

    /**
     * Console mode
     * <p/>
     * Constants copied <tt>wincon.h</tt>.
     */
    public static enum ConsoleMode
    {
        /**
         * The ReadFile or ReadConsole function returns only when a carriage return
         * character is read. If this mode is disable, the functions return when one
         * or more characters are available.
         */
        ENABLE_LINE_INPUT(2),

        /**
         * Characters read by the ReadFile or ReadConsole function are written to
         * the active screen buffer as they are read. This mode can be used only if
         * the ENABLE_LINE_INPUT mode is also enabled.
         */
        ENABLE_ECHO_INPUT(4),

        /**
         * CTRL+C is processed by the system and is not placed in the input buffer.
         * If the input buffer is being read by ReadFile or ReadConsole, other
         * control keys are processed by the system and are not returned in the
         * ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is also
         * enabled, backspace, carriage return, and linefeed characters are handled
         * by the system.
         */
        ENABLE_PROCESSED_INPUT(1),

        /**
         * User interactions that change the size of the console screen buffer are
         * reported in the console's input buffee. Information about these events
         * can be read from the input buffer by applications using
         * theReadConsoleInput function, but not by those using ReadFile
         * orReadConsole.
         */
        ENABLE_WINDOW_INPUT(8),

        /**
         * If the mouse pointer is within the borders of the console window and the
         * window has the keyboard focus, mouse events generated by mouse movement
         * and button presses are placed in the input buffer. These events are
         * discarded by ReadFile or ReadConsole, even when this mode is enabled.
         */
        ENABLE_MOUSE_INPUT(16),

        /**
         * When enabled, text entered in a console window will be inserted at the
         * current cursor location and all text following that location will not be
         * overwritten. When disabled, all following text will be overwritten. An OR
         * operation must be performed with this flag and the ENABLE_EXTENDED_FLAGS
         * flag to enable this functionality.
         */
        ENABLE_PROCESSED_OUTPUT(1),

        /**
         * This flag enables the user to use the mouse to select and edit text. To
         * enable this option, use the OR to combine this flag with
         * ENABLE_EXTENDED_FLAGS.
         */
        ENABLE_WRAP_AT_EOL_OUTPUT(2),;

        public final int code;

        ConsoleMode(final int code) {
            this.code = code;
        }
    }

}

jdk/internal/jline/WindowsTerminal.java

 

JDK 11 jdk.internal.opt.jmod - Internal Opt Module

JDK 11 jdk.internal.jvmstat.jmod - Internal JVM Stat Module

Download and Use JDK 11

⇑⇑ FAQ for JDK (Java Development Kit)

2018-11-09, 2790👍, 0💬