@shitiandmw/node-pty 1.1.0-agent.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +69 -0
- package/README.md +170 -0
- package/binding.gyp +111 -0
- package/deps/.editorconfig +2 -0
- package/deps/winpty/.drone.yml +17 -0
- package/deps/winpty/.gitattributes +19 -0
- package/deps/winpty/LICENSE +21 -0
- package/deps/winpty/Makefile +166 -0
- package/deps/winpty/README.md +151 -0
- package/deps/winpty/RELEASES.md +280 -0
- package/deps/winpty/VERSION.txt +1 -0
- package/deps/winpty/configure +167 -0
- package/deps/winpty/misc/BufferResizeTests.cc +90 -0
- package/deps/winpty/misc/ChangeScreenBuffer.cc +53 -0
- package/deps/winpty/misc/ClearConsole.cc +72 -0
- package/deps/winpty/misc/ConinMode.cc +117 -0
- package/deps/winpty/misc/ConinMode.ps1 +116 -0
- package/deps/winpty/misc/ConoutMode.cc +113 -0
- package/deps/winpty/misc/DebugClient.py +42 -0
- package/deps/winpty/misc/DebugServer.py +63 -0
- package/deps/winpty/misc/DumpLines.py +5 -0
- package/deps/winpty/misc/EnableExtendedFlags.txt +46 -0
- package/deps/winpty/misc/Font-Report-June2016/CP437-Consolas.txt +528 -0
- package/deps/winpty/misc/Font-Report-June2016/CP437-Lucida.txt +633 -0
- package/deps/winpty/misc/Font-Report-June2016/CP932.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/CP936.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/CP949.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/CP950.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/MinimumWindowWidths.txt +16 -0
- package/deps/winpty/misc/Font-Report-June2016/Results.txt +4 -0
- package/deps/winpty/misc/Font-Report-June2016/Windows10SetFontBugginess.txt +144 -0
- package/deps/winpty/misc/FontSurvey.cc +100 -0
- package/deps/winpty/misc/FormatChar.h +21 -0
- package/deps/winpty/misc/FreezePerfTest.cc +62 -0
- package/deps/winpty/misc/GetCh.cc +20 -0
- package/deps/winpty/misc/GetConsolePos.cc +41 -0
- package/deps/winpty/misc/GetFont.cc +261 -0
- package/deps/winpty/misc/IdentifyConsoleWindow.ps1 +51 -0
- package/deps/winpty/misc/IsNewConsole.cc +87 -0
- package/deps/winpty/misc/MouseInputNotes.txt +90 -0
- package/deps/winpty/misc/MoveConsoleWindow.cc +34 -0
- package/deps/winpty/misc/Notes.txt +219 -0
- package/deps/winpty/misc/OSVersion.cc +27 -0
- package/deps/winpty/misc/ScreenBufferFreezeInactive.cc +101 -0
- package/deps/winpty/misc/ScreenBufferTest.cc +671 -0
- package/deps/winpty/misc/ScreenBufferTest2.cc +151 -0
- package/deps/winpty/misc/SelectAllTest.cc +45 -0
- package/deps/winpty/misc/SetBufferSize.cc +32 -0
- package/deps/winpty/misc/SetCursorPos.cc +10 -0
- package/deps/winpty/misc/SetFont.cc +145 -0
- package/deps/winpty/misc/SetWindowRect.cc +36 -0
- package/deps/winpty/misc/ShowArgv.cc +12 -0
- package/deps/winpty/misc/ShowConsoleInput.cc +40 -0
- package/deps/winpty/misc/Spew.py +5 -0
- package/deps/winpty/misc/TestUtil.cc +172 -0
- package/deps/winpty/misc/UnicodeDoubleWidthTest.cc +102 -0
- package/deps/winpty/misc/UnicodeWideTest1.cc +246 -0
- package/deps/winpty/misc/UnicodeWideTest2.cc +130 -0
- package/deps/winpty/misc/UnixEcho.cc +89 -0
- package/deps/winpty/misc/Utf16Echo.cc +46 -0
- package/deps/winpty/misc/VeryLargeRead.cc +122 -0
- package/deps/winpty/misc/VkEscapeTest.cc +56 -0
- package/deps/winpty/misc/Win10ResizeWhileFrozen.cc +52 -0
- package/deps/winpty/misc/Win10WrapTest1.cc +57 -0
- package/deps/winpty/misc/Win10WrapTest2.cc +30 -0
- package/deps/winpty/misc/Win32Echo1.cc +26 -0
- package/deps/winpty/misc/Win32Echo2.cc +19 -0
- package/deps/winpty/misc/Win32Test1.cc +46 -0
- package/deps/winpty/misc/Win32Test2.cc +70 -0
- package/deps/winpty/misc/Win32Test3.cc +78 -0
- package/deps/winpty/misc/Win32Write1.cc +44 -0
- package/deps/winpty/misc/WindowsBugCrashReader.cc +27 -0
- package/deps/winpty/misc/WriteConsole.cc +106 -0
- package/deps/winpty/misc/build32.sh +9 -0
- package/deps/winpty/misc/build64.sh +9 -0
- package/deps/winpty/misc/color-test.sh +212 -0
- package/deps/winpty/misc/font-notes.txt +300 -0
- package/deps/winpty/misc/winbug-15048.cc +201 -0
- package/deps/winpty/ship/build-pty4j-libpty.bat +36 -0
- package/deps/winpty/ship/common_ship.py +53 -0
- package/deps/winpty/ship/make_msvc_package.py +165 -0
- package/deps/winpty/ship/ship.py +108 -0
- package/deps/winpty/src/agent/Agent.cc +613 -0
- package/deps/winpty/src/agent/Agent.h +103 -0
- package/deps/winpty/src/agent/AgentCreateDesktop.cc +84 -0
- package/deps/winpty/src/agent/AgentCreateDesktop.h +28 -0
- package/deps/winpty/src/agent/ConsoleFont.cc +632 -0
- package/deps/winpty/src/agent/ConsoleFont.h +28 -0
- package/deps/winpty/src/agent/ConsoleInput.cc +852 -0
- package/deps/winpty/src/agent/ConsoleInput.h +109 -0
- package/deps/winpty/src/agent/ConsoleInputReencoding.cc +121 -0
- package/deps/winpty/src/agent/ConsoleInputReencoding.h +36 -0
- package/deps/winpty/src/agent/ConsoleLine.cc +152 -0
- package/deps/winpty/src/agent/ConsoleLine.h +41 -0
- package/deps/winpty/src/agent/Coord.h +87 -0
- package/deps/winpty/src/agent/DebugShowInput.cc +239 -0
- package/deps/winpty/src/agent/DebugShowInput.h +32 -0
- package/deps/winpty/src/agent/DefaultInputMap.cc +422 -0
- package/deps/winpty/src/agent/DefaultInputMap.h +28 -0
- package/deps/winpty/src/agent/DsrSender.h +30 -0
- package/deps/winpty/src/agent/EventLoop.cc +99 -0
- package/deps/winpty/src/agent/EventLoop.h +47 -0
- package/deps/winpty/src/agent/InputMap.cc +246 -0
- package/deps/winpty/src/agent/InputMap.h +114 -0
- package/deps/winpty/src/agent/LargeConsoleRead.cc +71 -0
- package/deps/winpty/src/agent/LargeConsoleRead.h +68 -0
- package/deps/winpty/src/agent/NamedPipe.cc +378 -0
- package/deps/winpty/src/agent/NamedPipe.h +125 -0
- package/deps/winpty/src/agent/Scraper.cc +699 -0
- package/deps/winpty/src/agent/Scraper.h +103 -0
- package/deps/winpty/src/agent/SimplePool.h +75 -0
- package/deps/winpty/src/agent/SmallRect.h +143 -0
- package/deps/winpty/src/agent/Terminal.cc +535 -0
- package/deps/winpty/src/agent/Terminal.h +69 -0
- package/deps/winpty/src/agent/UnicodeEncoding.h +157 -0
- package/deps/winpty/src/agent/UnicodeEncodingTest.cc +189 -0
- package/deps/winpty/src/agent/Win32Console.cc +107 -0
- package/deps/winpty/src/agent/Win32Console.h +67 -0
- package/deps/winpty/src/agent/Win32ConsoleBuffer.cc +193 -0
- package/deps/winpty/src/agent/Win32ConsoleBuffer.h +99 -0
- package/deps/winpty/src/agent/main.cc +114 -0
- package/deps/winpty/src/agent/subdir.mk +61 -0
- package/deps/winpty/src/configurations.gypi +60 -0
- package/deps/winpty/src/debugserver/DebugServer.cc +117 -0
- package/deps/winpty/src/debugserver/subdir.mk +41 -0
- package/deps/winpty/src/include/winpty.h +242 -0
- package/deps/winpty/src/include/winpty_constants.h +131 -0
- package/deps/winpty/src/libwinpty/AgentLocation.cc +75 -0
- package/deps/winpty/src/libwinpty/AgentLocation.h +28 -0
- package/deps/winpty/src/libwinpty/LibWinptyException.h +54 -0
- package/deps/winpty/src/libwinpty/WinptyInternal.h +72 -0
- package/deps/winpty/src/libwinpty/subdir.mk +46 -0
- package/deps/winpty/src/libwinpty/winpty.cc +970 -0
- package/deps/winpty/src/shared/AgentMsg.h +38 -0
- package/deps/winpty/src/shared/BackgroundDesktop.cc +122 -0
- package/deps/winpty/src/shared/BackgroundDesktop.h +73 -0
- package/deps/winpty/src/shared/Buffer.cc +103 -0
- package/deps/winpty/src/shared/Buffer.h +102 -0
- package/deps/winpty/src/shared/DebugClient.cc +187 -0
- package/deps/winpty/src/shared/DebugClient.h +38 -0
- package/deps/winpty/src/shared/GenRandom.cc +138 -0
- package/deps/winpty/src/shared/GenRandom.h +55 -0
- package/deps/winpty/src/shared/GetCommitHash.bat +13 -0
- package/deps/winpty/src/shared/Mutex.h +54 -0
- package/deps/winpty/src/shared/OsModule.h +63 -0
- package/deps/winpty/src/shared/OwnedHandle.cc +36 -0
- package/deps/winpty/src/shared/OwnedHandle.h +45 -0
- package/deps/winpty/src/shared/PrecompiledHeader.h +43 -0
- package/deps/winpty/src/shared/StringBuilder.h +227 -0
- package/deps/winpty/src/shared/StringBuilderTest.cc +114 -0
- package/deps/winpty/src/shared/StringUtil.cc +55 -0
- package/deps/winpty/src/shared/StringUtil.h +80 -0
- package/deps/winpty/src/shared/TimeMeasurement.h +63 -0
- package/deps/winpty/src/shared/UnixCtrlChars.h +45 -0
- package/deps/winpty/src/shared/UpdateGenVersion.bat +20 -0
- package/deps/winpty/src/shared/WindowsSecurity.cc +460 -0
- package/deps/winpty/src/shared/WindowsSecurity.h +104 -0
- package/deps/winpty/src/shared/WindowsVersion.cc +252 -0
- package/deps/winpty/src/shared/WindowsVersion.h +29 -0
- package/deps/winpty/src/shared/WinptyAssert.cc +55 -0
- package/deps/winpty/src/shared/WinptyAssert.h +64 -0
- package/deps/winpty/src/shared/WinptyException.cc +57 -0
- package/deps/winpty/src/shared/WinptyException.h +43 -0
- package/deps/winpty/src/shared/WinptyVersion.cc +42 -0
- package/deps/winpty/src/shared/WinptyVersion.h +27 -0
- package/deps/winpty/src/shared/winpty_snprintf.h +99 -0
- package/deps/winpty/src/subdir.mk +5 -0
- package/deps/winpty/src/tests/subdir.mk +28 -0
- package/deps/winpty/src/tests/trivial_test.cc +158 -0
- package/deps/winpty/src/unix-adapter/InputHandler.cc +114 -0
- package/deps/winpty/src/unix-adapter/InputHandler.h +56 -0
- package/deps/winpty/src/unix-adapter/OutputHandler.cc +80 -0
- package/deps/winpty/src/unix-adapter/OutputHandler.h +53 -0
- package/deps/winpty/src/unix-adapter/Util.cc +86 -0
- package/deps/winpty/src/unix-adapter/Util.h +31 -0
- package/deps/winpty/src/unix-adapter/WakeupFd.cc +70 -0
- package/deps/winpty/src/unix-adapter/WakeupFd.h +42 -0
- package/deps/winpty/src/unix-adapter/main.cc +729 -0
- package/deps/winpty/src/unix-adapter/subdir.mk +41 -0
- package/deps/winpty/src/winpty.gyp +234 -0
- package/deps/winpty/vcbuild.bat +83 -0
- package/lib/conpty_console_list_agent.js +16 -0
- package/lib/conpty_console_list_agent.js.map +1 -0
- package/lib/eventEmitter2.js +47 -0
- package/lib/eventEmitter2.js.map +1 -0
- package/lib/eventEmitter2.test.js +30 -0
- package/lib/eventEmitter2.test.js.map +1 -0
- package/lib/index.js +52 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces.js +7 -0
- package/lib/interfaces.js.map +1 -0
- package/lib/shared/conout.js +11 -0
- package/lib/shared/conout.js.map +1 -0
- package/lib/terminal.js +190 -0
- package/lib/terminal.js.map +1 -0
- package/lib/terminal.test.js +139 -0
- package/lib/terminal.test.js.map +1 -0
- package/lib/testUtils.test.js +28 -0
- package/lib/testUtils.test.js.map +1 -0
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -0
- package/lib/unixTerminal.js +346 -0
- package/lib/unixTerminal.js.map +1 -0
- package/lib/unixTerminal.test.js +351 -0
- package/lib/unixTerminal.test.js.map +1 -0
- package/lib/utils.js +39 -0
- package/lib/utils.js.map +1 -0
- package/lib/windowsConoutConnection.js +125 -0
- package/lib/windowsConoutConnection.js.map +1 -0
- package/lib/windowsPtyAgent.js +320 -0
- package/lib/windowsPtyAgent.js.map +1 -0
- package/lib/windowsPtyAgent.test.js +90 -0
- package/lib/windowsPtyAgent.test.js.map +1 -0
- package/lib/windowsTerminal.js +199 -0
- package/lib/windowsTerminal.js.map +1 -0
- package/lib/windowsTerminal.test.js +219 -0
- package/lib/windowsTerminal.test.js.map +1 -0
- package/lib/worker/conoutSocketWorker.js +22 -0
- package/lib/worker/conoutSocketWorker.js.map +1 -0
- package/package.json +68 -0
- package/prebuilds/darwin-arm64/pty.node +0 -0
- package/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/prebuilds/darwin-x64/pty.node +0 -0
- package/prebuilds/darwin-x64/spawn-helper +0 -0
- package/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/prebuilds/win32-arm64/conpty.node +0 -0
- package/prebuilds/win32-arm64/conpty.pdb +0 -0
- package/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
- package/prebuilds/win32-arm64/pty.node +0 -0
- package/prebuilds/win32-arm64/pty.pdb +0 -0
- package/prebuilds/win32-arm64/winpty-agent.exe +0 -0
- package/prebuilds/win32-arm64/winpty-agent.pdb +0 -0
- package/prebuilds/win32-arm64/winpty.dll +0 -0
- package/prebuilds/win32-arm64/winpty.pdb +0 -0
- package/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/prebuilds/win32-x64/conpty.node +0 -0
- package/prebuilds/win32-x64/conpty.pdb +0 -0
- package/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
- package/prebuilds/win32-x64/pty.node +0 -0
- package/prebuilds/win32-x64/pty.pdb +0 -0
- package/prebuilds/win32-x64/winpty-agent.exe +0 -0
- package/prebuilds/win32-x64/winpty-agent.pdb +0 -0
- package/prebuilds/win32-x64/winpty.dll +0 -0
- package/prebuilds/win32-x64/winpty.pdb +0 -0
- package/scripts/gen-compile-commands.js +8 -0
- package/scripts/increment-version.js +54 -0
- package/scripts/post-install.js +99 -0
- package/scripts/prebuild.js +39 -0
- package/scripts/sync-prebuild.js +31 -0
- package/scripts/verify-darwin-fd-leak.js +63 -0
- package/src/conpty_console_list_agent.ts +15 -0
- package/src/eventEmitter2.test.ts +30 -0
- package/src/eventEmitter2.ts +48 -0
- package/src/index.ts +52 -0
- package/src/interfaces.ts +130 -0
- package/src/native.d.ts +54 -0
- package/src/shared/conout.ts +15 -0
- package/src/terminal.test.ts +119 -0
- package/src/terminal.ts +211 -0
- package/src/testUtils.test.ts +23 -0
- package/src/tsconfig.json +22 -0
- package/src/types.ts +15 -0
- package/src/unix/pty.cc +808 -0
- package/src/unix/spawn-helper.cc +23 -0
- package/src/unixTerminal.test.ts +367 -0
- package/src/unixTerminal.ts +388 -0
- package/src/utils.ts +29 -0
- package/src/win/conpty.cc +583 -0
- package/src/win/conpty.h +41 -0
- package/src/win/conpty_console_list.cc +44 -0
- package/src/win/path_util.cc +95 -0
- package/src/win/path_util.h +26 -0
- package/src/win/winpty.cc +333 -0
- package/src/windowsConoutConnection.ts +82 -0
- package/src/windowsPtyAgent.test.ts +94 -0
- package/src/windowsPtyAgent.ts +321 -0
- package/src/windowsTerminal.test.ts +229 -0
- package/src/windowsTerminal.ts +203 -0
- package/src/worker/conoutSocketWorker.ts +22 -0
- package/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
- package/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
- package/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
- package/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
- package/typings/node-pty.d.ts +211 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Demonstrates how U+30FC is sometimes handled as a single-width character
|
|
2
|
+
// when it should be handled as a double-width character.
|
|
3
|
+
//
|
|
4
|
+
// It only runs on computers where 932 is a valid code page. Set the system
|
|
5
|
+
// local to "Japanese (Japan)" to ensure this.
|
|
6
|
+
//
|
|
7
|
+
// The problem seems to happen when U+30FC is printed in a console using the
|
|
8
|
+
// Lucida Console font, and only when that font is at certain sizes.
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
#include <windows.h>
|
|
12
|
+
#include <assert.h>
|
|
13
|
+
#include <locale.h>
|
|
14
|
+
#include <stdio.h>
|
|
15
|
+
#include <stdlib.h>
|
|
16
|
+
#include <string.h>
|
|
17
|
+
|
|
18
|
+
#include "TestUtil.cc"
|
|
19
|
+
|
|
20
|
+
#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
|
|
21
|
+
|
|
22
|
+
static void setFont(const wchar_t *faceName, int pxSize) {
|
|
23
|
+
CONSOLE_FONT_INFOEX infoex = {0};
|
|
24
|
+
infoex.cbSize = sizeof(infoex);
|
|
25
|
+
infoex.dwFontSize.Y = pxSize;
|
|
26
|
+
wcsncpy(infoex.FaceName, faceName, COUNT_OF(infoex.FaceName));
|
|
27
|
+
BOOL ret = SetCurrentConsoleFontEx(
|
|
28
|
+
GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &infoex);
|
|
29
|
+
assert(ret);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static bool performTest(const wchar_t testChar) {
|
|
33
|
+
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
34
|
+
|
|
35
|
+
SetConsoleTextAttribute(conout, 7);
|
|
36
|
+
|
|
37
|
+
system("cls");
|
|
38
|
+
DWORD actual = 0;
|
|
39
|
+
BOOL ret = WriteConsoleW(conout, &testChar, 1, &actual, NULL);
|
|
40
|
+
assert(ret && actual == 1);
|
|
41
|
+
|
|
42
|
+
CHAR_INFO verify[2];
|
|
43
|
+
COORD bufSize = {2, 1};
|
|
44
|
+
COORD bufCoord = {0, 0};
|
|
45
|
+
const SMALL_RECT readRegion = {0, 0, 1, 0};
|
|
46
|
+
SMALL_RECT actualRegion = readRegion;
|
|
47
|
+
ret = ReadConsoleOutputW(conout, verify, bufSize, bufCoord, &actualRegion);
|
|
48
|
+
assert(ret && !memcmp(&readRegion, &actualRegion, sizeof(readRegion)));
|
|
49
|
+
assert(verify[0].Char.UnicodeChar == testChar);
|
|
50
|
+
|
|
51
|
+
if (verify[1].Char.UnicodeChar == testChar) {
|
|
52
|
+
// Typical double-width behavior with a TrueType font. Pass.
|
|
53
|
+
assert(verify[0].Attributes == 0x107);
|
|
54
|
+
assert(verify[1].Attributes == 0x207);
|
|
55
|
+
return true;
|
|
56
|
+
} else if (verify[1].Char.UnicodeChar == 0) {
|
|
57
|
+
// Typical double-width behavior with a Raster Font. Pass.
|
|
58
|
+
assert(verify[0].Attributes == 7);
|
|
59
|
+
assert(verify[1].Attributes == 0);
|
|
60
|
+
return true;
|
|
61
|
+
} else if (verify[1].Char.UnicodeChar == L' ') {
|
|
62
|
+
// Single-width behavior. Fail.
|
|
63
|
+
assert(verify[0].Attributes == 7);
|
|
64
|
+
assert(verify[1].Attributes == 7);
|
|
65
|
+
return false;
|
|
66
|
+
} else {
|
|
67
|
+
// Unexpected output.
|
|
68
|
+
assert(false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
int main(int argc, char *argv[]) {
|
|
73
|
+
setlocale(LC_ALL, "");
|
|
74
|
+
if (argc == 1) {
|
|
75
|
+
startChildProcess(L"CHILD");
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
assert(SetConsoleCP(932));
|
|
80
|
+
assert(SetConsoleOutputCP(932));
|
|
81
|
+
|
|
82
|
+
const wchar_t testChar = 0x30FC;
|
|
83
|
+
const wchar_t *const faceNames[] = {
|
|
84
|
+
L"Lucida Console",
|
|
85
|
+
L"Consolas",
|
|
86
|
+
L"MS ゴシック",
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
trace("Test started");
|
|
90
|
+
|
|
91
|
+
for (auto faceName : faceNames) {
|
|
92
|
+
for (int px = 1; px <= 50; ++px) {
|
|
93
|
+
setFont(faceName, px);
|
|
94
|
+
if (!performTest(testChar)) {
|
|
95
|
+
trace("FAILURE: %s %dpx", narrowString(faceName).c_str(), px);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
trace("Test complete");
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
#include <windows.h>
|
|
2
|
+
|
|
3
|
+
#include <assert.h>
|
|
4
|
+
#include <vector>
|
|
5
|
+
|
|
6
|
+
#include "TestUtil.cc"
|
|
7
|
+
|
|
8
|
+
#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
CHAR_INFO ci(wchar_t ch, WORD attributes) {
|
|
12
|
+
CHAR_INFO ret;
|
|
13
|
+
ret.Char.UnicodeChar = ch;
|
|
14
|
+
ret.Attributes = attributes;
|
|
15
|
+
return ret;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
CHAR_INFO ci(wchar_t ch) {
|
|
19
|
+
return ci(ch, 7);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
CHAR_INFO ci() {
|
|
23
|
+
return ci(L' ');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
bool operator==(SMALL_RECT x, SMALL_RECT y) {
|
|
27
|
+
return !memcmp(&x, &y, sizeof(x));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
SMALL_RECT sr(COORD pt, COORD size) {
|
|
31
|
+
return {
|
|
32
|
+
pt.X, pt.Y,
|
|
33
|
+
static_cast<SHORT>(pt.X + size.X - 1),
|
|
34
|
+
static_cast<SHORT>(pt.Y + size.Y - 1)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static void set(
|
|
39
|
+
const COORD pt,
|
|
40
|
+
const COORD size,
|
|
41
|
+
const std::vector<CHAR_INFO> &data) {
|
|
42
|
+
assert(data.size() == size.X * size.Y);
|
|
43
|
+
SMALL_RECT writeRegion = sr(pt, size);
|
|
44
|
+
BOOL ret = WriteConsoleOutputW(
|
|
45
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
46
|
+
data.data(), size, {0, 0}, &writeRegion);
|
|
47
|
+
assert(ret && writeRegion == sr(pt, size));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static void set(
|
|
51
|
+
const COORD pt,
|
|
52
|
+
const std::vector<CHAR_INFO> &data) {
|
|
53
|
+
set(pt, {static_cast<SHORT>(data.size()), 1}, data);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void writeAttrsAt(
|
|
57
|
+
const COORD pt,
|
|
58
|
+
const std::vector<WORD> &data) {
|
|
59
|
+
DWORD actual = 0;
|
|
60
|
+
BOOL ret = WriteConsoleOutputAttribute(
|
|
61
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
62
|
+
data.data(), data.size(), pt, &actual);
|
|
63
|
+
assert(ret && actual == data.size());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static void writeCharsAt(
|
|
67
|
+
const COORD pt,
|
|
68
|
+
const std::vector<wchar_t> &data) {
|
|
69
|
+
DWORD actual = 0;
|
|
70
|
+
BOOL ret = WriteConsoleOutputCharacterW(
|
|
71
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
72
|
+
data.data(), data.size(), pt, &actual);
|
|
73
|
+
assert(ret && actual == data.size());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static void writeChars(
|
|
77
|
+
const std::vector<wchar_t> &data) {
|
|
78
|
+
DWORD actual = 0;
|
|
79
|
+
BOOL ret = WriteConsoleW(
|
|
80
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
81
|
+
data.data(), data.size(), &actual, NULL);
|
|
82
|
+
assert(ret && actual == data.size());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
std::vector<CHAR_INFO> get(
|
|
86
|
+
const COORD pt,
|
|
87
|
+
const COORD size) {
|
|
88
|
+
std::vector<CHAR_INFO> data(size.X * size.Y);
|
|
89
|
+
SMALL_RECT readRegion = sr(pt, size);
|
|
90
|
+
BOOL ret = ReadConsoleOutputW(
|
|
91
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
92
|
+
data.data(), size, {0, 0}, &readRegion);
|
|
93
|
+
assert(ret && readRegion == sr(pt, size));
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
std::vector<wchar_t> readCharsAt(
|
|
98
|
+
const COORD pt,
|
|
99
|
+
int size) {
|
|
100
|
+
std::vector<wchar_t> data(size);
|
|
101
|
+
DWORD actual = 0;
|
|
102
|
+
BOOL ret = ReadConsoleOutputCharacterW(
|
|
103
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
104
|
+
data.data(), data.size(), pt, &actual);
|
|
105
|
+
assert(ret);
|
|
106
|
+
data.resize(actual); // With double-width chars, we can read fewer than `size`.
|
|
107
|
+
return data;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static void dump(const COORD pt, const COORD size) {
|
|
111
|
+
for (CHAR_INFO ci : get(pt, size)) {
|
|
112
|
+
printf("%04X %04X\n", ci.Char.UnicodeChar, ci.Attributes);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static void dumpCharsAt(const COORD pt, int size) {
|
|
117
|
+
for (wchar_t ch : readCharsAt(pt, size)) {
|
|
118
|
+
printf("%04X\n", ch);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static COORD getCursorPos() {
|
|
123
|
+
CONSOLE_SCREEN_BUFFER_INFO info = { sizeof(info) };
|
|
124
|
+
assert(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info));
|
|
125
|
+
return info.dwCursorPosition;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static void test1() {
|
|
129
|
+
// We write "䀀䀀", then write "䀁" in the middle of the two. The second
|
|
130
|
+
// write turns the first and last cells into spaces. The LEADING/TRAILING
|
|
131
|
+
// flags retain consistency.
|
|
132
|
+
printf("test1 - overlap full-width char with full-width char\n");
|
|
133
|
+
writeCharsAt({1,0}, {0x4000, 0x4000});
|
|
134
|
+
dump({0,0}, {6,1});
|
|
135
|
+
printf("\n");
|
|
136
|
+
writeCharsAt({2,0}, {0x4001});
|
|
137
|
+
dump({0,0}, {6,1});
|
|
138
|
+
printf("\n");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static void test2() {
|
|
142
|
+
// Like `test1`, but use a lower-level API to do the write. Consistency is
|
|
143
|
+
// preserved here too -- the first and last cells are replaced with spaces.
|
|
144
|
+
printf("test2 - overlap full-width char with full-width char (lowlevel)\n");
|
|
145
|
+
writeCharsAt({1,0}, {0x4000, 0x4000});
|
|
146
|
+
dump({0,0}, {6,1});
|
|
147
|
+
printf("\n");
|
|
148
|
+
set({2,0}, {ci(0x4001,0x107), ci(0x4001,0x207)});
|
|
149
|
+
dump({0,0}, {6,1});
|
|
150
|
+
printf("\n");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static void test3() {
|
|
154
|
+
// However, the lower-level API can break the LEADING/TRAILING invariant
|
|
155
|
+
// explicitly:
|
|
156
|
+
printf("test3 - explicitly violate LEADING/TRAILING using lowlevel API\n");
|
|
157
|
+
set({1,0}, {
|
|
158
|
+
ci(0x4000, 0x207),
|
|
159
|
+
ci(0x4001, 0x107),
|
|
160
|
+
ci(0x3044, 7),
|
|
161
|
+
ci(L'X', 0x107),
|
|
162
|
+
ci(L'X', 0x207),
|
|
163
|
+
});
|
|
164
|
+
dump({0,0}, {7,1});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static void test4() {
|
|
168
|
+
// It is possible for the two cells of a double-width character to have two
|
|
169
|
+
// colors.
|
|
170
|
+
printf("test4 - use lowlevel to assign two colors to one full-width char\n");
|
|
171
|
+
set({0,0}, {
|
|
172
|
+
ci(0x4000, 0x142),
|
|
173
|
+
ci(0x4000, 0x224),
|
|
174
|
+
});
|
|
175
|
+
dump({0,0}, {2,1});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static void test5() {
|
|
179
|
+
// WriteConsoleOutputAttribute doesn't seem to affect the LEADING/TRAILING
|
|
180
|
+
// flags.
|
|
181
|
+
printf("test5 - WriteConsoleOutputAttribute cannot affect LEADING/TRAILING\n");
|
|
182
|
+
|
|
183
|
+
// Trying to clear the flags doesn't work...
|
|
184
|
+
writeCharsAt({0,0}, {0x4000});
|
|
185
|
+
dump({0,0}, {2,1});
|
|
186
|
+
writeAttrsAt({0,0}, {0x42, 0x24});
|
|
187
|
+
printf("\n");
|
|
188
|
+
dump({0,0}, {2,1});
|
|
189
|
+
|
|
190
|
+
// ... and trying to add them also doesn't work.
|
|
191
|
+
writeCharsAt({0,1}, {'A', ' '});
|
|
192
|
+
writeAttrsAt({0,1}, {0x107, 0x207});
|
|
193
|
+
printf("\n");
|
|
194
|
+
dump({0,1}, {2,1});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
static void test6() {
|
|
198
|
+
// The cursor position may be on either cell of a double-width character.
|
|
199
|
+
// Visually, the cursor appears under both cells, regardless of which
|
|
200
|
+
// specific one has the cursor.
|
|
201
|
+
printf("test6 - cursor can be either left or right cell of full-width char\n");
|
|
202
|
+
|
|
203
|
+
writeCharsAt({2,1}, {0x4000});
|
|
204
|
+
|
|
205
|
+
setCursorPos(2, 1);
|
|
206
|
+
auto pos1 = getCursorPos();
|
|
207
|
+
Sleep(1000);
|
|
208
|
+
|
|
209
|
+
setCursorPos(3, 1);
|
|
210
|
+
auto pos2 = getCursorPos();
|
|
211
|
+
Sleep(1000);
|
|
212
|
+
|
|
213
|
+
setCursorPos(0, 15);
|
|
214
|
+
printf("%d,%d\n", pos1.X, pos1.Y);
|
|
215
|
+
printf("%d,%d\n", pos2.X, pos2.Y);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static void runTest(void (&test)()) {
|
|
219
|
+
system("cls");
|
|
220
|
+
setCursorPos(0, 14);
|
|
221
|
+
test();
|
|
222
|
+
system("pause");
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
int main(int argc, char *argv[]) {
|
|
226
|
+
if (argc == 1) {
|
|
227
|
+
startChildProcess(L"CHILD");
|
|
228
|
+
return 0;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
setWindowPos(0, 0, 1, 1);
|
|
232
|
+
setBufferSize(80, 40);
|
|
233
|
+
setWindowPos(0, 0, 80, 40);
|
|
234
|
+
|
|
235
|
+
auto cp = GetConsoleOutputCP();
|
|
236
|
+
assert(cp == 932 || cp == 936 || cp == 949 || cp == 950);
|
|
237
|
+
|
|
238
|
+
runTest(test1);
|
|
239
|
+
runTest(test2);
|
|
240
|
+
runTest(test3);
|
|
241
|
+
runTest(test4);
|
|
242
|
+
runTest(test5);
|
|
243
|
+
runTest(test6);
|
|
244
|
+
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Test half-width vs full-width characters.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#include <windows.h>
|
|
6
|
+
#include <assert.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
|
|
10
|
+
#include "TestUtil.cc"
|
|
11
|
+
|
|
12
|
+
static void writeChars(const wchar_t *text) {
|
|
13
|
+
wcslen(text);
|
|
14
|
+
const int len = wcslen(text);
|
|
15
|
+
DWORD actual = 0;
|
|
16
|
+
BOOL ret = WriteConsoleW(
|
|
17
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
18
|
+
text, len, &actual, NULL);
|
|
19
|
+
trace("writeChars: ret=%d, actual=%lld", ret, (long long)actual);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static void dumpChars(int x, int y, int w, int h) {
|
|
23
|
+
BOOL ret;
|
|
24
|
+
const COORD bufSize = {w, h};
|
|
25
|
+
const COORD bufCoord = {0, 0};
|
|
26
|
+
const SMALL_RECT topLeft = {x, y, x + w - 1, y + h - 1};
|
|
27
|
+
CHAR_INFO mbcsData[w * h];
|
|
28
|
+
CHAR_INFO unicodeData[w * h];
|
|
29
|
+
SMALL_RECT readRegion;
|
|
30
|
+
readRegion = topLeft;
|
|
31
|
+
ret = ReadConsoleOutputW(GetStdHandle(STD_OUTPUT_HANDLE), unicodeData,
|
|
32
|
+
bufSize, bufCoord, &readRegion);
|
|
33
|
+
assert(ret);
|
|
34
|
+
readRegion = topLeft;
|
|
35
|
+
ret = ReadConsoleOutputA(GetStdHandle(STD_OUTPUT_HANDLE), mbcsData,
|
|
36
|
+
bufSize, bufCoord, &readRegion);
|
|
37
|
+
assert(ret);
|
|
38
|
+
|
|
39
|
+
printf("\n");
|
|
40
|
+
for (int i = 0; i < w * h; ++i) {
|
|
41
|
+
printf("(%02d,%02d) CHAR: %04x %4x -- %02x %4x\n",
|
|
42
|
+
x + i % w, y + i / w,
|
|
43
|
+
(unsigned short)unicodeData[i].Char.UnicodeChar,
|
|
44
|
+
(unsigned short)unicodeData[i].Attributes,
|
|
45
|
+
(unsigned char)mbcsData[i].Char.AsciiChar,
|
|
46
|
+
(unsigned short)mbcsData[i].Attributes);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
int main(int argc, char *argv[]) {
|
|
51
|
+
system("cls");
|
|
52
|
+
setWindowPos(0, 0, 1, 1);
|
|
53
|
+
setBufferSize(80, 38);
|
|
54
|
+
setWindowPos(0, 0, 80, 38);
|
|
55
|
+
|
|
56
|
+
// Write text.
|
|
57
|
+
const wchar_t text1[] = {
|
|
58
|
+
0x3044, // U+3044 (HIRAGANA LETTER I)
|
|
59
|
+
0x2014, // U+2014 (EM DASH)
|
|
60
|
+
0x3044, // U+3044 (HIRAGANA LETTER I)
|
|
61
|
+
0xFF2D, // U+FF2D (FULLWIDTH LATIN CAPITAL LETTER M)
|
|
62
|
+
0x30FC, // U+30FC (KATAKANA-HIRAGANA PROLONGED SOUND MARK)
|
|
63
|
+
0x0031, // U+3031 (DIGIT ONE)
|
|
64
|
+
0x2014, // U+2014 (EM DASH)
|
|
65
|
+
0x0032, // U+0032 (DIGIT TWO)
|
|
66
|
+
0x005C, // U+005C (REVERSE SOLIDUS)
|
|
67
|
+
0x3044, // U+3044 (HIRAGANA LETTER I)
|
|
68
|
+
0
|
|
69
|
+
};
|
|
70
|
+
setCursorPos(0, 0);
|
|
71
|
+
writeChars(text1);
|
|
72
|
+
|
|
73
|
+
setCursorPos(78, 1);
|
|
74
|
+
writeChars(L"<>");
|
|
75
|
+
|
|
76
|
+
const wchar_t text2[] = {
|
|
77
|
+
0x0032, // U+3032 (DIGIT TWO)
|
|
78
|
+
0x3044, // U+3044 (HIRAGANA LETTER I)
|
|
79
|
+
0,
|
|
80
|
+
};
|
|
81
|
+
setCursorPos(78, 1);
|
|
82
|
+
writeChars(text2);
|
|
83
|
+
|
|
84
|
+
system("pause");
|
|
85
|
+
|
|
86
|
+
dumpChars(0, 0, 17, 1);
|
|
87
|
+
dumpChars(2, 0, 2, 1);
|
|
88
|
+
dumpChars(2, 0, 1, 1);
|
|
89
|
+
dumpChars(3, 0, 1, 1);
|
|
90
|
+
dumpChars(78, 1, 2, 1);
|
|
91
|
+
dumpChars(0, 2, 2, 1);
|
|
92
|
+
|
|
93
|
+
system("pause");
|
|
94
|
+
system("cls");
|
|
95
|
+
|
|
96
|
+
const wchar_t text3[] = {
|
|
97
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 1
|
|
98
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 2
|
|
99
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 3
|
|
100
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 4
|
|
101
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 5
|
|
102
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 6
|
|
103
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 7
|
|
104
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 8
|
|
105
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 9
|
|
106
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 10
|
|
107
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 11
|
|
108
|
+
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 12
|
|
109
|
+
L'\r', '\n',
|
|
110
|
+
L'\r', '\n',
|
|
111
|
+
0
|
|
112
|
+
};
|
|
113
|
+
writeChars(text3);
|
|
114
|
+
system("pause");
|
|
115
|
+
{
|
|
116
|
+
const COORD bufSize = {80, 2};
|
|
117
|
+
const COORD bufCoord = {0, 0};
|
|
118
|
+
SMALL_RECT readRegion = {0, 0, 79, 1};
|
|
119
|
+
CHAR_INFO unicodeData[160];
|
|
120
|
+
BOOL ret = ReadConsoleOutputW(GetStdHandle(STD_OUTPUT_HANDLE), unicodeData,
|
|
121
|
+
bufSize, bufCoord, &readRegion);
|
|
122
|
+
assert(ret);
|
|
123
|
+
for (int i = 0; i < 96; ++i) {
|
|
124
|
+
printf("%04x ", unicodeData[i].Char.UnicodeChar);
|
|
125
|
+
}
|
|
126
|
+
printf("\n");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Unix test code that puts the terminal into raw mode, then echos typed
|
|
3
|
+
* characters to stdout. Derived from sample code in the Stevens book, posted
|
|
4
|
+
* online at http://www.lafn.org/~dave/linux/terminalIO.html.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#include <termios.h>
|
|
8
|
+
#include <unistd.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include "FormatChar.h"
|
|
12
|
+
|
|
13
|
+
static struct termios save_termios;
|
|
14
|
+
static int term_saved;
|
|
15
|
+
|
|
16
|
+
/* RAW! mode */
|
|
17
|
+
int tty_raw(int fd)
|
|
18
|
+
{
|
|
19
|
+
struct termios buf;
|
|
20
|
+
|
|
21
|
+
if (tcgetattr(fd, &save_termios) < 0) /* get the original state */
|
|
22
|
+
return -1;
|
|
23
|
+
|
|
24
|
+
buf = save_termios;
|
|
25
|
+
|
|
26
|
+
/* echo off, canonical mode off, extended input
|
|
27
|
+
processing off, signal chars off */
|
|
28
|
+
buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
|
29
|
+
|
|
30
|
+
/* no SIGINT on BREAK, CR-to-NL off, input parity
|
|
31
|
+
check off, don't strip the 8th bit on input,
|
|
32
|
+
ouput flow control off */
|
|
33
|
+
buf.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON);
|
|
34
|
+
|
|
35
|
+
/* clear size bits, parity checking off */
|
|
36
|
+
buf.c_cflag &= ~(CSIZE | PARENB);
|
|
37
|
+
|
|
38
|
+
/* set 8 bits/char */
|
|
39
|
+
buf.c_cflag |= CS8;
|
|
40
|
+
|
|
41
|
+
/* output processing off */
|
|
42
|
+
buf.c_oflag &= ~(OPOST);
|
|
43
|
+
|
|
44
|
+
buf.c_cc[VMIN] = 1; /* 1 byte at a time */
|
|
45
|
+
buf.c_cc[VTIME] = 0; /* no timer on input */
|
|
46
|
+
|
|
47
|
+
if (tcsetattr(fd, TCSAFLUSH, &buf) < 0)
|
|
48
|
+
return -1;
|
|
49
|
+
|
|
50
|
+
term_saved = 1;
|
|
51
|
+
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/* set it to normal! */
|
|
57
|
+
int tty_reset(int fd)
|
|
58
|
+
{
|
|
59
|
+
if (term_saved)
|
|
60
|
+
if (tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
|
|
61
|
+
return -1;
|
|
62
|
+
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
int main()
|
|
68
|
+
{
|
|
69
|
+
tty_raw(0);
|
|
70
|
+
|
|
71
|
+
int count = 0;
|
|
72
|
+
while (true) {
|
|
73
|
+
char ch;
|
|
74
|
+
char buf[16];
|
|
75
|
+
int actual = read(0, &ch, 1);
|
|
76
|
+
if (actual != 1) {
|
|
77
|
+
perror("read error");
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
formatChar(buf, ch);
|
|
81
|
+
fputs(buf, stdout);
|
|
82
|
+
fflush(stdout);
|
|
83
|
+
if (ch == 3) // Ctrl-C
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
tty_reset(0);
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#include <windows.h>
|
|
2
|
+
#include <assert.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
|
|
6
|
+
#include <vector>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
int main(int argc, char *argv[]) {
|
|
10
|
+
system("cls");
|
|
11
|
+
|
|
12
|
+
if (argc == 1) {
|
|
13
|
+
printf("Usage: %s hhhh\n", argv[0]);
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
std::wstring dataToWrite;
|
|
18
|
+
for (int i = 1; i < argc; ++i) {
|
|
19
|
+
wchar_t ch = strtol(argv[i], NULL, 16);
|
|
20
|
+
dataToWrite.push_back(ch);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
DWORD actual = 0;
|
|
24
|
+
BOOL ret = WriteConsoleW(
|
|
25
|
+
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
26
|
+
dataToWrite.data(), dataToWrite.size(), &actual, NULL);
|
|
27
|
+
assert(ret && actual == dataToWrite.size());
|
|
28
|
+
|
|
29
|
+
// Read it back.
|
|
30
|
+
std::vector<CHAR_INFO> readBuffer(dataToWrite.size() * 2);
|
|
31
|
+
COORD bufSize = {static_cast<short>(readBuffer.size()), 1};
|
|
32
|
+
COORD bufCoord = {0, 0};
|
|
33
|
+
SMALL_RECT topLeft = {0, 0, static_cast<short>(readBuffer.size() - 1), 0};
|
|
34
|
+
ret = ReadConsoleOutputW(
|
|
35
|
+
GetStdHandle(STD_OUTPUT_HANDLE), readBuffer.data(),
|
|
36
|
+
bufSize, bufCoord, &topLeft);
|
|
37
|
+
assert(ret);
|
|
38
|
+
|
|
39
|
+
printf("\n");
|
|
40
|
+
for (int i = 0; i < readBuffer.size(); ++i) {
|
|
41
|
+
printf("CHAR: %04x %04x\n",
|
|
42
|
+
readBuffer[i].Char.UnicodeChar,
|
|
43
|
+
readBuffer[i].Attributes);
|
|
44
|
+
}
|
|
45
|
+
return 0;
|
|
46
|
+
}
|