001/*
002 * Copyright (C) 2009-2017 the original author(s).
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fusesource.jansi.internal;
017
018import static org.fusesource.jansi.internal.Kernel32.*;
019
020import org.fusesource.jansi.internal.Kernel32.CONSOLE_SCREEN_BUFFER_INFO;
021
022import java.io.IOException;
023
024/**
025 * Windows helper to ease Kernel32 usage.
026 *
027 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
028 */
029public class WindowsSupport {
030        
031        public static String getLastErrorMessage() {
032                int errorCode = GetLastError();
033                int bufferSize = 160;
034                byte data[] = new byte[bufferSize]; 
035                FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, data, bufferSize, null);
036                return new String(data);
037        }
038        
039    //////////////////////////////////////////////////////////////////////////                                       00
040    //
041    // The following helper methods are for jline 
042    //
043    //////////////////////////////////////////////////////////////////////////
044    
045    public static int readByte() {
046        return _getch();
047    }
048    
049    public static int getConsoleMode() {
050        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
051        if (hConsole == INVALID_HANDLE_VALUE)
052            return -1;
053        int mode[] = new int[1];
054        if (GetConsoleMode (hConsole, mode)==0)
055            return -1;
056        return mode[0];
057    }
058
059    public static void setConsoleMode(int mode) {
060        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
061        if (hConsole == INVALID_HANDLE_VALUE)
062            return;
063        SetConsoleMode (hConsole, mode);
064    }
065    
066    public static int getWindowsTerminalWidth() {
067        long outputHandle = GetStdHandle (STD_OUTPUT_HANDLE);
068        CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(); 
069        GetConsoleScreenBufferInfo (outputHandle, info);
070        return info.windowWidth();        
071    }
072
073    public static int getWindowsTerminalHeight() {
074        long outputHandle = GetStdHandle (STD_OUTPUT_HANDLE);
075        CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(); 
076        GetConsoleScreenBufferInfo (outputHandle, info);
077        return info.windowHeight();        
078    }
079
080    public static int writeConsole(String msg) {
081        long hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
082        if (hConsole == INVALID_HANDLE_VALUE)
083            return 0;
084        char[] chars = msg.toCharArray();
085        int[] written =  new int[1];
086        if (WriteConsoleW(hConsole, chars, chars.length, written, 0) != 0) {
087            return written[0];
088        } else {
089            return 0;
090        }
091    }
092
093    public static INPUT_RECORD[] readConsoleInput(int count, int dwMilliseconds) throws IOException {
094        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
095        if (hConsole == INVALID_HANDLE_VALUE)
096            return null;
097        if (WaitForSingleObject(hConsole, dwMilliseconds) != 0)
098            return null;
099        return readConsoleInputHelper(hConsole, count, false);
100    }
101
102    public static INPUT_RECORD[] readConsoleInput(int count) throws IOException {
103        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
104        if (hConsole == INVALID_HANDLE_VALUE)
105            return null;
106        return readConsoleInputHelper(hConsole, count, false);
107    }
108
109    public static INPUT_RECORD[] peekConsoleInput(int count, int dwMilliseconds) throws IOException {
110        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
111        if (hConsole == INVALID_HANDLE_VALUE)
112            return null;
113        if (WaitForSingleObject(hConsole, dwMilliseconds) != 0)
114            return null;
115        return readConsoleInputHelper(hConsole, count, true);
116    }
117
118    public static INPUT_RECORD[] peekConsoleInput(int count) throws IOException {
119        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
120        if (hConsole == INVALID_HANDLE_VALUE)
121            return null;
122        return readConsoleInputHelper(hConsole, count, true);
123    }
124
125    public static void flushConsoleInputBuffer() {
126        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
127        if (hConsole == INVALID_HANDLE_VALUE)
128            return;
129        FlushConsoleInputBuffer(hConsole);
130    }
131}