From 8869d29ec2d6d87423c44dcbc09f40b8d5a0fa58 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sat, 16 May 2020 15:51:00 +0700 Subject: [PATCH 1/2] Add additional Wincon bindings: * GetConsoleScreenBufferInfo * ReadConsoleInput * WriteConsole --- .../com/sun/jna/platform/win32/WinDef.java | 143 ++++++++++++++++++ .../com/sun/jna/platform/win32/Wincon.java | 41 +++++ .../platform/win32/Kernel32ConsoleTest.java | 51 +++++++ 3 files changed, 235 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java index 220f6126b1..2589b0acc6 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java @@ -31,6 +31,7 @@ import com.sun.jna.PointerType; import com.sun.jna.Structure; import com.sun.jna.Structure.FieldOrder; +import com.sun.jna.Union; import com.sun.jna.platform.win32.BaseTSD.LONG_PTR; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; @@ -1774,4 +1775,146 @@ public HGLRCByReference(HGLRC h) { super(h); } } + + /** + * COORD structure + */ + @FieldOrder({ "X", "Y" }) + public static class COORD extends Structure { + + public short X; + public short Y; + + @Override + public String toString() { + return String.format("COORD(%s,%s)", X, Y); + } + } + + /** + * SMALL_RECT structure + */ + @FieldOrder({ "Left", "Top", "Right", "Bottom" }) + public static class SMALL_RECT extends Structure { + + public short Left; + public short Top; + public short Right; + public short Bottom; + + @Override + public String toString() { + return String.format("SMALL_RECT(%s,%s)(%s,%s)", Left, Top, Right, Bottom); + } + } + + /** + * CONSOLE_SCREEN_BUFFER_INFO structure + */ + @FieldOrder({ "dwSize", "dwCursorPosition", "wAttributes", "srWindow", "dwMaximumWindowSize" }) + public static class CONSOLE_SCREEN_BUFFER_INFO extends Structure { + + public COORD dwSize; + public COORD dwCursorPosition; + public short wAttributes; + public SMALL_RECT srWindow; + public COORD dwMaximumWindowSize; + + @Override + public String toString() { + return String.format("CONSOLE_SCREEN_BUFFER_INFO(%s,%s,%s,%s,%s)", dwSize, dwCursorPosition, wAttributes, srWindow, dwMaximumWindowSize); + } + } + + /** + * INPUT_RECORD structure + */ + @FieldOrder({ "EventType", "Event" }) + public static class INPUT_RECORD extends Structure { + + public static final short KEY_EVENT = 0x01; + public static final short MOUSE_EVENT = 0x02; + public static final short WINDOW_BUFFER_SIZE_EVENT = 0x04; + + public short EventType; + public Event Event; + + public static class Event extends Union { + public KEY_EVENT_RECORD KeyEvent; + public MOUSE_EVENT_RECORD MouseEvent; + public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + } + + @Override + public void read() { + super.read(); + switch (EventType) { + case KEY_EVENT: + Event.setType("KeyEvent"); + break; + case MOUSE_EVENT: + Event.setType("MouseEvent"); + break; + case WINDOW_BUFFER_SIZE_EVENT: + Event.setType("WindowBufferSizeEvent"); + break; + } + Event.read(); + } + + @Override + public String toString() { + return String.format("INPUT_RECORD(%s)", EventType); + } + } + + /** + * KEY_EVENT_RECORD structure + */ + @FieldOrder({ "bKeyDown", "wRepeatCount", "wVirtualKeyCode", "wVirtualScanCode", "uChar", "dwControlKeyState" }) + public static class KEY_EVENT_RECORD extends Structure { + + public boolean bKeyDown; + public short wRepeatCount; + public short wVirtualKeyCode; + public short wVirtualScanCode; + public char uChar; + public int dwControlKeyState; + + @Override + public String toString() { + return String.format("KEY_EVENT_RECORD(%s,%s,%s,%s,%s,%s)", bKeyDown, wRepeatCount, wVirtualKeyCode, wVirtualKeyCode, wVirtualScanCode, uChar, dwControlKeyState); + } + } + + /** + * MOUSE_EVENT_RECORD structure + */ + @FieldOrder({ "dwMousePosition", "dwButtonState", "dwControlKeyState", "dwEventFlags" }) + public static class MOUSE_EVENT_RECORD extends Structure { + + public COORD dwMousePosition; + public int dwButtonState; + public int dwControlKeyState; + public int dwEventFlags; + + @Override + public String toString() { + return String.format("MOUSE_EVENT_RECORD(%s,%s,%s,%s)", dwMousePosition, dwButtonState, dwControlKeyState, dwEventFlags); + } + } + + /** + * WINDOW_BUFFER_SIZE_RECORD structure + */ + @FieldOrder({ "dwSize" }) + public static class WINDOW_BUFFER_SIZE_RECORD extends Structure { + + public COORD dwSize; + + @Override + public String toString() { + return String.format("WINDOW_BUFFER_SIZE_RECORD(%s)", dwSize); + } + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java b/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java index 787fc4745e..e794d544ce 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java @@ -24,7 +24,10 @@ package com.sun.jna.platform.win32; import com.sun.jna.Native; +import com.sun.jna.platform.win32.WinDef.CONSOLE_SCREEN_BUFFER_INFO; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.INPUT_RECORD; +import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; @@ -182,6 +185,9 @@ public interface Wincon { int ENABLE_INSERT_MODE=0x0020; int ENABLE_QUICK_EDIT_MODE=0x0040; int ENABLE_EXTENDED_FLAGS=0x0080; + int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; + int DISABLE_NEWLINE_AUTO_RETURN = 0x0008; + int ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200; /* If the hConsoleHandle parameter is a screen buffer handle, the mode * can be one or more of the following values @@ -249,4 +255,39 @@ public interface Wincon { * @see SetConsoleTitle documentation */ boolean SetConsoleTitle(String lpConsoleTitle); + + /** + * Retrieves information about the specified console screen buffer. + * @param hConsoleOutput A handle to the console screen buffer. + * @param lpConsoleScreenBufferInfo A pointer to a CONSOLE_SCREEN_BUFFER_INFO structure that receives the console screen buffer information. + * @return {@code true} if successful - if {@code false} then use + * {@code GetLastError()} to get extended error information + * @see GetConsoleScreenBufferInfo documentation + */ + boolean GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo); + + /** + * Reads data from a console input buffer and removes it from the buffer. + * @param hConsoleInput A handle to the console input buffer. + * @param lpBuffer A pointer to an array of INPUT_RECORD structures that receives the input buffer data. + * @param nLength The size of the array pointed to by the lpBuffer parameter, in array elements. + * @param lpNumberOfEventsRead A pointer to a variable that receives the number of input records read. + * @return {@code true} if successful - if {@code false} then use + * {@code GetLastError()} to get extended error information + * @see ReadConsoleInput documentation + */ + boolean ReadConsoleInput(HANDLE hConsoleInput, INPUT_RECORD[] lpBuffer, int nLength, IntByReference lpNumberOfEventsRead); + + /** + * Writes a character string to a console screen buffer beginning at the current cursor location. + * @param hConsoleOutput A handle to the console screen buffer. + * @param lpBuffer A pointer to a buffer that contains characters to be written to the console screen buffer. + * @param nNumberOfCharsToWrite The number of characters to be written. + * @param lpNumberOfCharsWritten A pointer to a variable that receives the number of characters actually written. + * @param lpReserved Reserved; must be NULL. + * @return {@code true} if successful - if {@code false} then use + * {@code GetLastError()} to get extended error information + * @see WriteConsole documentation + */ + boolean WriteConsole(HANDLE hConsoleOutput, String lpBuffer, int nNumberOfCharsToWrite, IntByReference lpNumberOfCharsWritten, LPVOID lpReserved); } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java index 284b5147f0..6de2aab8db 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java @@ -28,7 +28,9 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinDef.CONSOLE_SCREEN_BUFFER_INFO; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.INPUT_RECORD; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; import org.junit.Assume; @@ -142,4 +144,53 @@ public void testGetConsoleOriginalTitle() { } } } + + @Test + public void testGetConsoleScreenBufferInfo() { + HANDLE hConsoleOutput = INSTANCE.GetStdHandle(Wincon.STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo = new CONSOLE_SCREEN_BUFFER_INFO(); + + if (System.console() == null) { + assertFalse(INSTANCE.GetConsoleScreenBufferInfo(hConsoleOutput, lpConsoleScreenBufferInfo)); + } else { + assertCallSucceeded("GetConsoleScreenBufferInfo", INSTANCE.GetConsoleScreenBufferInfo(hConsoleOutput, lpConsoleScreenBufferInfo)); + } + } + + @Test + public void testReadConsoleInput() { + HANDLE hConsoleInput = INSTANCE.GetStdHandle(Wincon.STD_INPUT_HANDLE); + INPUT_RECORD[] lpBuffer = new INPUT_RECORD[1]; + IntByReference lpNumberOfEventsRead = new IntByReference(); + + if (System.console() == null) { + assertFalse(INSTANCE.ReadConsoleInput(hConsoleInput, lpBuffer, lpBuffer.length, lpNumberOfEventsRead)); + } else { + assertCallSucceeded("ReadConsoleInput", INSTANCE.ReadConsoleInput(hConsoleInput, lpBuffer, lpBuffer.length, lpNumberOfEventsRead)); + } + } + + @Test + public void testGetNumberOfConsoleInputEvents() { + HANDLE hConsoleInput = INSTANCE.GetStdHandle(Wincon.STD_INPUT_HANDLE); + IntByReference lpcNumberOfEvents = new IntByReference(); + + if (System.console() == null) { + assertFalse(INSTANCE.GetNumberOfConsoleInputEvents(hConsoleInput, lpcNumberOfEvents)); + } else { + assertCallSucceeded("GetNumberOfConsoleInputEvents", INSTANCE.GetNumberOfConsoleInputEvents(hConsoleInput, lpcNumberOfEvents)); + } + } + + @Test + public void testWriteConsole() { + HANDLE hConsoleOutput = INSTANCE.GetStdHandle(Wincon.STD_OUTPUT_HANDLE); + String lpBuffer = "WriteConsole"; + + if (System.console() == null) { + assertFalse(INSTANCE.WriteConsole(hConsoleOutput, lpBuffer, lpBuffer.length(), null, null)); + } else { + assertCallSucceeded("WriteConsole", INSTANCE.WriteConsole(hConsoleOutput, lpBuffer, lpBuffer.length(), null, null)); + } + } } From 738f98d06fdd211f52d8973ae1ff3ce30f029a73 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sun, 17 May 2020 18:52:34 +0700 Subject: [PATCH 2/2] Move all changes to Wincon --- .../com/sun/jna/platform/win32/WinDef.java | 142 ----------------- .../com/sun/jna/platform/win32/Wincon.java | 147 +++++++++++++++++- 2 files changed, 145 insertions(+), 144 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java index 2589b0acc6..abd61747f4 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java @@ -1775,146 +1775,4 @@ public HGLRCByReference(HGLRC h) { super(h); } } - - /** - * COORD structure - */ - @FieldOrder({ "X", "Y" }) - public static class COORD extends Structure { - - public short X; - public short Y; - - @Override - public String toString() { - return String.format("COORD(%s,%s)", X, Y); - } - } - - /** - * SMALL_RECT structure - */ - @FieldOrder({ "Left", "Top", "Right", "Bottom" }) - public static class SMALL_RECT extends Structure { - - public short Left; - public short Top; - public short Right; - public short Bottom; - - @Override - public String toString() { - return String.format("SMALL_RECT(%s,%s)(%s,%s)", Left, Top, Right, Bottom); - } - } - - /** - * CONSOLE_SCREEN_BUFFER_INFO structure - */ - @FieldOrder({ "dwSize", "dwCursorPosition", "wAttributes", "srWindow", "dwMaximumWindowSize" }) - public static class CONSOLE_SCREEN_BUFFER_INFO extends Structure { - - public COORD dwSize; - public COORD dwCursorPosition; - public short wAttributes; - public SMALL_RECT srWindow; - public COORD dwMaximumWindowSize; - - @Override - public String toString() { - return String.format("CONSOLE_SCREEN_BUFFER_INFO(%s,%s,%s,%s,%s)", dwSize, dwCursorPosition, wAttributes, srWindow, dwMaximumWindowSize); - } - } - - /** - * INPUT_RECORD structure - */ - @FieldOrder({ "EventType", "Event" }) - public static class INPUT_RECORD extends Structure { - - public static final short KEY_EVENT = 0x01; - public static final short MOUSE_EVENT = 0x02; - public static final short WINDOW_BUFFER_SIZE_EVENT = 0x04; - - public short EventType; - public Event Event; - - public static class Event extends Union { - public KEY_EVENT_RECORD KeyEvent; - public MOUSE_EVENT_RECORD MouseEvent; - public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; - } - - @Override - public void read() { - super.read(); - switch (EventType) { - case KEY_EVENT: - Event.setType("KeyEvent"); - break; - case MOUSE_EVENT: - Event.setType("MouseEvent"); - break; - case WINDOW_BUFFER_SIZE_EVENT: - Event.setType("WindowBufferSizeEvent"); - break; - } - Event.read(); - } - - @Override - public String toString() { - return String.format("INPUT_RECORD(%s)", EventType); - } - } - - /** - * KEY_EVENT_RECORD structure - */ - @FieldOrder({ "bKeyDown", "wRepeatCount", "wVirtualKeyCode", "wVirtualScanCode", "uChar", "dwControlKeyState" }) - public static class KEY_EVENT_RECORD extends Structure { - - public boolean bKeyDown; - public short wRepeatCount; - public short wVirtualKeyCode; - public short wVirtualScanCode; - public char uChar; - public int dwControlKeyState; - - @Override - public String toString() { - return String.format("KEY_EVENT_RECORD(%s,%s,%s,%s,%s,%s)", bKeyDown, wRepeatCount, wVirtualKeyCode, wVirtualKeyCode, wVirtualScanCode, uChar, dwControlKeyState); - } - } - - /** - * MOUSE_EVENT_RECORD structure - */ - @FieldOrder({ "dwMousePosition", "dwButtonState", "dwControlKeyState", "dwEventFlags" }) - public static class MOUSE_EVENT_RECORD extends Structure { - - public COORD dwMousePosition; - public int dwButtonState; - public int dwControlKeyState; - public int dwEventFlags; - - @Override - public String toString() { - return String.format("MOUSE_EVENT_RECORD(%s,%s,%s,%s)", dwMousePosition, dwButtonState, dwControlKeyState, dwEventFlags); - } - } - - /** - * WINDOW_BUFFER_SIZE_RECORD structure - */ - @FieldOrder({ "dwSize" }) - public static class WINDOW_BUFFER_SIZE_RECORD extends Structure { - - public COORD dwSize; - - @Override - public String toString() { - return String.format("WINDOW_BUFFER_SIZE_RECORD(%s)", dwSize); - } - } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java b/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java index e794d544ce..ad190150d1 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java @@ -24,9 +24,10 @@ package com.sun.jna.platform.win32; import com.sun.jna.Native; -import com.sun.jna.platform.win32.WinDef.CONSOLE_SCREEN_BUFFER_INFO; +import com.sun.jna.Structure; +import com.sun.jna.Structure.FieldOrder; +import com.sun.jna.Union; import com.sun.jna.platform.win32.WinDef.HWND; -import com.sun.jna.platform.win32.WinDef.INPUT_RECORD; import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; @@ -290,4 +291,146 @@ public interface Wincon { * @see WriteConsole documentation */ boolean WriteConsole(HANDLE hConsoleOutput, String lpBuffer, int nNumberOfCharsToWrite, IntByReference lpNumberOfCharsWritten, LPVOID lpReserved); + + /** + * COORD structure + */ + @FieldOrder({ "X", "Y" }) + public static class COORD extends Structure { + + public short X; + public short Y; + + @Override + public String toString() { + return String.format("COORD(%s,%s)", X, Y); + } + } + + /** + * SMALL_RECT structure + */ + @FieldOrder({ "Left", "Top", "Right", "Bottom" }) + public static class SMALL_RECT extends Structure { + + public short Left; + public short Top; + public short Right; + public short Bottom; + + @Override + public String toString() { + return String.format("SMALL_RECT(%s,%s)(%s,%s)", Left, Top, Right, Bottom); + } + } + + /** + * CONSOLE_SCREEN_BUFFER_INFO structure + */ + @FieldOrder({ "dwSize", "dwCursorPosition", "wAttributes", "srWindow", "dwMaximumWindowSize" }) + public static class CONSOLE_SCREEN_BUFFER_INFO extends Structure { + + public COORD dwSize; + public COORD dwCursorPosition; + public short wAttributes; + public SMALL_RECT srWindow; + public COORD dwMaximumWindowSize; + + @Override + public String toString() { + return String.format("CONSOLE_SCREEN_BUFFER_INFO(%s,%s,%s,%s,%s)", dwSize, dwCursorPosition, wAttributes, srWindow, dwMaximumWindowSize); + } + } + + /** + * INPUT_RECORD structure + */ + @FieldOrder({ "EventType", "Event" }) + public static class INPUT_RECORD extends Structure { + + public static final short KEY_EVENT = 0x01; + public static final short MOUSE_EVENT = 0x02; + public static final short WINDOW_BUFFER_SIZE_EVENT = 0x04; + + public short EventType; + public Event Event; + + public static class Event extends Union { + public KEY_EVENT_RECORD KeyEvent; + public MOUSE_EVENT_RECORD MouseEvent; + public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + } + + @Override + public void read() { + super.read(); + switch (EventType) { + case KEY_EVENT: + Event.setType("KeyEvent"); + break; + case MOUSE_EVENT: + Event.setType("MouseEvent"); + break; + case WINDOW_BUFFER_SIZE_EVENT: + Event.setType("WindowBufferSizeEvent"); + break; + } + Event.read(); + } + + @Override + public String toString() { + return String.format("INPUT_RECORD(%s)", EventType); + } + } + + /** + * KEY_EVENT_RECORD structure + */ + @FieldOrder({ "bKeyDown", "wRepeatCount", "wVirtualKeyCode", "wVirtualScanCode", "uChar", "dwControlKeyState" }) + public static class KEY_EVENT_RECORD extends Structure { + + public boolean bKeyDown; + public short wRepeatCount; + public short wVirtualKeyCode; + public short wVirtualScanCode; + public char uChar; + public int dwControlKeyState; + + @Override + public String toString() { + return String.format("KEY_EVENT_RECORD(%s,%s,%s,%s,%s,%s)", bKeyDown, wRepeatCount, wVirtualKeyCode, wVirtualKeyCode, wVirtualScanCode, uChar, dwControlKeyState); + } + } + + /** + * MOUSE_EVENT_RECORD structure + */ + @FieldOrder({ "dwMousePosition", "dwButtonState", "dwControlKeyState", "dwEventFlags" }) + public static class MOUSE_EVENT_RECORD extends Structure { + + public COORD dwMousePosition; + public int dwButtonState; + public int dwControlKeyState; + public int dwEventFlags; + + @Override + public String toString() { + return String.format("MOUSE_EVENT_RECORD(%s,%s,%s,%s)", dwMousePosition, dwButtonState, dwControlKeyState, dwEventFlags); + } + } + + /** + * WINDOW_BUFFER_SIZE_RECORD structure + */ + @FieldOrder({ "dwSize" }) + public static class WINDOW_BUFFER_SIZE_RECORD extends Structure { + + public COORD dwSize; + + @Override + public String toString() { + return String.format("WINDOW_BUFFER_SIZE_RECORD(%s)", dwSize); + } + } }