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 * 
026 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
027 */
028public class WindowsSupport {
029        
030        public static String getLastErrorMessage() {
031                int errorCode = GetLastError();
032                int bufferSize = 160;
033                byte data[] = new byte[bufferSize]; 
034                FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, data, bufferSize, null);
035                return new String(data);
036        }
037        
038    //////////////////////////////////////////////////////////////////////////                                       00
039    //
040    // The following helper methods are for jline 
041    //
042    //////////////////////////////////////////////////////////////////////////
043    
044    public static int readByte() {
045        return _getch();
046    }
047    
048    public static int getConsoleMode() {
049        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
050        if (hConsole == INVALID_HANDLE_VALUE)
051            return -1;
052        int mode[] = new int[1];
053        if (GetConsoleMode (hConsole, mode)==0)
054            return -1;
055        return mode[0];
056    }
057
058    public static void setConsoleMode(int mode) {
059        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
060        if (hConsole == INVALID_HANDLE_VALUE)
061            return;
062        SetConsoleMode (hConsole, mode);
063    }
064    
065    public static int getWindowsTerminalWidth() {
066        long outputHandle = GetStdHandle (STD_OUTPUT_HANDLE);
067        CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(); 
068        GetConsoleScreenBufferInfo (outputHandle, info);
069        return info.windowWidth();        
070    }
071
072    public static int getWindowsTerminalHeight() {
073        long outputHandle = GetStdHandle (STD_OUTPUT_HANDLE);
074        CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(); 
075        GetConsoleScreenBufferInfo (outputHandle, info);
076        return info.windowHeight();        
077    }
078
079    public static int writeConsole(String msg) {
080        long hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
081        if (hConsole == INVALID_HANDLE_VALUE)
082            return 0;
083        char[] chars = msg.toCharArray();
084        int[] written =  new int[1];
085        if (WriteConsoleW(hConsole, chars, chars.length, written, 0) != 0) {
086            return written[0];
087        } else {
088            return 0;
089        }
090    }
091
092    public static INPUT_RECORD[] readConsoleInput(int count) throws IOException {
093        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
094        if (hConsole == INVALID_HANDLE_VALUE)
095            return null;
096        return readConsoleKeyInput(hConsole, count, false);
097    }
098
099    public static INPUT_RECORD[] peekConsoleInput(int count) throws IOException {
100        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
101        if (hConsole == INVALID_HANDLE_VALUE)
102            return null;
103        return readConsoleKeyInput(hConsole, count, true);
104    }
105
106    public static void flushConsoleInputBuffer() {
107        long hConsole = GetStdHandle (STD_INPUT_HANDLE);
108        if (hConsole == INVALID_HANDLE_VALUE)
109            return;
110        FlushConsoleInputBuffer(hConsole);
111    }
112}