Remove ws module from edge-agent dependencies
This commit is contained in:
-21
@@ -18,27 +18,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-addon-api": "^7.1.0"
|
"node-addon-api": "^7.1.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"node_modules/ws": {
|
|
||||||
"version": "8.20.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
|
|
||||||
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": ">=5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017 [Node.js API collaborators](https://github.com/nodejs/node-addon-api#collaborators)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
+319
@@ -0,0 +1,319 @@
|
|||||||
|
NOTE: The default branch has been renamed!
|
||||||
|
master is now named main
|
||||||
|
|
||||||
|
If you have a local clone, you can update it by running:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git branch -m master main
|
||||||
|
git fetch origin
|
||||||
|
git branch -u origin/main main
|
||||||
|
```
|
||||||
|
|
||||||
|
# **node-addon-api module**
|
||||||
|
This module contains **header-only C++ wrapper classes** which simplify
|
||||||
|
the use of the C based [Node-API](https://nodejs.org/dist/latest/docs/api/n-api.html)
|
||||||
|
provided by Node.js when using C++. It provides a C++ object model
|
||||||
|
and exception handling semantics with low overhead.
|
||||||
|
|
||||||
|
There are three options for implementing addons: Node-API, nan, or direct
|
||||||
|
use of internal V8, libuv, and Node.js libraries. Unless there is a need for
|
||||||
|
direct access to functionality that is not exposed by Node-API as outlined
|
||||||
|
in [C/C++ addons](https://nodejs.org/dist/latest/docs/api/addons.html)
|
||||||
|
in Node.js core, use Node-API. Refer to
|
||||||
|
[C/C++ addons with Node-API](https://nodejs.org/dist/latest/docs/api/n-api.html)
|
||||||
|
for more information on Node-API.
|
||||||
|
|
||||||
|
Node-API is an ABI stable C interface provided by Node.js for building native
|
||||||
|
addons. It is independent of the underlying JavaScript runtime (e.g. V8 or ChakraCore)
|
||||||
|
and is maintained as part of Node.js itself. It is intended to insulate
|
||||||
|
native addons from changes in the underlying JavaScript engine and allow
|
||||||
|
modules compiled for one version to run on later versions of Node.js without
|
||||||
|
recompilation.
|
||||||
|
|
||||||
|
The `node-addon-api` module, which is not part of Node.js, preserves the benefits
|
||||||
|
of the Node-API as it consists only of inline code that depends only on the stable API
|
||||||
|
provided by Node-API. As such, modules built against one version of Node.js
|
||||||
|
using node-addon-api should run without having to be rebuilt with newer versions
|
||||||
|
of Node.js.
|
||||||
|
|
||||||
|
It is important to remember that *other* Node.js interfaces such as
|
||||||
|
`libuv` (included in a project via `#include <uv.h>`) are not ABI-stable across
|
||||||
|
Node.js major versions. Thus, an addon must use Node-API and/or `node-addon-api`
|
||||||
|
exclusively and build against a version of Node.js that includes an
|
||||||
|
implementation of Node-API (meaning an active LTS version of Node.js) in
|
||||||
|
order to benefit from ABI stability across Node.js major versions. Node.js
|
||||||
|
provides an [ABI stability guide][] containing a detailed explanation of ABI
|
||||||
|
stability in general, and the Node-API ABI stability guarantee in particular.
|
||||||
|
|
||||||
|
As new APIs are added to Node-API, node-addon-api must be updated to provide
|
||||||
|
wrappers for those new APIs. For this reason, node-addon-api provides
|
||||||
|
methods that allow callers to obtain the underlying Node-API handles so
|
||||||
|
direct calls to Node-API and the use of the objects/methods provided by
|
||||||
|
node-addon-api can be used together. For example, in order to be able
|
||||||
|
to use an API for which the node-addon-api does not yet provide a wrapper.
|
||||||
|
|
||||||
|
APIs exposed by node-addon-api are generally used to create and
|
||||||
|
manipulate JavaScript values. Concepts and operations generally map
|
||||||
|
to ideas specified in the **ECMA262 Language Specification**.
|
||||||
|
|
||||||
|
The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers an
|
||||||
|
excellent orientation and tips for developers just getting started with Node-API
|
||||||
|
and node-addon-api.
|
||||||
|
|
||||||
|
- **[Setup](#setup)**
|
||||||
|
- **[API Documentation](#api)**
|
||||||
|
- **[Examples](#examples)**
|
||||||
|
- **[Tests](#tests)**
|
||||||
|
- **[More resource and info about native Addons](#resources)**
|
||||||
|
- **[Badges](#badges)**
|
||||||
|
- **[Code of Conduct](CODE_OF_CONDUCT.md)**
|
||||||
|
- **[Contributors](#contributors)**
|
||||||
|
- **[License](#license)**
|
||||||
|
|
||||||
|
## **Current version: 7.1.1**
|
||||||
|
|
||||||
|
(See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
|
||||||
|
|
||||||
|
[](https://nodei.co/npm/node-addon-api/) [](https://nodei.co/npm/node-addon-api/)
|
||||||
|
|
||||||
|
<a name="setup"></a>
|
||||||
|
|
||||||
|
node-addon-api is based on [Node-API](https://nodejs.org/api/n-api.html) and supports using different Node-API versions.
|
||||||
|
This allows addons built with it to run with Node.js versions which support the targeted Node-API version.
|
||||||
|
**However** the node-addon-api support model is to support only the active LTS Node.js versions. This means that
|
||||||
|
every year there will be a new major which drops support for the Node.js LTS version which has gone out of service.
|
||||||
|
|
||||||
|
The oldest Node.js version supported by the current version of node-addon-api is Node.js 16.x.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
- [Installation and usage](doc/setup.md)
|
||||||
|
- [node-gyp](doc/node-gyp.md)
|
||||||
|
- [cmake-js](doc/cmake-js.md)
|
||||||
|
- [Conversion tool](doc/conversion-tool.md)
|
||||||
|
- [Checker tool](doc/checker-tool.md)
|
||||||
|
- [Generator](doc/generator.md)
|
||||||
|
- [Prebuild tools](doc/prebuild_tools.md)
|
||||||
|
|
||||||
|
<a name="api"></a>
|
||||||
|
|
||||||
|
### **API Documentation**
|
||||||
|
|
||||||
|
The following is the documentation for node-addon-api.
|
||||||
|
|
||||||
|
- [Full Class Hierarchy](doc/hierarchy.md)
|
||||||
|
- [Addon Structure](doc/addon.md)
|
||||||
|
- Data Types:
|
||||||
|
- [Env](doc/env.md)
|
||||||
|
- [CallbackInfo](doc/callbackinfo.md)
|
||||||
|
- [Reference](doc/reference.md)
|
||||||
|
- [Value](doc/value.md)
|
||||||
|
- [Name](doc/name.md)
|
||||||
|
- [Symbol](doc/symbol.md)
|
||||||
|
- [String](doc/string.md)
|
||||||
|
- [Number](doc/number.md)
|
||||||
|
- [Date](doc/date.md)
|
||||||
|
- [BigInt](doc/bigint.md)
|
||||||
|
- [Boolean](doc/boolean.md)
|
||||||
|
- [External](doc/external.md)
|
||||||
|
- [Object](doc/object.md)
|
||||||
|
- [Array](doc/array.md)
|
||||||
|
- [ObjectReference](doc/object_reference.md)
|
||||||
|
- [PropertyDescriptor](doc/property_descriptor.md)
|
||||||
|
- [Function](doc/function.md)
|
||||||
|
- [FunctionReference](doc/function_reference.md)
|
||||||
|
- [ObjectWrap](doc/object_wrap.md)
|
||||||
|
- [ClassPropertyDescriptor](doc/class_property_descriptor.md)
|
||||||
|
- [Buffer](doc/buffer.md)
|
||||||
|
- [ArrayBuffer](doc/array_buffer.md)
|
||||||
|
- [TypedArray](doc/typed_array.md)
|
||||||
|
- [TypedArrayOf](doc/typed_array_of.md)
|
||||||
|
- [DataView](doc/dataview.md)
|
||||||
|
- [Error Handling](doc/error_handling.md)
|
||||||
|
- [Error](doc/error.md)
|
||||||
|
- [TypeError](doc/type_error.md)
|
||||||
|
- [RangeError](doc/range_error.md)
|
||||||
|
- [SyntaxError](doc/syntax_error.md)
|
||||||
|
- [Object Lifetime Management](doc/object_lifetime_management.md)
|
||||||
|
- [HandleScope](doc/handle_scope.md)
|
||||||
|
- [EscapableHandleScope](doc/escapable_handle_scope.md)
|
||||||
|
- [Memory Management](doc/memory_management.md)
|
||||||
|
- [Async Operations](doc/async_operations.md)
|
||||||
|
- [AsyncWorker](doc/async_worker.md)
|
||||||
|
- [AsyncContext](doc/async_context.md)
|
||||||
|
- [AsyncWorker Variants](doc/async_worker_variants.md)
|
||||||
|
- [Thread-safe Functions](doc/threadsafe.md)
|
||||||
|
- [ThreadSafeFunction](doc/threadsafe_function.md)
|
||||||
|
- [TypedThreadSafeFunction](doc/typed_threadsafe_function.md)
|
||||||
|
- [Promises](doc/promises.md)
|
||||||
|
- [Version management](doc/version_management.md)
|
||||||
|
|
||||||
|
<a name="examples"></a>
|
||||||
|
|
||||||
|
### **Examples**
|
||||||
|
|
||||||
|
Are you new to **node-addon-api**? Take a look at our **[examples](https://github.com/nodejs/node-addon-examples)**
|
||||||
|
|
||||||
|
- **[Hello World](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/1_hello_world)**
|
||||||
|
- **[Pass arguments to a function](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/2_function_arguments/node-addon-api)**
|
||||||
|
- **[Callbacks](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/3_callbacks/node-addon-api)**
|
||||||
|
- **[Object factory](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/4_object_factory/node-addon-api)**
|
||||||
|
- **[Function factory](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/5_function_factory/node-addon-api)**
|
||||||
|
- **[Wrapping C++ Object](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/6_object_wrap/node-addon-api)**
|
||||||
|
- **[Factory of wrapped object](https://github.com/nodejs/node-addon-examples/tree/main/src/1-getting-started/7_factory_wrap/node-addon-api)**
|
||||||
|
- **[Passing wrapped object around](https://github.com/nodejs/node-addon-examples/tree/main/src/2-js-to-native-conversion/8_passing_wrapped/node-addon-api)**
|
||||||
|
|
||||||
|
<a name="tests"></a>
|
||||||
|
|
||||||
|
### **Tests**
|
||||||
|
|
||||||
|
To run the **node-addon-api** tests do:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
To avoid testing the deprecated portions of the API run
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
npm test --disable-deprecated
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the tests targeting a specific version of Node-API run
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
export NAPI_VERSION=X
|
||||||
|
npm test --NAPI_VERSION=X
|
||||||
|
```
|
||||||
|
|
||||||
|
where X is the version of Node-API you want to target.
|
||||||
|
|
||||||
|
To run a specific unit test, filter conditions are available
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
compile and run only tests on objectwrap.cc and objectwrap.js
|
||||||
|
```
|
||||||
|
npm run unit --filter=objectwrap
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple unit tests cane be selected with wildcards
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
compile and run all test files ending with "reference" -> function_reference.cc, object_reference.cc, reference.cc
|
||||||
|
```
|
||||||
|
npm run unit --filter=*reference
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple filter conditions can be joined to broaden the test selection
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
compile and run all tests under folders threadsafe_function and typed_threadsafe_function and also the objectwrap.cc file
|
||||||
|
npm run unit --filter='*function objectwrap'
|
||||||
|
|
||||||
|
### **Debug**
|
||||||
|
|
||||||
|
To run the **node-addon-api** tests with `--debug` option:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run-script dev
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want a faster build, you might use the following option:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run-script dev:incremental
|
||||||
|
```
|
||||||
|
|
||||||
|
Take a look and get inspired by our **[test suite](https://github.com/nodejs/node-addon-api/tree/HEAD/test)**
|
||||||
|
|
||||||
|
### **Benchmarks**
|
||||||
|
|
||||||
|
You can run the available benchmarks using the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run-script benchmark
|
||||||
|
```
|
||||||
|
|
||||||
|
See [benchmark/README.md](benchmark/README.md) for more details about running and adding benchmarks.
|
||||||
|
|
||||||
|
<a name="resources"></a>
|
||||||
|
|
||||||
|
### **More resource and info about native Addons**
|
||||||
|
- **[C++ Addons](https://nodejs.org/dist/latest/docs/api/addons.html)**
|
||||||
|
- **[Node-API](https://nodejs.org/dist/latest/docs/api/n-api.html)**
|
||||||
|
- **[Node-API - Next Generation Node API for Native Modules](https://youtu.be/-Oniup60Afs)**
|
||||||
|
- **[How We Migrated Realm JavaScript From NAN to Node-API](https://developer.mongodb.com/article/realm-javascript-nan-to-n-api)**
|
||||||
|
|
||||||
|
As node-addon-api's core mission is to expose the plain C Node-API as C++
|
||||||
|
wrappers, tools that facilitate n-api/node-addon-api providing more
|
||||||
|
convenient patterns for developing a Node.js add-on with n-api/node-addon-api
|
||||||
|
can be published to NPM as standalone packages. It is also recommended to tag
|
||||||
|
such packages with `node-addon-api` to provide more visibility to the community.
|
||||||
|
|
||||||
|
Quick links to NPM searches: [keywords:node-addon-api](https://www.npmjs.com/search?q=keywords%3Anode-addon-api).
|
||||||
|
|
||||||
|
<a name="other-bindings"></a>
|
||||||
|
|
||||||
|
### **Other bindings**
|
||||||
|
|
||||||
|
- **[napi-rs](https://napi.rs)** - (`Rust`)
|
||||||
|
|
||||||
|
<a name="badges"></a>
|
||||||
|
|
||||||
|
### **Badges**
|
||||||
|
|
||||||
|
The use of badges is recommended to indicate the minimum version of Node-API
|
||||||
|
required for the module. This helps to determine which Node.js major versions are
|
||||||
|
supported. Addon maintainers can consult the [Node-API support matrix][] to determine
|
||||||
|
which Node.js versions provide a given Node-API version. The following badges are
|
||||||
|
available:
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## **Contributing**
|
||||||
|
|
||||||
|
We love contributions from the community to **node-addon-api**!
|
||||||
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for more details on our philosophy around extending this module.
|
||||||
|
|
||||||
|
<a name="contributors"></a>
|
||||||
|
|
||||||
|
## Team members
|
||||||
|
|
||||||
|
### Active
|
||||||
|
| Name | GitHub Link |
|
||||||
|
| ------------------- | ----------------------------------------------------- |
|
||||||
|
| Anna Henningsen | [addaleax](https://github.com/addaleax) |
|
||||||
|
| Chengzhong Wu | [legendecas](https://github.com/legendecas) |
|
||||||
|
| Jack Xia | [JckXia](https://github.com/JckXia) |
|
||||||
|
| Kevin Eady | [KevinEady](https://github.com/KevinEady) |
|
||||||
|
| Michael Dawson | [mhdawson](https://github.com/mhdawson) |
|
||||||
|
| Nicola Del Gobbo | [NickNaso](https://github.com/NickNaso) |
|
||||||
|
| Vladimir Morozov | [vmoroz](https://github.com/vmoroz) |
|
||||||
|
|
||||||
|
### Emeritus
|
||||||
|
| Name | GitHub Link |
|
||||||
|
| ------------------- | ----------------------------------------------------- |
|
||||||
|
| Arunesh Chandra | [aruneshchandra](https://github.com/aruneshchandra) |
|
||||||
|
| Benjamin Byholm | [kkoopa](https://github.com/kkoopa) |
|
||||||
|
| Gabriel Schulhof | [gabrielschulhof](https://github.com/gabrielschulhof) |
|
||||||
|
| Hitesh Kanwathirtha | [digitalinfinity](https://github.com/digitalinfinity) |
|
||||||
|
| Jason Ginchereau | [jasongin](https://github.com/jasongin) |
|
||||||
|
| Jim Schlight | [jschlight](https://github.com/jschlight) |
|
||||||
|
| Sampson Gao | [sampsongao](https://github.com/sampsongao) |
|
||||||
|
| Taylor Woll | [boingoing](https://github.com/boingoing) |
|
||||||
|
|
||||||
|
<a name="license"></a>
|
||||||
|
|
||||||
|
Licensed under [MIT](./LICENSE.md)
|
||||||
|
|
||||||
|
[ABI stability guide]: https://nodejs.org/en/docs/guides/abi-stability/
|
||||||
|
[Node-API support matrix]: https://nodejs.org/dist/latest/docs/api/n-api.html#n_api_n_api_version_matrix
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
'variables': {
|
||||||
|
'NAPI_VERSION%': "<!(node -p \"process.env.NAPI_VERSION || process.versions.napi\")",
|
||||||
|
'disable_deprecated': "<!(node -p \"process.env['npm_config_disable_deprecated']\")"
|
||||||
|
},
|
||||||
|
'conditions': [
|
||||||
|
['NAPI_VERSION!=""', { 'defines': ['NAPI_VERSION=<@(NAPI_VERSION)'] } ],
|
||||||
|
['disable_deprecated=="true"', {
|
||||||
|
'defines': ['NODE_ADDON_API_DISABLE_DEPRECATED']
|
||||||
|
}],
|
||||||
|
['OS=="mac"', {
|
||||||
|
'cflags+': ['-fvisibility=hidden'],
|
||||||
|
'xcode_settings': {
|
||||||
|
'OTHER_CFLAGS': ['-fvisibility=hidden']
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
],
|
||||||
|
'cflags': [ '-Werror', '-Wall', '-Wextra', '-Wpedantic', '-Wunused-parameter' ],
|
||||||
|
'cflags_cc': [ '-Werror', '-Wall', '-Wextra', '-Wpedantic', '-Wunused-parameter' ]
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
'defines': [ 'NAPI_CPP_EXCEPTIONS' ],
|
||||||
|
'cflags!': [ '-fno-exceptions' ],
|
||||||
|
'cflags_cc!': [ '-fno-exceptions' ],
|
||||||
|
'conditions': [
|
||||||
|
["OS=='win'", {
|
||||||
|
"defines": [
|
||||||
|
"_HAS_EXCEPTIONS=1"
|
||||||
|
],
|
||||||
|
"msvs_settings": {
|
||||||
|
"VCCLCompilerTool": {
|
||||||
|
"ExceptionHandling": 1,
|
||||||
|
'EnablePREfast': 'true',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
["OS=='mac'", {
|
||||||
|
'xcode_settings': {
|
||||||
|
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
||||||
|
'CLANG_CXX_LIBRARY': 'libc++',
|
||||||
|
'MACOSX_DEPLOYMENT_TARGET': '10.7',
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const includeDir = path.relative('.', __dirname);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
include: `"${__dirname}"`, // deprecated, can be removed as part of 4.0.0
|
||||||
|
include_dir: includeDir,
|
||||||
|
gyp: path.join(includeDir, 'node_api.gyp:nothing'), // deprecated.
|
||||||
|
targets: path.join(includeDir, 'node_addon_api.gyp'),
|
||||||
|
isNodeApiBuiltin: true,
|
||||||
|
needsFlag: false
|
||||||
|
};
|
||||||
+186
@@ -0,0 +1,186 @@
|
|||||||
|
#ifndef SRC_NAPI_INL_DEPRECATED_H_
|
||||||
|
#define SRC_NAPI_INL_DEPRECATED_H_
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PropertyDescriptor class
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename Getter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
const char* utf8name,
|
||||||
|
Getter getter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* /*data*/) {
|
||||||
|
using CbData = details::CallbackData<Getter, Napi::Value>;
|
||||||
|
// TODO: Delete when the function is destroyed
|
||||||
|
auto callbackData = new CbData({getter, nullptr});
|
||||||
|
|
||||||
|
return PropertyDescriptor({utf8name,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
CbData::Wrapper,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
attributes,
|
||||||
|
callbackData});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
const std::string& utf8name,
|
||||||
|
Getter getter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* data) {
|
||||||
|
return Accessor(utf8name.c_str(), getter, attributes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
napi_value name,
|
||||||
|
Getter getter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* /*data*/) {
|
||||||
|
using CbData = details::CallbackData<Getter, Napi::Value>;
|
||||||
|
// TODO: Delete when the function is destroyed
|
||||||
|
auto callbackData = new CbData({getter, nullptr});
|
||||||
|
|
||||||
|
return PropertyDescriptor({nullptr,
|
||||||
|
name,
|
||||||
|
nullptr,
|
||||||
|
CbData::Wrapper,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
attributes,
|
||||||
|
callbackData});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
Name name, Getter getter, napi_property_attributes attributes, void* data) {
|
||||||
|
napi_value nameValue = name;
|
||||||
|
return PropertyDescriptor::Accessor(nameValue, getter, attributes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter, typename Setter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
const char* utf8name,
|
||||||
|
Getter getter,
|
||||||
|
Setter setter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* /*data*/) {
|
||||||
|
using CbData = details::AccessorCallbackData<Getter, Setter>;
|
||||||
|
// TODO: Delete when the function is destroyed
|
||||||
|
auto callbackData = new CbData({getter, setter, nullptr});
|
||||||
|
|
||||||
|
return PropertyDescriptor({utf8name,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
CbData::GetterWrapper,
|
||||||
|
CbData::SetterWrapper,
|
||||||
|
nullptr,
|
||||||
|
attributes,
|
||||||
|
callbackData});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter, typename Setter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
const std::string& utf8name,
|
||||||
|
Getter getter,
|
||||||
|
Setter setter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* data) {
|
||||||
|
return Accessor(utf8name.c_str(), getter, setter, attributes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter, typename Setter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
napi_value name,
|
||||||
|
Getter getter,
|
||||||
|
Setter setter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* /*data*/) {
|
||||||
|
using CbData = details::AccessorCallbackData<Getter, Setter>;
|
||||||
|
// TODO: Delete when the function is destroyed
|
||||||
|
auto callbackData = new CbData({getter, setter, nullptr});
|
||||||
|
|
||||||
|
return PropertyDescriptor({nullptr,
|
||||||
|
name,
|
||||||
|
nullptr,
|
||||||
|
CbData::GetterWrapper,
|
||||||
|
CbData::SetterWrapper,
|
||||||
|
nullptr,
|
||||||
|
attributes,
|
||||||
|
callbackData});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Getter, typename Setter>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Accessor(
|
||||||
|
Name name,
|
||||||
|
Getter getter,
|
||||||
|
Setter setter,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* data) {
|
||||||
|
napi_value nameValue = name;
|
||||||
|
return PropertyDescriptor::Accessor(
|
||||||
|
nameValue, getter, setter, attributes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Callable>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Function(
|
||||||
|
const char* utf8name,
|
||||||
|
Callable cb,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* /*data*/) {
|
||||||
|
using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr)));
|
||||||
|
using CbData = details::CallbackData<Callable, ReturnType>;
|
||||||
|
// TODO: Delete when the function is destroyed
|
||||||
|
auto callbackData = new CbData({cb, nullptr});
|
||||||
|
|
||||||
|
return PropertyDescriptor({utf8name,
|
||||||
|
nullptr,
|
||||||
|
CbData::Wrapper,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
attributes,
|
||||||
|
callbackData});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Callable>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Function(
|
||||||
|
const std::string& utf8name,
|
||||||
|
Callable cb,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* data) {
|
||||||
|
return Function(utf8name.c_str(), cb, attributes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Callable>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Function(
|
||||||
|
napi_value name,
|
||||||
|
Callable cb,
|
||||||
|
napi_property_attributes attributes,
|
||||||
|
void* /*data*/) {
|
||||||
|
using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr)));
|
||||||
|
using CbData = details::CallbackData<Callable, ReturnType>;
|
||||||
|
// TODO: Delete when the function is destroyed
|
||||||
|
auto callbackData = new CbData({cb, nullptr});
|
||||||
|
|
||||||
|
return PropertyDescriptor({nullptr,
|
||||||
|
name,
|
||||||
|
CbData::Wrapper,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
attributes,
|
||||||
|
callbackData});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Callable>
|
||||||
|
inline PropertyDescriptor PropertyDescriptor::Function(
|
||||||
|
Name name, Callable cb, napi_property_attributes attributes, void* data) {
|
||||||
|
napi_value nameValue = name;
|
||||||
|
return PropertyDescriptor::Function(nameValue, cb, attributes, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !SRC_NAPI_INL_DEPRECATED_H_
|
||||||
+6607
File diff suppressed because it is too large
Load Diff
+3201
File diff suppressed because it is too large
Load Diff
+32
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'node_addon_api',
|
||||||
|
'type': 'none',
|
||||||
|
'sources': [ 'napi.h', 'napi-inl.h' ],
|
||||||
|
'direct_dependent_settings': {
|
||||||
|
'include_dirs': [ '.' ],
|
||||||
|
'includes': ['noexcept.gypi'],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'node_addon_api_except',
|
||||||
|
'type': 'none',
|
||||||
|
'sources': [ 'napi.h', 'napi-inl.h' ],
|
||||||
|
'direct_dependent_settings': {
|
||||||
|
'include_dirs': [ '.' ],
|
||||||
|
'includes': ['except.gypi'],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'node_addon_api_maybe',
|
||||||
|
'type': 'none',
|
||||||
|
'sources': [ 'napi.h', 'napi-inl.h' ],
|
||||||
|
'direct_dependent_settings': {
|
||||||
|
'include_dirs': [ '.' ],
|
||||||
|
'includes': ['noexcept.gypi'],
|
||||||
|
'defines': ['NODE_ADDON_API_ENABLE_MAYBE']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'nothing',
|
||||||
|
'type': 'static_library',
|
||||||
|
'sources': [ 'nothing.c' ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
|
||||||
|
'cflags': [ '-fno-exceptions' ],
|
||||||
|
'cflags_cc': [ '-fno-exceptions' ],
|
||||||
|
'conditions': [
|
||||||
|
["OS=='win'", {
|
||||||
|
# _HAS_EXCEPTIONS is already defined and set to 0 in common.gypi
|
||||||
|
#"defines": [
|
||||||
|
# "_HAS_EXCEPTIONS=0"
|
||||||
|
#],
|
||||||
|
"msvs_settings": {
|
||||||
|
"VCCLCompilerTool": {
|
||||||
|
'ExceptionHandling': 0,
|
||||||
|
'EnablePREfast': 'true',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
["OS=='mac'", {
|
||||||
|
'xcode_settings': {
|
||||||
|
'CLANG_CXX_LIBRARY': 'libc++',
|
||||||
|
'MACOSX_DEPLOYMENT_TARGET': '10.7',
|
||||||
|
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO',
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"versions": [
|
||||||
|
{
|
||||||
|
"version": "*",
|
||||||
|
"target": {
|
||||||
|
"node": "active"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"type": "time-permitting",
|
||||||
|
"paid": false,
|
||||||
|
"contact": {
|
||||||
|
"name": "node-addon-api team",
|
||||||
|
"url": "https://github.com/nodejs/node-addon-api/issues"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backing": [ { "project": "https://github.com/nodejs" },
|
||||||
|
{ "foundation": "https://openjsf.org/" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+480
@@ -0,0 +1,480 @@
|
|||||||
|
{
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/nodejs/node-addon-api/issues"
|
||||||
|
},
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Abhishek Kumar Singh",
|
||||||
|
"url": "https://github.com/abhi11210646"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Alba Mendez",
|
||||||
|
"url": "https://github.com/jmendeth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Alexander Floh",
|
||||||
|
"url": "https://github.com/alexanderfloh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ammar Faizi",
|
||||||
|
"url": "https://github.com/ammarfaizi2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "András Timár, Dr",
|
||||||
|
"url": "https://github.com/timarandras"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Andrew Petersen",
|
||||||
|
"url": "https://github.com/kirbysayshi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Anisha Rohra",
|
||||||
|
"url": "https://github.com/anisha-rohra"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Anna Henningsen",
|
||||||
|
"url": "https://github.com/addaleax"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Arnaud Botella",
|
||||||
|
"url": "https://github.com/BotellaA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Arunesh Chandra",
|
||||||
|
"url": "https://github.com/aruneshchandra"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Azlan Mukhtar",
|
||||||
|
"url": "https://github.com/azlan"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ben Berman",
|
||||||
|
"url": "https://github.com/rivertam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Byholm",
|
||||||
|
"url": "https://github.com/kkoopa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bill Gallafent",
|
||||||
|
"url": "https://github.com/gallafent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blagoev",
|
||||||
|
"url": "https://github.com/blagoev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bruce A. MacNaughton",
|
||||||
|
"url": "https://github.com/bmacnaughton"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cory Mickelson",
|
||||||
|
"url": "https://github.com/corymickelson"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Daniel Bevenius",
|
||||||
|
"url": "https://github.com/danbev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dante Calderón",
|
||||||
|
"url": "https://github.com/dantehemerson"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Darshan Sen",
|
||||||
|
"url": "https://github.com/RaisinTen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "David Halls",
|
||||||
|
"url": "https://github.com/davedoesdev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Deepak Rajamohan",
|
||||||
|
"url": "https://github.com/deepakrkris"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dmitry Ashkadov",
|
||||||
|
"url": "https://github.com/dmitryash"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dongjin Na",
|
||||||
|
"url": "https://github.com/nadongguri"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Doni Rubiagatra",
|
||||||
|
"url": "https://github.com/rubiagatra"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Eric Bickle",
|
||||||
|
"url": "https://github.com/ebickle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "extremeheat",
|
||||||
|
"url": "https://github.com/extremeheat"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Feng Yu",
|
||||||
|
"url": "https://github.com/F3n67u"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ferdinand Holzer",
|
||||||
|
"url": "https://github.com/fholzer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gabriel Schulhof",
|
||||||
|
"url": "https://github.com/gabrielschulhof"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guenter Sandner",
|
||||||
|
"url": "https://github.com/gms1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gus Caplan",
|
||||||
|
"url": "https://github.com/devsnek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Helio Frota",
|
||||||
|
"url": "https://github.com/helio-frota"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Hitesh Kanwathirtha",
|
||||||
|
"url": "https://github.com/digitalinfinity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ikokostya",
|
||||||
|
"url": "https://github.com/ikokostya"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jack Xia",
|
||||||
|
"url": "https://github.com/JckXia"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jake Barnes",
|
||||||
|
"url": "https://github.com/DuBistKomisch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jake Yoon",
|
||||||
|
"url": "https://github.com/yjaeseok"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jason Ginchereau",
|
||||||
|
"url": "https://github.com/jasongin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jenny",
|
||||||
|
"url": "https://github.com/egg-bread"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jeroen Janssen",
|
||||||
|
"url": "https://github.com/japj"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jim Schlight",
|
||||||
|
"url": "https://github.com/jschlight"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jinho Bang",
|
||||||
|
"url": "https://github.com/romandev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "José Expósito",
|
||||||
|
"url": "https://github.com/JoseExposito"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "joshgarde",
|
||||||
|
"url": "https://github.com/joshgarde"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Julian Mesa",
|
||||||
|
"url": "https://github.com/julianmesa-gitkraken"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kasumi Hanazuki",
|
||||||
|
"url": "https://github.com/hanazuki"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kelvin",
|
||||||
|
"url": "https://github.com/kelvinhammond"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kevin Eady",
|
||||||
|
"url": "https://github.com/KevinEady"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kévin VOYER",
|
||||||
|
"url": "https://github.com/kecsou"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kidneysolo",
|
||||||
|
"url": "https://github.com/kidneysolo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Koki Nishihara",
|
||||||
|
"url": "https://github.com/Nishikoh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Konstantin Tarkus",
|
||||||
|
"url": "https://github.com/koistya"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kyle Farnung",
|
||||||
|
"url": "https://github.com/kfarnung"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kyle Kovacs",
|
||||||
|
"url": "https://github.com/nullromo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "legendecas",
|
||||||
|
"url": "https://github.com/legendecas"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "LongYinan",
|
||||||
|
"url": "https://github.com/Brooooooklyn"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Lovell Fuller",
|
||||||
|
"url": "https://github.com/lovell"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Luciano Martorella",
|
||||||
|
"url": "https://github.com/lmartorella"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mastergberry",
|
||||||
|
"url": "https://github.com/mastergberry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mathias Küsel",
|
||||||
|
"url": "https://github.com/mathiask88"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mathias Stearn",
|
||||||
|
"url": "https://github.com/RedBeard0531"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Matteo Collina",
|
||||||
|
"url": "https://github.com/mcollina"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Michael Dawson",
|
||||||
|
"url": "https://github.com/mhdawson"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Michael Price",
|
||||||
|
"url": "https://github.com/mikepricedev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Michele Campus",
|
||||||
|
"url": "https://github.com/kYroL01"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mikhail Cheshkov",
|
||||||
|
"url": "https://github.com/mcheshkov"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nempoBu4",
|
||||||
|
"url": "https://github.com/nempoBu4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nicola Del Gobbo",
|
||||||
|
"url": "https://github.com/NickNaso"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nick Soggin",
|
||||||
|
"url": "https://github.com/iSkore"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nikolai Vavilov",
|
||||||
|
"url": "https://github.com/seishun"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Nurbol Alpysbayev",
|
||||||
|
"url": "https://github.com/anurbol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pacop",
|
||||||
|
"url": "https://github.com/pacop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Peter Šándor",
|
||||||
|
"url": "https://github.com/petersandor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Philipp Renoth",
|
||||||
|
"url": "https://github.com/DaAitch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rgerd",
|
||||||
|
"url": "https://github.com/rgerd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Richard Lau",
|
||||||
|
"url": "https://github.com/richardlau"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rolf Timmermans",
|
||||||
|
"url": "https://github.com/rolftimmermans"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ross Weir",
|
||||||
|
"url": "https://github.com/ross-weir"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ryuichi Okumura",
|
||||||
|
"url": "https://github.com/okuryu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Saint Gabriel",
|
||||||
|
"url": "https://github.com/chineduG"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sampson Gao",
|
||||||
|
"url": "https://github.com/sampsongao"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sam Roberts",
|
||||||
|
"url": "https://github.com/sam-github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "strager",
|
||||||
|
"url": "https://github.com/strager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Taylor Woll",
|
||||||
|
"url": "https://github.com/boingoing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Thomas Gentilhomme",
|
||||||
|
"url": "https://github.com/fraxken"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tim Rach",
|
||||||
|
"url": "https://github.com/timrach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tobias Nießen",
|
||||||
|
"url": "https://github.com/tniessen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "todoroff",
|
||||||
|
"url": "https://github.com/todoroff"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Toyo Li",
|
||||||
|
"url": "https://github.com/toyobayashi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tux3",
|
||||||
|
"url": "https://github.com/tux3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vlad Velmisov",
|
||||||
|
"url": "https://github.com/Velmisov"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vladimir Morozov",
|
||||||
|
"url": "https://github.com/vmoroz"
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "WenheLI",
|
||||||
|
"url": "https://github.com/WenheLI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Xuguang Mei",
|
||||||
|
"url": "https://github.com/meixg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Yohei Kishimoto",
|
||||||
|
"url": "https://github.com/morokosi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Yulong Wang",
|
||||||
|
"url": "https://github.com/fs-eire"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ziqiu Zhao",
|
||||||
|
"url": "https://github.com/ZzqiZQute"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Feng Yu",
|
||||||
|
"url": "https://github.com/F3n67u"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wanlu wang",
|
||||||
|
"url": "https://github.com/wanlu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Caleb Hearon",
|
||||||
|
"url": "https://github.com/chearon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Marx",
|
||||||
|
"url": "https://github.com/MarxJiao"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ömer AKGÜL",
|
||||||
|
"url": "https://github.com/tuhalf"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Node.js API (Node-API)",
|
||||||
|
"devDependencies": {
|
||||||
|
"benchmark": "^2.1.4",
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"clang-format": "^1.4.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-config-semistandard": "^16.0.0",
|
||||||
|
"eslint-config-standard": "^16.0.3",
|
||||||
|
"eslint-plugin-import": "^2.24.2",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^5.1.0",
|
||||||
|
"fs-extra": "^11.1.1",
|
||||||
|
"path": "^0.12.7",
|
||||||
|
"pre-commit": "^1.2.2",
|
||||||
|
"safe-buffer": "^5.1.1"
|
||||||
|
},
|
||||||
|
"directories": {},
|
||||||
|
"gypfile": false,
|
||||||
|
"homepage": "https://github.com/nodejs/node-addon-api",
|
||||||
|
"keywords": [
|
||||||
|
"n-api",
|
||||||
|
"napi",
|
||||||
|
"addon",
|
||||||
|
"native",
|
||||||
|
"bindings",
|
||||||
|
"c",
|
||||||
|
"c++",
|
||||||
|
"nan",
|
||||||
|
"node-addon-api"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "index.js",
|
||||||
|
"name": "node-addon-api",
|
||||||
|
"readme": "README.md",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/nodejs/node-addon-api.git"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"*.{c,h,gyp,gypi}",
|
||||||
|
"package-support.json",
|
||||||
|
"tools/"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"prebenchmark": "node-gyp rebuild -C benchmark",
|
||||||
|
"benchmark": "node benchmark",
|
||||||
|
"pretest": "node-gyp rebuild -C test",
|
||||||
|
"test": "node test",
|
||||||
|
"test:debug": "node-gyp rebuild -C test --debug && NODE_API_BUILD_CONFIG=Debug node ./test/index.js",
|
||||||
|
"predev": "node-gyp rebuild -C test --debug",
|
||||||
|
"dev": "node test",
|
||||||
|
"predev:incremental": "node-gyp configure build -C test --debug",
|
||||||
|
"dev:incremental": "node test",
|
||||||
|
"doc": "doxygen doc/Doxyfile",
|
||||||
|
"lint": "node tools/eslint-format && node tools/clang-format",
|
||||||
|
"lint:fix": "node tools/clang-format --fix && node tools/eslint-format --fix"
|
||||||
|
},
|
||||||
|
"pre-commit": "lint",
|
||||||
|
"version": "7.1.1",
|
||||||
|
"support": true
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
# Tools
|
||||||
|
|
||||||
|
## clang-format
|
||||||
|
|
||||||
|
The clang-format checking tools is designed to check changed lines of code compared to given git-refs.
|
||||||
|
|
||||||
|
## Migration Script
|
||||||
|
|
||||||
|
The migration tool is designed to reduce repetitive work in the migration process. However, the script is not aiming to convert every thing for you. There are usually some small fixes and major reconstruction required.
|
||||||
|
|
||||||
|
### How To Use
|
||||||
|
|
||||||
|
To run the conversion script, first make sure you have the latest `node-addon-api` in your `node_modules` directory.
|
||||||
|
```
|
||||||
|
npm install node-addon-api
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the script passing your project directory
|
||||||
|
```
|
||||||
|
node ./node_modules/node-addon-api/tools/conversion.js ./
|
||||||
|
```
|
||||||
|
|
||||||
|
After finish, recompile and debug things that are missed by the script.
|
||||||
|
|
||||||
|
|
||||||
|
### Quick Fixes
|
||||||
|
Here is the list of things that can be fixed easily.
|
||||||
|
1. Change your methods' return value to void if it doesn't return value to JavaScript.
|
||||||
|
2. Use `.` to access attribute or to invoke member function in Napi::Object instead of `->`.
|
||||||
|
3. `Napi::New(env, value);` to `Napi::[Type]::New(env, value);
|
||||||
|
|
||||||
|
|
||||||
|
### Major Reconstructions
|
||||||
|
The implementation of `Napi::ObjectWrap` is significantly different from NAN's. `Napi::ObjectWrap` takes a pointer to the wrapped object and creates a reference to the wrapped object inside ObjectWrap constructor. `Napi::ObjectWrap` also associates wrapped object's instance methods to Javascript module instead of static methods like NAN.
|
||||||
|
|
||||||
|
So if you use Nan::ObjectWrap in your module, you will need to execute the following steps.
|
||||||
|
|
||||||
|
1. Convert your [ClassName]::New function to a constructor function that takes a `Napi::CallbackInfo`. Declare it as
|
||||||
|
```
|
||||||
|
[ClassName](const Napi::CallbackInfo& info);
|
||||||
|
```
|
||||||
|
and define it as
|
||||||
|
```
|
||||||
|
[ClassName]::[ClassName](const Napi::CallbackInfo& info) : Napi::ObjectWrap<[ClassName]>(info){
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This way, the `Napi::ObjectWrap` constructor will be invoked after the object has been instantiated and `Napi::ObjectWrap` can use the `this` pointer to create a reference to the wrapped object.
|
||||||
|
|
||||||
|
2. Move your original constructor code into the new constructor. Delete your original constructor.
|
||||||
|
3. In your class initialization function, associate native methods in the following way.
|
||||||
|
```
|
||||||
|
Napi::FunctionReference constructor;
|
||||||
|
|
||||||
|
void [ClassName]::Init(Napi::Env env, Napi::Object exports, Napi::Object module) {
|
||||||
|
Napi::HandleScope scope(env);
|
||||||
|
Napi::Function ctor = DefineClass(env, "Canvas", {
|
||||||
|
InstanceMethod<&[ClassName]::Func1>("Func1"),
|
||||||
|
InstanceMethod<&[ClassName]::Func2>("Func2"),
|
||||||
|
InstanceAccessor<&[ClassName]::ValueGetter>("Value"),
|
||||||
|
StaticMethod<&[ClassName]::StaticMethod>("MethodName"),
|
||||||
|
InstanceValue("Value", Napi::[Type]::New(env, value)),
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor = Napi::Persistent(ctor);
|
||||||
|
constructor .SuppressDestruct();
|
||||||
|
exports.Set("[ClassName]", ctor);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
4. In function where you need to Unwrap the ObjectWrap in NAN like `[ClassName]* native = Nan::ObjectWrap::Unwrap<[ClassName]>(info.This());`, use `this` pointer directly as the unwrapped object as each ObjectWrap instance is associated with a unique object instance.
|
||||||
|
|
||||||
|
|
||||||
|
If you still find issues after following this guide, please leave us an issue describing your problem and we will try to resolve it.
|
||||||
+99
@@ -0,0 +1,99 @@
|
|||||||
|
'use strict';
|
||||||
|
// Descend into a directory structure and, for each file matching *.node, output
|
||||||
|
// based on the imports found in the file whether it's an N-API module or not.
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// Read the output of the command, break it into lines, and use the reducer to
|
||||||
|
// decide whether the file is an N-API module or not.
|
||||||
|
function checkFile (file, command, argv, reducer) {
|
||||||
|
const child = require('child_process').spawn(command, argv, {
|
||||||
|
stdio: ['inherit', 'pipe', 'inherit']
|
||||||
|
});
|
||||||
|
let leftover = '';
|
||||||
|
let isNapi;
|
||||||
|
child.stdout.on('data', (chunk) => {
|
||||||
|
if (isNapi === undefined) {
|
||||||
|
chunk = (leftover + chunk.toString()).split(/[\r\n]+/);
|
||||||
|
leftover = chunk.pop();
|
||||||
|
isNapi = chunk.reduce(reducer, isNapi);
|
||||||
|
if (isNapi !== undefined) {
|
||||||
|
child.kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
child.on('close', (code, signal) => {
|
||||||
|
if ((code === null && signal !== null) || (code !== 0)) {
|
||||||
|
console.log(
|
||||||
|
command + ' exited with code: ' + code + ' and signal: ' + signal);
|
||||||
|
} else {
|
||||||
|
// Green if it's a N-API module, red otherwise.
|
||||||
|
console.log(
|
||||||
|
'\x1b[' + (isNapi ? '42' : '41') + 'm' +
|
||||||
|
(isNapi ? ' N-API' : 'Not N-API') +
|
||||||
|
'\x1b[0m: ' + file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use nm -a to list symbols.
|
||||||
|
function checkFileUNIX (file) {
|
||||||
|
checkFile(file, 'nm', ['-a', file], (soFar, line) => {
|
||||||
|
if (soFar === undefined) {
|
||||||
|
line = line.match(/([0-9a-f]*)? ([a-zA-Z]) (.*$)/);
|
||||||
|
if (line[2] === 'U') {
|
||||||
|
if (/^napi/.test(line[3])) {
|
||||||
|
soFar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return soFar;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use dumpbin /imports to list symbols.
|
||||||
|
function checkFileWin32 (file) {
|
||||||
|
checkFile(file, 'dumpbin', ['/imports', file], (soFar, line) => {
|
||||||
|
if (soFar === undefined) {
|
||||||
|
line = line.match(/([0-9a-f]*)? +([a-zA-Z0-9]) (.*$)/);
|
||||||
|
if (line && /^napi/.test(line[line.length - 1])) {
|
||||||
|
soFar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return soFar;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Descend into a directory structure and pass each file ending in '.node' to
|
||||||
|
// one of the above checks, depending on the OS.
|
||||||
|
function recurse (top) {
|
||||||
|
fs.readdir(top, (error, items) => {
|
||||||
|
if (error) {
|
||||||
|
throw new Error('error reading directory ' + top + ': ' + error);
|
||||||
|
}
|
||||||
|
items.forEach((item) => {
|
||||||
|
item = path.join(top, item);
|
||||||
|
fs.stat(item, ((item) => (error, stats) => {
|
||||||
|
if (error) {
|
||||||
|
throw new Error('error about ' + item + ': ' + error);
|
||||||
|
}
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
recurse(item);
|
||||||
|
} else if (/[.]node$/.test(item) &&
|
||||||
|
// Explicitly ignore files called 'nothing.node' because they are
|
||||||
|
// artefacts of node-addon-api having identified a version of
|
||||||
|
// Node.js that ships with a correct implementation of N-API.
|
||||||
|
path.basename(item) !== 'nothing.node') {
|
||||||
|
process.platform === 'win32'
|
||||||
|
? checkFileWin32(item)
|
||||||
|
: checkFileUNIX(item);
|
||||||
|
}
|
||||||
|
})(item));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start with the directory given on the command line or the current directory
|
||||||
|
// if nothing was given.
|
||||||
|
recurse(process.argv.length > 3 ? process.argv[2] : '.');
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const spawn = require('child_process').spawnSync;
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const filesToCheck = ['*.h', '*.cc'];
|
||||||
|
const FORMAT_START = process.env.FORMAT_START || 'main';
|
||||||
|
|
||||||
|
function main (args) {
|
||||||
|
let fix = false;
|
||||||
|
while (args.length > 0) {
|
||||||
|
switch (args[0]) {
|
||||||
|
case '-f':
|
||||||
|
case '--fix':
|
||||||
|
fix = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
args.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
const clangFormatPath = path.dirname(require.resolve('clang-format'));
|
||||||
|
const binary = process.platform === 'win32'
|
||||||
|
? 'node_modules\\.bin\\clang-format.cmd'
|
||||||
|
: 'node_modules/.bin/clang-format';
|
||||||
|
const options = ['--binary=' + binary, '--style=file'];
|
||||||
|
if (fix) {
|
||||||
|
options.push(FORMAT_START);
|
||||||
|
} else {
|
||||||
|
options.push('--diff', FORMAT_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gitClangFormatPath = path.join(clangFormatPath, 'bin/git-clang-format');
|
||||||
|
const result = spawn(
|
||||||
|
'python',
|
||||||
|
[gitClangFormatPath, ...options, '--', ...filesToCheck],
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.stderr) {
|
||||||
|
console.error('Error running git-clang-format:', result.stderr);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const clangFormatOutput = result.stdout.trim();
|
||||||
|
// Bail fast if in fix mode.
|
||||||
|
if (fix) {
|
||||||
|
console.log(clangFormatOutput);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Detect if there is any complains from clang-format
|
||||||
|
if (
|
||||||
|
clangFormatOutput !== '' &&
|
||||||
|
clangFormatOutput !== 'no modified files to format' &&
|
||||||
|
clangFormatOutput !== 'clang-format did not modify any files'
|
||||||
|
) {
|
||||||
|
console.error(clangFormatOutput);
|
||||||
|
const fixCmd = 'npm run lint:fix';
|
||||||
|
console.error(`
|
||||||
|
ERROR: please run "${fixCmd}" to format changes in your commit
|
||||||
|
Note that when running the command locally, please keep your local
|
||||||
|
main branch and working branch up to date with nodejs/node-addon-api
|
||||||
|
to exclude un-related complains.
|
||||||
|
Or you can run "env FORMAT_START=upstream/main ${fixCmd}".`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
process.exitCode = main(process.argv.slice(2));
|
||||||
|
}
|
||||||
+301
@@ -0,0 +1,301 @@
|
|||||||
|
#! /usr/bin/env node
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const dir = args[0];
|
||||||
|
if (!dir) {
|
||||||
|
console.log('Usage: node ' + path.basename(__filename) + ' <target-dir>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const NodeApiVersion = require('../package.json').version;
|
||||||
|
|
||||||
|
const disable = args[1];
|
||||||
|
let ConfigFileOperations;
|
||||||
|
if (disable !== '--disable' && dir !== '--disable') {
|
||||||
|
ConfigFileOperations = {
|
||||||
|
'package.json': [
|
||||||
|
[/([ ]*)"dependencies": {/g, '$1"dependencies": {\n$1 "node-addon-api": "' + NodeApiVersion + '",'],
|
||||||
|
[/[ ]*"nan": *"[^"]+"(,|)[\n\r]/g, '']
|
||||||
|
],
|
||||||
|
'binding.gyp': [
|
||||||
|
[/([ ]*)'include_dirs': \[/g, '$1\'include_dirs\': [\n$1 \'<!(node -p "require(\\\'node-addon-api\\\').include_dir")\','],
|
||||||
|
[/([ ]*)"include_dirs": \[/g, '$1"include_dirs": [\n$1 "<!(node -p \\"require(\'node-addon-api\').include_dir\\")",'],
|
||||||
|
[/[ ]*("|')<!\(node -e ("|'|\\"|\\')require\(("|'|\\"|\\')nan("|'|\\"|\\')\)("|'|\\"|\\')\)("|')(,|)[\r\n]/g, ''],
|
||||||
|
[/([ ]*)("|')target_name("|'): ("|')(.+?)("|'),/g, '$1$2target_name$2: $4$5$6,\n $2cflags!$2: [ $2-fno-exceptions$2 ],\n $2cflags_cc!$2: [ $2-fno-exceptions$2 ],\n $2xcode_settings$2: { $2GCC_ENABLE_CPP_EXCEPTIONS$2: $2YES$2,\n $2CLANG_CXX_LIBRARY$2: $2libc++$2,\n $2MACOSX_DEPLOYMENT_TARGET$2: $210.7$2,\n },\n $2msvs_settings$2: {\n $2VCCLCompilerTool$2: { $2ExceptionHandling$2: 1 },\n },']
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
ConfigFileOperations = {
|
||||||
|
'package.json': [
|
||||||
|
[/([ ]*)"dependencies": {/g, '$1"dependencies": {\n$1 "node-addon-api": "' + NodeApiVersion + '",'],
|
||||||
|
[/[ ]*"nan": *"[^"]+"(,|)[\n\r]/g, '']
|
||||||
|
],
|
||||||
|
'binding.gyp': [
|
||||||
|
[/([ ]*)'include_dirs': \[/g, '$1\'include_dirs\': [\n$1 \'<!(node -p "require(\\\'node-addon-api\\\').include_dir")\','],
|
||||||
|
[/([ ]*)"include_dirs": \[/g, '$1"include_dirs": [\n$1 "<!(node -p \'require(\\"node-addon-api\\").include_dir\')",'],
|
||||||
|
[/[ ]*("|')<!\(node -e ("|'|\\"|\\')require\(("|'|\\"|\\')nan("|'|\\"|\\')\)("|'|\\"|\\')\)("|')(,|)[\r\n]/g, ''],
|
||||||
|
[/([ ]*)("|')target_name("|'): ("|')(.+?)("|'),/g, '$1$2target_name$2: $4$5$6,\n $2cflags!$2: [ $2-fno-exceptions$2 ],\n $2cflags_cc!$2: [ $2-fno-exceptions$2 ],\n $2defines$2: [ $2NAPI_DISABLE_CPP_EXCEPTIONS$2 ],\n $2conditions$2: [\n [\'OS=="win"\', { $2defines$2: [ $2_HAS_EXCEPTIONS=1$2 ] }]\n ]']
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const SourceFileOperations = [
|
||||||
|
[/Nan::SetMethod\(target,[\s]*"(.*)"[\s]*,[\s]*([^)]+)\)/g, 'exports.Set(Napi::String::New(env, "$1"), Napi::Function::New(env, $2))'],
|
||||||
|
|
||||||
|
[/v8::Local<v8::FunctionTemplate>\s+(\w+)\s*=\s*Nan::New<FunctionTemplate>\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {'],
|
||||||
|
[/Local<FunctionTemplate>\s+(\w+)\s*=\s*Nan::New<FunctionTemplate>\([\w\d:]+\);\s+(\w+)\.Reset\((\1)\);\s+\1->SetClassName\((Nan::String::New|Nan::New<(v8::)*String>)\("(.+?)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$6", {'],
|
||||||
|
[/Local<FunctionTemplate>\s+(\w+)\s*=\s*Nan::New<FunctionTemplate>\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {'],
|
||||||
|
[/Nan::New<v8::FunctionTemplate>\(([\w\d:]+)\)->GetFunction\(\)/g, 'Napi::Function::New(env, $1)'],
|
||||||
|
[/Nan::New<FunctionTemplate>\(([\w\d:]+)\)->GetFunction()/g, 'Napi::Function::New(env, $1);'],
|
||||||
|
[/Nan::New<v8::FunctionTemplate>\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)'],
|
||||||
|
[/Nan::New<FunctionTemplate>\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)'],
|
||||||
|
|
||||||
|
// FunctionTemplate to FunctionReference
|
||||||
|
[/Nan::Persistent<(v8::)*FunctionTemplate>/g, 'Napi::FunctionReference'],
|
||||||
|
[/Nan::Persistent<(v8::)*Function>/g, 'Napi::FunctionReference'],
|
||||||
|
[/v8::Local<v8::FunctionTemplate>/g, 'Napi::FunctionReference'],
|
||||||
|
[/Local<FunctionTemplate>/g, 'Napi::FunctionReference'],
|
||||||
|
[/v8::FunctionTemplate/g, 'Napi::FunctionReference'],
|
||||||
|
[/FunctionTemplate/g, 'Napi::FunctionReference'],
|
||||||
|
|
||||||
|
[/([ ]*)Nan::SetPrototypeMethod\(\w+, "(\w+)", (\w+)\);/g, '$1InstanceMethod("$2", &$3),'],
|
||||||
|
[/([ ]*)(?:\w+\.Reset\(\w+\);\s+)?\(target\)\.Set\("(\w+)",\s*Nan::GetFunction\((\w+)\)\);/gm,
|
||||||
|
'});\n\n' +
|
||||||
|
'$1constructor = Napi::Persistent($3);\n' +
|
||||||
|
'$1constructor.SuppressDestruct();\n' +
|
||||||
|
'$1target.Set("$2", $3);'],
|
||||||
|
|
||||||
|
// TODO: Other attribute combinations
|
||||||
|
[/static_cast<PropertyAttribute>\(ReadOnly\s*\|\s*DontDelete\)/gm,
|
||||||
|
'static_cast<napi_property_attributes>(napi_enumerable | napi_configurable)'],
|
||||||
|
|
||||||
|
[/([\w\d:<>]+?)::Cast\((.+?)\)/g, '$2.As<$1>()'],
|
||||||
|
|
||||||
|
[/\*Nan::Utf8String\(([^)]+)\)/g, '$1->As<Napi::String>().Utf8Value().c_str()'],
|
||||||
|
[/Nan::Utf8String +(\w+)\(([^)]+)\)/g, 'std::string $1 = $2.As<Napi::String>()'],
|
||||||
|
[/Nan::Utf8String/g, 'std::string'],
|
||||||
|
|
||||||
|
[/v8::String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)'],
|
||||||
|
[/String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)'],
|
||||||
|
[/\.length\(\)/g, '.Length()'],
|
||||||
|
|
||||||
|
[/Nan::MakeCallback\(([^,]+),[\s\\]+([^,]+),/gm, '$2.MakeCallback($1,'],
|
||||||
|
|
||||||
|
[/class\s+(\w+)\s*:\s*public\s+Nan::ObjectWrap/g, 'class $1 : public Napi::ObjectWrap<$1>'],
|
||||||
|
[/(\w+)\(([^)]*)\)\s*:\s*Nan::ObjectWrap\(\)\s*(,)?/gm, '$1($2) : Napi::ObjectWrap<$1>()$3'],
|
||||||
|
|
||||||
|
// HandleOKCallback to OnOK
|
||||||
|
[/HandleOKCallback/g, 'OnOK'],
|
||||||
|
// HandleErrorCallback to OnError
|
||||||
|
[/HandleErrorCallback/g, 'OnError'],
|
||||||
|
|
||||||
|
// ex. .As<Function>() to .As<Napi::Object>()
|
||||||
|
[/\.As<v8::(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>\(\)/g, '.As<Napi::$1>()'],
|
||||||
|
[/\.As<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>\(\)/g, '.As<Napi::$1>()'],
|
||||||
|
|
||||||
|
// ex. Nan::New<Number>(info[0]) to Napi::Number::New(info[0])
|
||||||
|
[/Nan::New<(v8::)*Integer>\((.+?)\)/g, 'Napi::Number::New(env, $2)'],
|
||||||
|
[/Nan::New\(([0-9.]+)\)/g, 'Napi::Number::New(env, $1)'],
|
||||||
|
[/Nan::New<(v8::)*String>\("(.+?)"\)/g, 'Napi::String::New(env, "$2")'],
|
||||||
|
[/Nan::New\("(.+?)"\)/g, 'Napi::String::New(env, "$1")'],
|
||||||
|
[/Nan::New<(v8::)*(.+?)>\(\)/g, 'Napi::$2::New(env)'],
|
||||||
|
[/Nan::New<(.+?)>\(\)/g, 'Napi::$1::New(env)'],
|
||||||
|
[/Nan::New<(v8::)*(.+?)>\(/g, 'Napi::$2::New(env, '],
|
||||||
|
[/Nan::New<(.+?)>\(/g, 'Napi::$1::New(env, '],
|
||||||
|
[/Nan::NewBuffer\(/g, 'Napi::Buffer<char>::New(env, '],
|
||||||
|
// TODO: Properly handle this
|
||||||
|
[/Nan::New\(/g, 'Napi::New(env, '],
|
||||||
|
|
||||||
|
[/\.IsInt32\(\)/g, '.IsNumber()'],
|
||||||
|
[/->IsInt32\(\)/g, '.IsNumber()'],
|
||||||
|
|
||||||
|
[/(.+?)->BooleanValue\(\)/g, '$1.As<Napi::Boolean>().Value()'],
|
||||||
|
[/(.+?)->Int32Value\(\)/g, '$1.As<Napi::Number>().Int32Value()'],
|
||||||
|
[/(.+?)->Uint32Value\(\)/g, '$1.As<Napi::Number>().Uint32Value()'],
|
||||||
|
[/(.+?)->IntegerValue\(\)/g, '$1.As<Napi::Number>().Int64Value()'],
|
||||||
|
[/(.+?)->NumberValue\(\)/g, '$1.As<Napi::Number>().DoubleValue()'],
|
||||||
|
|
||||||
|
// ex. Nan::To<bool>(info[0]) to info[0].Value()
|
||||||
|
[/Nan::To<v8::(Boolean|String|Number|Object|Array|Symbol|Function)>\((.+?)\)/g, '$2.To<Napi::$1>()'],
|
||||||
|
[/Nan::To<(Boolean|String|Number|Object|Array|Symbol|Function)>\((.+?)\)/g, '$2.To<Napi::$1>()'],
|
||||||
|
// ex. Nan::To<bool>(info[0]) to info[0].As<Napi::Boolean>().Value()
|
||||||
|
[/Nan::To<bool>\((.+?)\)/g, '$1.As<Napi::Boolean>().Value()'],
|
||||||
|
// ex. Nan::To<int>(info[0]) to info[0].As<Napi::Number>().Int32Value()
|
||||||
|
[/Nan::To<int>\((.+?)\)/g, '$1.As<Napi::Number>().Int32Value()'],
|
||||||
|
// ex. Nan::To<int32_t>(info[0]) to info[0].As<Napi::Number>().Int32Value()
|
||||||
|
[/Nan::To<int32_t>\((.+?)\)/g, '$1.As<Napi::Number>().Int32Value()'],
|
||||||
|
// ex. Nan::To<uint32_t>(info[0]) to info[0].As<Napi::Number>().Uint32Value()
|
||||||
|
[/Nan::To<uint32_t>\((.+?)\)/g, '$1.As<Napi::Number>().Uint32Value()'],
|
||||||
|
// ex. Nan::To<int64_t>(info[0]) to info[0].As<Napi::Number>().Int64Value()
|
||||||
|
[/Nan::To<int64_t>\((.+?)\)/g, '$1.As<Napi::Number>().Int64Value()'],
|
||||||
|
// ex. Nan::To<float>(info[0]) to info[0].As<Napi::Number>().FloatValue()
|
||||||
|
[/Nan::To<float>\((.+?)\)/g, '$1.As<Napi::Number>().FloatValue()'],
|
||||||
|
// ex. Nan::To<double>(info[0]) to info[0].As<Napi::Number>().DoubleValue()
|
||||||
|
[/Nan::To<double>\((.+?)\)/g, '$1.As<Napi::Number>().DoubleValue()'],
|
||||||
|
|
||||||
|
[/Nan::New\((\w+)\)->HasInstance\((\w+)\)/g, '$2.InstanceOf($1.Value())'],
|
||||||
|
|
||||||
|
[/Nan::Has\(([^,]+),\s*/gm, '($1).Has('],
|
||||||
|
[/\.Has\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Has($1)'],
|
||||||
|
[/\.Has\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Has($1)'],
|
||||||
|
|
||||||
|
[/Nan::Get\(([^,]+),\s*/gm, '($1).Get('],
|
||||||
|
[/\.Get\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Get($1)'],
|
||||||
|
[/\.Get\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Get($1)'],
|
||||||
|
|
||||||
|
[/Nan::Set\(([^,]+),\s*/gm, '($1).Set('],
|
||||||
|
[/\.Set\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\s*,/gm, '.Set($1,'],
|
||||||
|
[/\.Set\([\s|\\]*Nan::New\(([^)]+)\)\s*,/gm, '.Set($1,'],
|
||||||
|
|
||||||
|
// ex. node::Buffer::HasInstance(info[0]) to info[0].IsBuffer()
|
||||||
|
[/node::Buffer::HasInstance\((.+?)\)/g, '$1.IsBuffer()'],
|
||||||
|
// ex. node::Buffer::Length(info[0]) to info[0].Length()
|
||||||
|
[/node::Buffer::Length\((.+?)\)/g, '$1.As<Napi::Buffer<char>>().Length()'],
|
||||||
|
// ex. node::Buffer::Data(info[0]) to info[0].Data()
|
||||||
|
[/node::Buffer::Data\((.+?)\)/g, '$1.As<Napi::Buffer<char>>().Data()'],
|
||||||
|
[/Nan::CopyBuffer\(/g, 'Napi::Buffer::Copy(env, '],
|
||||||
|
|
||||||
|
// Nan::AsyncQueueWorker(worker)
|
||||||
|
[/Nan::AsyncQueueWorker\((.+)\);/g, '$1.Queue();'],
|
||||||
|
[/Nan::(Undefined|Null|True|False)\(\)/g, 'env.$1()'],
|
||||||
|
|
||||||
|
// Nan::ThrowError(error) to Napi::Error::New(env, error).ThrowAsJavaScriptException()
|
||||||
|
[/([ ]*)return Nan::Throw(\w*?)Error\((.+?)\);/g, '$1Napi::$2Error::New(env, $3).ThrowAsJavaScriptException();\n$1return env.Null();'],
|
||||||
|
[/Nan::Throw(\w*?)Error\((.+?)\);\n(\s*)return;/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n$3return env.Null();'],
|
||||||
|
[/Nan::Throw(\w*?)Error\((.+?)\);/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n'],
|
||||||
|
// Nan::RangeError(error) to Napi::RangeError::New(env, error)
|
||||||
|
[/Nan::(\w*?)Error\((.+)\)/g, 'Napi::$1Error::New(env, $2)'],
|
||||||
|
|
||||||
|
[/Nan::Set\((.+?),\n* *(.+?),\n* *(.+?),\n* *(.+?)\)/g, '$1.Set($2, $3, $4)'],
|
||||||
|
|
||||||
|
[/Nan::(Escapable)?HandleScope\s+(\w+)\s*;/g, 'Napi::$1HandleScope $2(env);'],
|
||||||
|
[/Nan::(Escapable)?HandleScope/g, 'Napi::$1HandleScope'],
|
||||||
|
[/Nan::ForceSet\(([^,]+), ?/g, '$1->DefineProperty('],
|
||||||
|
[/\.ForceSet\(Napi::String::New\(env, "(\w+)"\),\s*?/g, '.DefineProperty("$1", '],
|
||||||
|
// [ /Nan::GetPropertyNames\(([^,]+)\)/, '$1->GetPropertyNames()' ],
|
||||||
|
[/Nan::Equals\(([^,]+),/g, '$1.StrictEquals('],
|
||||||
|
|
||||||
|
[/(.+)->Set\(/g, '$1.Set('],
|
||||||
|
|
||||||
|
[/Nan::Callback/g, 'Napi::FunctionReference'],
|
||||||
|
|
||||||
|
[/Nan::Persistent<Object>/g, 'Napi::ObjectReference'],
|
||||||
|
[/Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target/g, 'Napi::Env& env, Napi::Object& target'],
|
||||||
|
|
||||||
|
[/(\w+)\*\s+(\w+)\s*=\s*Nan::ObjectWrap::Unwrap<\w+>\(info\.This\(\)\);/g, '$1* $2 = this;'],
|
||||||
|
[/Nan::ObjectWrap::Unwrap<(\w+)>\((.*)\);/g, '$2.Unwrap<$1>();'],
|
||||||
|
|
||||||
|
[/Nan::NAN_METHOD_RETURN_TYPE/g, 'void'],
|
||||||
|
[/NAN_INLINE/g, 'inline'],
|
||||||
|
|
||||||
|
[/Nan::NAN_METHOD_ARGS_TYPE/g, 'const Napi::CallbackInfo&'],
|
||||||
|
[/NAN_METHOD\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'],
|
||||||
|
[/static\s*NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'],
|
||||||
|
[/NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'],
|
||||||
|
[/static\s*NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)'],
|
||||||
|
[/NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)'],
|
||||||
|
[/void Init\((v8::)*Local<(v8::)*Object> exports\)/g, 'Napi::Object Init(Napi::Env env, Napi::Object exports)'],
|
||||||
|
[/NAN_MODULE_INIT\(([\w\d:]+?)\);/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports);'],
|
||||||
|
[/NAN_MODULE_INIT\(([\w\d:]+?)\)/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports)'],
|
||||||
|
|
||||||
|
[/::(Init(?:ialize)?)\(target\)/g, '::$1(env, target, module)'],
|
||||||
|
[/constructor_template/g, 'constructor'],
|
||||||
|
|
||||||
|
[/Nan::FunctionCallbackInfo<(v8::)?Value>[ ]*& [ ]*info\)[ ]*{\n*([ ]*)/gm, 'Napi::CallbackInfo& info) {\n$2Napi::Env env = info.Env();\n$2'],
|
||||||
|
[/Nan::FunctionCallbackInfo<(v8::)*Value>\s*&\s*info\);/g, 'Napi::CallbackInfo& info);'],
|
||||||
|
[/Nan::FunctionCallbackInfo<(v8::)*Value>\s*&/g, 'Napi::CallbackInfo&'],
|
||||||
|
|
||||||
|
[/Buffer::HasInstance\(([^)]+)\)/g, '$1.IsBuffer()'],
|
||||||
|
|
||||||
|
[/info\[(\d+)\]->/g, 'info[$1].'],
|
||||||
|
[/info\[([\w\d]+)\]->/g, 'info[$1].'],
|
||||||
|
[/info\.This\(\)->/g, 'info.This().'],
|
||||||
|
[/->Is(Object|String|Int32|Number)\(\)/g, '.Is$1()'],
|
||||||
|
[/info.GetReturnValue\(\).SetUndefined\(\)/g, 'return env.Undefined()'],
|
||||||
|
[/info\.GetReturnValue\(\)\.Set\(((\n|.)+?)\);/g, 'return $1;'],
|
||||||
|
|
||||||
|
// ex. Local<Value> to Napi::Value
|
||||||
|
[/v8::Local<v8::(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>/g, 'Napi::$1'],
|
||||||
|
[/Local<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>/g, 'Napi::$1'],
|
||||||
|
|
||||||
|
// Declare an env in helper functions that take a Napi::Value
|
||||||
|
[/(\w+)\(Napi::Value (\w+)(,\s*[^()]+)?\)\s*{\n*([ ]*)/gm, '$1(Napi::Value $2$3) {\n$4Napi::Env env = $2.Env();\n$4'],
|
||||||
|
|
||||||
|
// delete #include <node.h> and/or <v8.h>
|
||||||
|
[/#include +(<|")(?:node|nan).h("|>)/g, '#include $1napi.h$2\n#include $1uv.h$2'],
|
||||||
|
// NODE_MODULE to NODE_API_MODULE
|
||||||
|
[/NODE_MODULE/g, 'NODE_API_MODULE'],
|
||||||
|
[/Nan::/g, 'Napi::'],
|
||||||
|
[/nan.h/g, 'napi.h'],
|
||||||
|
|
||||||
|
// delete .FromJust()
|
||||||
|
[/\.FromJust\(\)/g, ''],
|
||||||
|
// delete .ToLocalCheck()
|
||||||
|
[/\.ToLocalChecked\(\)/g, ''],
|
||||||
|
[/^.*->SetInternalFieldCount\(.*$/gm, ''],
|
||||||
|
|
||||||
|
// replace using node; and/or using v8; to using Napi;
|
||||||
|
[/using (node|v8);/g, 'using Napi;'],
|
||||||
|
[/using namespace (node|Nan|v8);/g, 'using namespace Napi;'],
|
||||||
|
// delete using v8::Local;
|
||||||
|
[/using v8::Local;\n/g, ''],
|
||||||
|
// replace using v8::XXX; with using Napi::XXX
|
||||||
|
[/using v8::([A-Za-z]+);/g, 'using Napi::$1;']
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
const paths = listFiles(dir);
|
||||||
|
paths.forEach(function (dirEntry) {
|
||||||
|
const filename = dirEntry.split('\\').pop().split('/').pop();
|
||||||
|
|
||||||
|
// Check whether the file is a source file or a config file
|
||||||
|
// then execute function accordingly
|
||||||
|
const sourcePattern = /.+\.h|.+\.cc|.+\.cpp/;
|
||||||
|
if (sourcePattern.test(filename)) {
|
||||||
|
convertFile(dirEntry, SourceFileOperations);
|
||||||
|
} else if (ConfigFileOperations[filename] != null) {
|
||||||
|
convertFile(dirEntry, ConfigFileOperations[filename]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function listFiles (dir, filelist) {
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
filelist = filelist || [];
|
||||||
|
files.forEach(function (file) {
|
||||||
|
if (file === 'node_modules') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.statSync(path.join(dir, file)).isDirectory()) {
|
||||||
|
filelist = listFiles(path.join(dir, file), filelist);
|
||||||
|
} else {
|
||||||
|
filelist.push(path.join(dir, file));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return filelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convert (content, operations) {
|
||||||
|
for (let i = 0; i < operations.length; i++) {
|
||||||
|
const operation = operations[i];
|
||||||
|
content = content.replace(operation[0], operation[1]);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertFile (fileName, operations) {
|
||||||
|
fs.readFile(fileName, 'utf-8', function (err, file) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
file = convert(file, operations);
|
||||||
|
|
||||||
|
fs.writeFile(fileName, file, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const spawn = require('child_process').spawnSync;
|
||||||
|
|
||||||
|
const filesToCheck = '*.js';
|
||||||
|
const FORMAT_START = process.env.FORMAT_START || 'main';
|
||||||
|
const IS_WIN = process.platform === 'win32';
|
||||||
|
const ESLINT_PATH = IS_WIN ? 'node_modules\\.bin\\eslint.cmd' : 'node_modules/.bin/eslint';
|
||||||
|
|
||||||
|
function main (args) {
|
||||||
|
let fix = false;
|
||||||
|
while (args.length > 0) {
|
||||||
|
switch (args[0]) {
|
||||||
|
case '-f':
|
||||||
|
case '--fix':
|
||||||
|
fix = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
args.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check js files that change on unstaged file
|
||||||
|
const fileUnStaged = spawn(
|
||||||
|
'git',
|
||||||
|
['diff', '--name-only', '--diff-filter=d', FORMAT_START, filesToCheck],
|
||||||
|
{
|
||||||
|
encoding: 'utf-8'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check js files that change on staged file
|
||||||
|
const fileStaged = spawn(
|
||||||
|
'git',
|
||||||
|
['diff', '--name-only', '--cached', '--diff-filter=d', FORMAT_START, filesToCheck],
|
||||||
|
{
|
||||||
|
encoding: 'utf-8'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
...fileStaged.stdout.split('\n').filter((f) => f !== ''),
|
||||||
|
...fileUnStaged.stdout.split('\n').filter((f) => f !== '')
|
||||||
|
];
|
||||||
|
|
||||||
|
if (fix) {
|
||||||
|
options.push('--fix');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = spawn(ESLINT_PATH, [...options], {
|
||||||
|
encoding: 'utf-8'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.error && result.error.errno === 'ENOENT') {
|
||||||
|
console.error('Eslint not found! Eslint is supposed to be found at ', ESLINT_PATH);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.status === 1) {
|
||||||
|
console.error('Eslint error:', result.stdout);
|
||||||
|
const fixCmd = 'npm run lint:fix';
|
||||||
|
console.error(`ERROR: please run "${fixCmd}" to format changes in your commit
|
||||||
|
Note that when running the command locally, please keep your local
|
||||||
|
main branch and working branch up to date with nodejs/node-addon-api
|
||||||
|
to exclude un-related complains.
|
||||||
|
Or you can run "env FORMAT_START=upstream/main ${fixCmd}".
|
||||||
|
Also fix JS files by yourself if necessary.`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.stderr) {
|
||||||
|
console.error('Error running eslint:', result.stderr);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
process.exitCode = main(process.argv.slice(2));
|
||||||
|
}
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
Copyright (c) 2012-2015, Christopher Jeffrey (https://github.com/chjj/)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016, Daniel Imms (http://www.growingwiththeweb.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 - present Microsoft Corporation
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
# node-pty
|
||||||
|
|
||||||
|
[](https://dev.azure.com/vscode/node-pty/_build/latest?definitionId=11&branchName=main)
|
||||||
|
|
||||||
|
`forkpty(3)` bindings for node.js. This allows you to fork processes with pseudoterminal file descriptors. It returns a terminal object which allows reads and writes.
|
||||||
|
|
||||||
|
This is useful for:
|
||||||
|
|
||||||
|
- Writing a terminal emulator (eg. via [xterm.js](https://github.com/sourcelair/xterm.js)).
|
||||||
|
- Getting certain programs to *think* you're a terminal, such as when you need a program to send you control sequences.
|
||||||
|
|
||||||
|
`node-pty` supports Linux, macOS and Windows. Windows support is possible by utilizing the [Windows conpty API](https://blogs.msdn.microsoft.com/commandline/2018/08/02/windows-command-line-introducing-the-windows-pseudo-console-conpty/) on Windows 1809+ and the [winpty](https://github.com/rprichard/winpty) library in older version.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
The full API for node-pty is contained within the [TypeScript declaration file](https://github.com/microsoft/node-pty/blob/main/typings/node-pty.d.ts), use the branch/tag picker in GitHub (`w`) to navigate to the correct version of the API.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
import * as os from 'node:os';
|
||||||
|
import * as pty from 'node-pty';
|
||||||
|
|
||||||
|
const shell = os.platform() === 'win32' ? 'powershell.exe' : 'bash';
|
||||||
|
|
||||||
|
const ptyProcess = pty.spawn(shell, [], {
|
||||||
|
name: 'xterm-color',
|
||||||
|
cols: 80,
|
||||||
|
rows: 30,
|
||||||
|
cwd: process.env.HOME,
|
||||||
|
env: process.env
|
||||||
|
});
|
||||||
|
|
||||||
|
ptyProcess.onData((data) => {
|
||||||
|
process.stdout.write(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
ptyProcess.write('ls\r');
|
||||||
|
ptyProcess.resize(100, 40);
|
||||||
|
ptyProcess.write('ls\r');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Real-world Uses
|
||||||
|
|
||||||
|
`node-pty` powers many different terminal emulators, including:
|
||||||
|
|
||||||
|
- [Microsoft Visual Studio Code](https://code.visualstudio.com)
|
||||||
|
- [Hyper](https://hyper.is/)
|
||||||
|
- [Upterm](https://github.com/railsware/upterm)
|
||||||
|
- [Script Runner](https://github.com/ioquatix/script-runner) for Atom.
|
||||||
|
- [Theia](https://github.com/theia-ide/theia)
|
||||||
|
- [FreeMAN](https://github.com/matthew-matvei/freeman) file manager
|
||||||
|
- [terminus](https://atom.io/packages/terminus) - An Atom plugin for providing terminals inside your Atom workspace.
|
||||||
|
- [x-terminal](https://atom.io/packages/x-terminal) - Also an Atom plugin that provides terminals inside your Atom workspace.
|
||||||
|
- [Termination](https://atom.io/packages/termination) - Also an Atom plugin that provides terminals inside your Atom workspace.
|
||||||
|
- [atom-xterm](https://atom.io/packages/atom-xterm) - Also an Atom plugin that provides terminals inside your Atom workspace.
|
||||||
|
- [electerm](https://github.com/electerm/electerm) Terminal/SSH/SFTP client(Linux, macOS, Windows).
|
||||||
|
- [Extraterm](http://extraterm.org/)
|
||||||
|
- [Wetty](https://github.com/krishnasrinivas/wetty) Browser based Terminal over HTTP and HTTPS
|
||||||
|
- [nomad](https://github.com/lukebarnard1/nomad-term)
|
||||||
|
- [DockerStacks](https://github.com/sfx101/docker-stacks) Local LAMP/LEMP stack using Docker
|
||||||
|
- [TeleType](https://github.com/akshaykmr/TeleType): cli tool that allows you to share your terminal online conveniently. Show off mad cli-fu, help a colleague, teach, or troubleshoot.
|
||||||
|
- [mesos-term](https://github.com/criteo/mesos-term): A web terminal for Apache Mesos. It allows to execute commands within containers.
|
||||||
|
- [Commas](https://github.com/CyanSalt/commas): A hackable terminal and command runner.
|
||||||
|
- [ENiGMA½ BBS Software](https://github.com/NuSkooler/enigma-bbs): A modern BBS software with a nostalgic flair!
|
||||||
|
- [Tinkerun](https://github.com/tinkerun/tinkerun): A new way of running Tinker.
|
||||||
|
- [Tess](https://tessapp.dev): Hackable, simple and rapid terminal for the new era of technology 👍
|
||||||
|
- [NxShell](https://nxshell.github.io/): An easy to use new terminal for Windows/Linux/MacOS platform.
|
||||||
|
- [OpenSumi](https://github.com/opensumi/core): A framework helps you quickly build Cloud or Desktop IDE products.
|
||||||
|
- [Enjoy Git](https://github.com/huangcs427/enjoy-git-release): A modern Git client featuring an intuitive user interface, built with Electron, Vue 3, and TypeScript.
|
||||||
|
|
||||||
|
Do you use node-pty in your application as well? Please open a [Pull Request](https://github.com/Tyriar/node-pty/pulls) to include it here. We would love to have it in our list.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies and build C++
|
||||||
|
npm install
|
||||||
|
# Compile TypeScript -> JavaScript
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Node.JS 16 or Electron 19 is required to use `node-pty`. What version of node is supported is currently mostly bound to [whatever version Visual Studio Code is using](https://github.com/microsoft/node-pty/issues/557#issuecomment-1332193541).
|
||||||
|
|
||||||
|
### Linux (apt)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt install -y make python build-essential
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
Xcode is needed to compile the sources, this can be installed from the App Store.
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
`npm install` requires some tools to be present in the system like Python and C++ compiler. Windows users can easily install them by running the following command in PowerShell as administrator. For more information see https://github.com/felixrieseberg/windows-build-tools:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --global --production windows-build-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
The following are also needed:
|
||||||
|
|
||||||
|
- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) - only the "Desktop C++ Apps" components are needed to be installed
|
||||||
|
- Spectre-mitigated libraries - In order to avoid the build error "MSB8040: Spectre-mitigated libraries are required for this project", open the Visual Studio Installer, press the Modify button, navigate to the "Individual components" tab, search "Spectre", and install an option like "MSVC v143 - VS 2022 C++ x64/x86 Spectre-mitigated libs (Latest)" (the exact option to install will depend on your version of Visual Studio as well as your operating system architecture)
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
[The wiki](https://github.com/Microsoft/node-pty/wiki/Debugging) contains instructions for debugging node-pty.
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
All processes launched from node-pty will launch at the same permission level of the parent process. Take care particularly when using node-pty inside a server that's accessible on the internet. We recommend launching the pty inside a container to protect your host machine.
|
||||||
|
|
||||||
|
## Thread Safety
|
||||||
|
|
||||||
|
Note that node-pty is not thread safe so running it across multiple worker threads in node.js could cause issues.
|
||||||
|
|
||||||
|
## Flow Control
|
||||||
|
|
||||||
|
Automatic flow control can be enabled by either providing `handleFlowControl = true` in the constructor options or setting it later on:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const PAUSE = '\x13'; // XOFF
|
||||||
|
const RESUME = '\x11'; // XON
|
||||||
|
|
||||||
|
const ptyProcess = pty.spawn(shell, [], {handleFlowControl: true});
|
||||||
|
|
||||||
|
// flow control in action
|
||||||
|
ptyProcess.write(PAUSE); // pty will block and pause the child program
|
||||||
|
...
|
||||||
|
ptyProcess.write(RESUME); // pty will enter flow mode and resume the child program
|
||||||
|
|
||||||
|
// temporarily disable/re-enable flow control
|
||||||
|
ptyProcess.handleFlowControl = false;
|
||||||
|
...
|
||||||
|
ptyProcess.handleFlowControl = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
By default `PAUSE` and `RESUME` are XON/XOFF control codes (as shown above). To avoid conflicts in environments that use these control codes for different purposes the messages can be customized as `flowControlPause: string` and `flowControlResume: string` in the constructor options. `PAUSE` and `RESUME` are not passed to the underlying pseudoterminal if flow control is enabled.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Powershell gives error 8009001d
|
||||||
|
|
||||||
|
> Internal Windows PowerShell error. Loading managed Windows PowerShell failed with error 8009001d.
|
||||||
|
|
||||||
|
This happens when PowerShell is launched with no `SystemRoot` environment variable present.
|
||||||
|
|
||||||
|
### ConnectNamedPipe failed: Windows error 232
|
||||||
|
|
||||||
|
This error can occur due to anti-virus software intercepting winpty from creating a pty. To workaround this you can exclude this file from your anti-virus scanning `node-pty\build\Release\winpty-agent.exe`
|
||||||
|
|
||||||
|
## pty.js
|
||||||
|
|
||||||
|
This project is forked from [chjj/pty.js](https://github.com/chjj/pty.js) with the primary goals being to provide better support for later Node.js versions and Windows.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Copyright (c) 2012-2015, Christopher Jeffrey (MIT License).<br>
|
||||||
|
Copyright (c) 2016, Daniel Imms (MIT License).<br>
|
||||||
|
Copyright (c) 2018, Microsoft Corporation (MIT License).
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
'target_defaults': {
|
||||||
|
'dependencies': [
|
||||||
|
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
|
||||||
|
],
|
||||||
|
'conditions': [
|
||||||
|
['OS=="win"', {
|
||||||
|
'msvs_configuration_attributes': {
|
||||||
|
'SpectreMitigation': 'Spectre'
|
||||||
|
},
|
||||||
|
'msvs_settings': {
|
||||||
|
'VCCLCompilerTool': {
|
||||||
|
'AdditionalOptions': [
|
||||||
|
'/guard:cf',
|
||||||
|
'/sdl',
|
||||||
|
'/W3',
|
||||||
|
'/w34244',
|
||||||
|
'/w34267',
|
||||||
|
'/ZH:SHA_256'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'VCLinkerTool': {
|
||||||
|
'AdditionalOptions': [
|
||||||
|
'/DYNAMICBASE',
|
||||||
|
'/guard:cf'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'conditions': [
|
||||||
|
['OS=="win"', {
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'conpty',
|
||||||
|
'sources' : [
|
||||||
|
'src/win/conpty.cc',
|
||||||
|
'src/win/path_util.cc'
|
||||||
|
],
|
||||||
|
'libraries': [
|
||||||
|
'-lshlwapi'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'conpty_console_list',
|
||||||
|
'sources' : [
|
||||||
|
'src/win/conpty_console_list.cc'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'pty',
|
||||||
|
'include_dirs' : [
|
||||||
|
'<!(node -p "require(\'node-addon-api\').include_dir")',
|
||||||
|
'deps/winpty/src/include',
|
||||||
|
],
|
||||||
|
# Disabled due to winpty
|
||||||
|
'msvs_disabled_warnings': [ 4506, 4530 ],
|
||||||
|
'dependencies' : [
|
||||||
|
'deps/winpty/src/winpty.gyp:winpty-agent',
|
||||||
|
'deps/winpty/src/winpty.gyp:winpty',
|
||||||
|
],
|
||||||
|
'sources' : [
|
||||||
|
'src/win/winpty.cc',
|
||||||
|
'src/win/path_util.cc'
|
||||||
|
],
|
||||||
|
'libraries': [
|
||||||
|
'-lshlwapi'
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, { # OS!="win"
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'pty',
|
||||||
|
'sources': [
|
||||||
|
'src/unix/pty.cc',
|
||||||
|
],
|
||||||
|
'libraries': [
|
||||||
|
'-lutil'
|
||||||
|
],
|
||||||
|
'cflags': ['-Wall', '-O2', '-D_FORTIFY_SOURCE=2'],
|
||||||
|
'conditions': [
|
||||||
|
# http://www.gnu.org/software/gnulib/manual/html_node/forkpty.html
|
||||||
|
# One some systems (at least including Cygwin, Interix,
|
||||||
|
# OSF/1 4 and 5, and Mac OS X) linking with -lutil is not required.
|
||||||
|
['OS=="mac" or OS=="solaris"', {
|
||||||
|
'libraries!': [
|
||||||
|
'-lutil'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
['OS=="mac"', {
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'spawn-helper',
|
||||||
|
'type': 'executable',
|
||||||
|
'sources': [
|
||||||
|
'src/unix/spawn-helper.cc',
|
||||||
|
],
|
||||||
|
"xcode_settings": {
|
||||||
|
"MACOSX_DEPLOYMENT_TARGET":"10.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
# Have editor config ignore this directory
|
||||||
|
root = true
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
# Build configure for https://www.tea-ci.org (fork of Drone CI with Msys2 support)
|
||||||
|
build:
|
||||||
|
image: teaci/msys$$arch
|
||||||
|
pull: true
|
||||||
|
shell: msys$$arch
|
||||||
|
commands:
|
||||||
|
- pacman -S --needed --noconfirm --noprogressbar mingw-w64-cross-gcc mingw-w64-cross-crt-git
|
||||||
|
- ./configure
|
||||||
|
- make
|
||||||
|
- make tests
|
||||||
|
- build/trivial_test.exe
|
||||||
|
- mintty --log - --exec build/winpty.exe cmd /c ver | grep Windows
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
arch:
|
||||||
|
- 64
|
||||||
|
- 32
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
* text=auto
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.c text
|
||||||
|
*.cc text
|
||||||
|
*.gyp text
|
||||||
|
*.gypi text
|
||||||
|
*.h text
|
||||||
|
*.ps1 text eol=crlf
|
||||||
|
*.rst text
|
||||||
|
*.sh text
|
||||||
|
*.txt text
|
||||||
|
.gitignore text
|
||||||
|
.gitattributes text
|
||||||
|
Makefile text
|
||||||
|
configure text
|
||||||
|
|
||||||
|
*.sh eol=lf
|
||||||
|
configure eol=lf
|
||||||
|
VERSION.txt eol=lf
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2011-2016 Ryan Prichard
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
+166
@@ -0,0 +1,166 @@
|
|||||||
|
# Copyright (c) 2011-2015 Ryan Prichard
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
# Use make -n to see the actual command-lines make would run.
|
||||||
|
|
||||||
|
# The default "make install" prefix is /usr/local. Pass PREFIX=<path> on the
|
||||||
|
# command-line to override the default.
|
||||||
|
|
||||||
|
.SECONDEXPANSION :
|
||||||
|
|
||||||
|
.PHONY : default
|
||||||
|
default : all
|
||||||
|
|
||||||
|
PREFIX := /usr/local
|
||||||
|
UNIX_ADAPTER_EXE := winpty.exe
|
||||||
|
MINGW_ENABLE_CXX11_FLAG := -std=c++11
|
||||||
|
USE_PCH := 1
|
||||||
|
|
||||||
|
COMMON_CXXFLAGS :=
|
||||||
|
UNIX_CXXFLAGS :=
|
||||||
|
MINGW_CXXFLAGS :=
|
||||||
|
MINGW_LDFLAGS :=
|
||||||
|
UNIX_LDFLAGS :=
|
||||||
|
|
||||||
|
# Include config.mk but complain if it hasn't been created yet.
|
||||||
|
ifeq "$(wildcard config.mk)" ""
|
||||||
|
$(error config.mk does not exist. Please run ./configure)
|
||||||
|
endif
|
||||||
|
include config.mk
|
||||||
|
|
||||||
|
COMMON_CXXFLAGS += \
|
||||||
|
-MMD -Wall \
|
||||||
|
-DUNICODE \
|
||||||
|
-D_UNICODE \
|
||||||
|
-D_WIN32_WINNT=0x0501 \
|
||||||
|
-Ibuild/gen
|
||||||
|
|
||||||
|
UNIX_CXXFLAGS += \
|
||||||
|
$(COMMON_CXXFLAGS)
|
||||||
|
|
||||||
|
MINGW_CXXFLAGS += \
|
||||||
|
$(COMMON_CXXFLAGS) \
|
||||||
|
-O2 \
|
||||||
|
$(MINGW_ENABLE_CXX11_FLAG)
|
||||||
|
|
||||||
|
MINGW_LDFLAGS += -static -static-libgcc -static-libstdc++
|
||||||
|
UNIX_LDFLAGS += $(UNIX_LDFLAGS_STATIC)
|
||||||
|
|
||||||
|
ifeq "$(USE_PCH)" "1"
|
||||||
|
MINGW_CXXFLAGS += -include build/mingw/PrecompiledHeader.h
|
||||||
|
PCH_DEP := build/mingw/PrecompiledHeader.h.gch
|
||||||
|
else
|
||||||
|
PCH_DEP :=
|
||||||
|
endif
|
||||||
|
|
||||||
|
build/gen/GenVersion.h : VERSION.txt $(COMMIT_HASH_DEP) | $$(@D)/.mkdir
|
||||||
|
$(info Updating build/gen/GenVersion.h)
|
||||||
|
@echo "const char GenVersion_Version[] = \"$(shell cat VERSION.txt | tr -d '\r\n')\";" > build/gen/GenVersion.h
|
||||||
|
@echo "const char GenVersion_Commit[] = \"$(COMMIT_HASH)\";" >> build/gen/GenVersion.h
|
||||||
|
|
||||||
|
build/mingw/PrecompiledHeader.h : src/shared/PrecompiledHeader.h | $$(@D)/.mkdir
|
||||||
|
$(info Copying $< to $@)
|
||||||
|
@cp $< $@
|
||||||
|
|
||||||
|
build/mingw/PrecompiledHeader.h.gch : build/mingw/PrecompiledHeader.h | $$(@D)/.mkdir
|
||||||
|
$(info Compiling $<)
|
||||||
|
@$(MINGW_CXX) $(MINGW_CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
-include build/mingw/PrecompiledHeader.h.d
|
||||||
|
|
||||||
|
define def_unix_target
|
||||||
|
build/$1/%.o : src/%.cc | $$$$(@D)/.mkdir
|
||||||
|
$$(info Compiling $$<)
|
||||||
|
@$$(UNIX_CXX) $$(UNIX_CXXFLAGS) $2 -I src/include -c -o $$@ $$<
|
||||||
|
endef
|
||||||
|
|
||||||
|
define def_mingw_target
|
||||||
|
build/$1/%.o : src/%.cc $$(PCH_DEP) | $$$$(@D)/.mkdir
|
||||||
|
$$(info Compiling $$<)
|
||||||
|
@$$(MINGW_CXX) $$(MINGW_CXXFLAGS) $2 -I src/include -c -o $$@ $$<
|
||||||
|
endef
|
||||||
|
|
||||||
|
include src/subdir.mk
|
||||||
|
|
||||||
|
.PHONY : all
|
||||||
|
all : $(ALL_TARGETS)
|
||||||
|
|
||||||
|
.PHONY : tests
|
||||||
|
tests : $(TEST_PROGRAMS)
|
||||||
|
|
||||||
|
.PHONY : install-bin
|
||||||
|
install-bin : all
|
||||||
|
mkdir -p $(PREFIX)/bin
|
||||||
|
install -m 755 -p -s build/$(UNIX_ADAPTER_EXE) $(PREFIX)/bin
|
||||||
|
install -m 755 -p -s build/winpty.dll $(PREFIX)/bin
|
||||||
|
install -m 755 -p -s build/winpty-agent.exe $(PREFIX)/bin
|
||||||
|
|
||||||
|
.PHONY : install-debugserver
|
||||||
|
install-debugserver : all
|
||||||
|
mkdir -p $(PREFIX)/bin
|
||||||
|
install -m 755 -p -s build/winpty-debugserver.exe $(PREFIX)/bin
|
||||||
|
|
||||||
|
.PHONY : install-lib
|
||||||
|
install-lib : all
|
||||||
|
mkdir -p $(PREFIX)/lib
|
||||||
|
install -m 644 -p build/winpty.lib $(PREFIX)/lib
|
||||||
|
|
||||||
|
.PHONY : install-doc
|
||||||
|
install-doc :
|
||||||
|
mkdir -p $(PREFIX)/share/doc/winpty
|
||||||
|
install -m 644 -p LICENSE $(PREFIX)/share/doc/winpty
|
||||||
|
install -m 644 -p README.md $(PREFIX)/share/doc/winpty
|
||||||
|
install -m 644 -p RELEASES.md $(PREFIX)/share/doc/winpty
|
||||||
|
|
||||||
|
.PHONY : install-include
|
||||||
|
install-include :
|
||||||
|
mkdir -p $(PREFIX)/include/winpty
|
||||||
|
install -m 644 -p src/include/winpty.h $(PREFIX)/include/winpty
|
||||||
|
install -m 644 -p src/include/winpty_constants.h $(PREFIX)/include/winpty
|
||||||
|
|
||||||
|
.PHONY : install
|
||||||
|
install : \
|
||||||
|
install-bin \
|
||||||
|
install-debugserver \
|
||||||
|
install-lib \
|
||||||
|
install-doc \
|
||||||
|
install-include
|
||||||
|
|
||||||
|
.PHONY : clean
|
||||||
|
clean :
|
||||||
|
rm -fr build
|
||||||
|
|
||||||
|
.PHONY : clean-msvc
|
||||||
|
clean-msvc :
|
||||||
|
rm -fr src/Default src/Release src/.vs src/gen
|
||||||
|
rm -f src/*.vcxproj src/*.vcxproj.filters src/*.sln src/*.sdf
|
||||||
|
|
||||||
|
.PHONY : distclean
|
||||||
|
distclean : clean
|
||||||
|
rm -f config.mk
|
||||||
|
|
||||||
|
.PRECIOUS : %.mkdir
|
||||||
|
%.mkdir :
|
||||||
|
$(info Creating directory $(dir $@))
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
@touch $@
|
||||||
|
|
||||||
|
src/%.h :
|
||||||
|
@echo "Missing header file $@ (stale dependency file?)"
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
# winpty
|
||||||
|
|
||||||
|
[](https://tea-ci.org/rprichard/winpty)
|
||||||
|
|
||||||
|
winpty is a Windows software package providing an interface similar to a Unix
|
||||||
|
pty-master for communicating with Windows console programs. The package
|
||||||
|
consists of a library (libwinpty) and a tool for Cygwin and MSYS for running
|
||||||
|
Windows console programs in a Cygwin/MSYS pty.
|
||||||
|
|
||||||
|
The software works by starting the `winpty-agent.exe` process with a new,
|
||||||
|
hidden console window, which bridges between the console API and terminal
|
||||||
|
input/output escape codes. It polls the hidden console's screen buffer for
|
||||||
|
changes and generates a corresponding stream of output.
|
||||||
|
|
||||||
|
The Unix adapter allows running Windows console programs (e.g. CMD, PowerShell,
|
||||||
|
IronPython, etc.) under `mintty` or Cygwin's `sshd` with
|
||||||
|
properly-functioning input (e.g. arrow and function keys) and output (e.g. line
|
||||||
|
buffering). The library could be also useful for writing a non-Cygwin SSH
|
||||||
|
server.
|
||||||
|
|
||||||
|
## Supported Windows versions
|
||||||
|
|
||||||
|
winpty runs on Windows XP through Windows 10, including server versions. It
|
||||||
|
can be compiled into either 32-bit or 64-bit binaries.
|
||||||
|
|
||||||
|
## Cygwin/MSYS adapter (`winpty.exe`)
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
You need the following to build winpty:
|
||||||
|
|
||||||
|
* A Cygwin or MSYS installation
|
||||||
|
* GNU make
|
||||||
|
* A MinGW g++ toolchain capable of compiling C++11 code to build `winpty.dll`
|
||||||
|
and `winpty-agent.exe`
|
||||||
|
* A g++ toolchain targeting Cygwin or MSYS to build `winpty.exe`
|
||||||
|
|
||||||
|
Winpty requires two g++ toolchains as it is split into two parts. The
|
||||||
|
`winpty.dll` and `winpty-agent.exe` binaries interface with the native
|
||||||
|
Windows command prompt window so they are compiled with the native MinGW
|
||||||
|
toolchain. The `winpty.exe` binary interfaces with the MSYS/Cygwin terminal so
|
||||||
|
it is compiled with the MSYS/Cygwin toolchain.
|
||||||
|
|
||||||
|
MinGW appears to be split into two distributions -- MinGW (creates 32-bit
|
||||||
|
binaries) and MinGW-w64 (creates both 32-bit and 64-bit binaries). Either
|
||||||
|
one is generally acceptable.
|
||||||
|
|
||||||
|
#### Cygwin packages
|
||||||
|
|
||||||
|
The default g++ compiler for Cygwin targets Cygwin itself, but Cygwin also
|
||||||
|
packages MinGW-w64 compilers. As of this writing, the necessary packages are:
|
||||||
|
|
||||||
|
* Either `mingw64-i686-gcc-g++` or `mingw64-x86_64-gcc-g++`. Select the
|
||||||
|
appropriate compiler for your CPU architecture.
|
||||||
|
* `gcc-g++`
|
||||||
|
* `make`
|
||||||
|
|
||||||
|
As of this writing (2016-01-23), only the MinGW-w64 compiler is acceptable.
|
||||||
|
The MinGW compiler (e.g. from the `mingw-gcc-g++` package) is no longer
|
||||||
|
maintained and is too buggy.
|
||||||
|
|
||||||
|
#### MSYS packages
|
||||||
|
|
||||||
|
For the original MSYS, use the `mingw-get` tool (MinGW Installation Manager),
|
||||||
|
and select at least these components:
|
||||||
|
|
||||||
|
* `mingw-developer-toolkit`
|
||||||
|
* `mingw32-base`
|
||||||
|
* `mingw32-gcc-g++`
|
||||||
|
* `msys-base`
|
||||||
|
* `msys-system-builder`
|
||||||
|
|
||||||
|
When running `./configure`, make sure that `mingw32-g++` is in your
|
||||||
|
`PATH`. It will be in the `C:\MinGW\bin` directory.
|
||||||
|
|
||||||
|
#### MSYS2 packages
|
||||||
|
|
||||||
|
For MSYS2, use `pacman` and install at least these packages:
|
||||||
|
|
||||||
|
* `msys/gcc`
|
||||||
|
* `mingw32/mingw-w64-i686-gcc` or `mingw64/mingw-w64-x86_64-gcc`. Select
|
||||||
|
the appropriate compiler for your CPU architecture.
|
||||||
|
* `make`
|
||||||
|
|
||||||
|
MSYS2 provides three start menu shortcuts for starting MSYS2:
|
||||||
|
|
||||||
|
* MinGW-w64 Win32 Shell
|
||||||
|
* MinGW-w64 Win64 Shell
|
||||||
|
* MSYS2 Shell
|
||||||
|
|
||||||
|
To build winpty, use the MinGW-w64 {Win32,Win64} shortcut of the architecture
|
||||||
|
matching MSYS2. These shortcuts will put the g++ compiler from the
|
||||||
|
`{mingw32,mingw64}/mingw-w64-{i686,x86_64}-gcc` packages into the `PATH`.
|
||||||
|
|
||||||
|
Alternatively, instead of installing `mingw32/mingw-w64-i686-gcc` or
|
||||||
|
`mingw64/mingw-w64-x86_64-gcc`, install the `mingw-w64-cross-gcc` and
|
||||||
|
`mingw-w64-cross-crt-git` packages. These packages install cross-compilers
|
||||||
|
into `/opt/bin`, and then any of the three shortcuts will work.
|
||||||
|
|
||||||
|
### Building the Unix adapter
|
||||||
|
|
||||||
|
In the project directory, run `./configure`, then `make`, then `make install`.
|
||||||
|
By default, winpty is installed into `/usr/local`. Pass `PREFIX=<path>` to
|
||||||
|
`make install` to override this default.
|
||||||
|
|
||||||
|
### Using the Unix adapter
|
||||||
|
|
||||||
|
To run a Windows console program in `mintty` or Cygwin `sshd`, prepend
|
||||||
|
`winpty` to the command-line:
|
||||||
|
|
||||||
|
$ winpty powershell
|
||||||
|
Windows PowerShell
|
||||||
|
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
|
||||||
|
|
||||||
|
PS C:\rprichard\proj\winpty> 10 + 20
|
||||||
|
30
|
||||||
|
PS C:\rprichard\proj\winpty> exit
|
||||||
|
|
||||||
|
## Embedding winpty / MSVC compilation
|
||||||
|
|
||||||
|
See `src/include/winpty.h` for the prototypes of functions exported by
|
||||||
|
`winpty.dll`.
|
||||||
|
|
||||||
|
Only the `winpty.exe` binary uses Cygwin; all the other binaries work without
|
||||||
|
it and can be compiled with either MinGW or MSVC. To compile using MSVC,
|
||||||
|
download gyp and run `gyp -I configurations.gypi` in the `src` subdirectory.
|
||||||
|
This will generate a `winpty.sln` and associated project files. See the
|
||||||
|
`src/winpty.gyp` and `src/configurations.gypi` files for notes on dealing with
|
||||||
|
MSVC versions and different architectures.
|
||||||
|
|
||||||
|
Compiling winpty with MSVC currently requires MSVC 2013 or newer.
|
||||||
|
|
||||||
|
## Debugging winpty
|
||||||
|
|
||||||
|
winpty comes with a tool for collecting timestamped debugging output. To use
|
||||||
|
it:
|
||||||
|
|
||||||
|
1. Run `winpty-debugserver.exe` on the same computer as winpty.
|
||||||
|
2. Set the `WINPTY_DEBUG` environment variable to `trace` for the
|
||||||
|
`winpty.exe` process and/or the process using `libwinpty.dll`.
|
||||||
|
|
||||||
|
winpty also recognizes a `WINPTY_SHOW_CONSOLE` environment variable. Set it
|
||||||
|
to 1 to prevent winpty from hiding the console window.
|
||||||
|
|
||||||
|
## Copyright
|
||||||
|
|
||||||
|
This project is distributed under the MIT license (see the `LICENSE` file in
|
||||||
|
the project root).
|
||||||
|
|
||||||
|
By submitting a pull request for this project, you agree to license your
|
||||||
|
contribution under the MIT license to this project.
|
||||||
+280
@@ -0,0 +1,280 @@
|
|||||||
|
# Next Version
|
||||||
|
|
||||||
|
Input handling changes:
|
||||||
|
|
||||||
|
* Improve Ctrl-C handling with programs that use unprocessed input. (e.g.
|
||||||
|
Ctrl-C now cancels input with PowerShell on Windows 10.)
|
||||||
|
[#116](https://github.com/rprichard/winpty/issues/116)
|
||||||
|
* Fix a theoretical issue with input event ordering.
|
||||||
|
[#117](https://github.com/rprichard/winpty/issues/117)
|
||||||
|
* Ctrl/Shift+{Arrow,Home,End} keys now work with IntelliJ.
|
||||||
|
[#118](https://github.com/rprichard/winpty/issues/118)
|
||||||
|
|
||||||
|
# Version 0.4.3 (2017-05-17)
|
||||||
|
|
||||||
|
Input handling changes:
|
||||||
|
|
||||||
|
* winpty sets `ENHANCED_KEY` for arrow and navigation keys. This fixes an
|
||||||
|
issue with the Ruby REPL.
|
||||||
|
[#99](https://github.com/rprichard/winpty/issues/99)
|
||||||
|
* AltGr keys are handled better now.
|
||||||
|
[#109](https://github.com/rprichard/winpty/issues/109)
|
||||||
|
* In `ENABLE_VIRTUAL_TERMINAL_INPUT` mode, when typing Home/End with a
|
||||||
|
modifier (e.g. Ctrl), winpty now generates an H/F escape sequence like
|
||||||
|
`^[[1;5F` rather than a 1/4 escape like `^[[4;5~`.
|
||||||
|
[#114](https://github.com/rprichard/winpty/issues/114)
|
||||||
|
|
||||||
|
Resizing and scraping fixes:
|
||||||
|
|
||||||
|
* winpty now synthesizes a `WINDOW_BUFFER_SIZE_EVENT` event after resizing
|
||||||
|
the console to better propagate window size changes to console programs.
|
||||||
|
In particular, this affects WSL and Cygwin.
|
||||||
|
[#110](https://github.com/rprichard/winpty/issues/110)
|
||||||
|
* Better handling of resizing for certain full-screen programs, like
|
||||||
|
WSL less.
|
||||||
|
[#112](https://github.com/rprichard/winpty/issues/112)
|
||||||
|
* Hide the cursor if it's currently outside the console window. This change
|
||||||
|
fixes an issue with Far Manager.
|
||||||
|
[#113](https://github.com/rprichard/winpty/issues/113)
|
||||||
|
* winpty now avoids using console fonts smaller than 5px high to improve
|
||||||
|
half-vs-full-width character handling. See
|
||||||
|
https://github.com/Microsoft/vscode/issues/19665.
|
||||||
|
[b4db322010](https://github.com/rprichard/winpty/commit/b4db322010d2d897e6c496fefc4f0ecc9b84c2f3)
|
||||||
|
|
||||||
|
Cygwin/MSYS adapter fix:
|
||||||
|
|
||||||
|
* The way the `winpty` Cygwin/MSYS2 adapter searches for the program to
|
||||||
|
launch changed. It now resolves symlinks and searches the PATH explicitly.
|
||||||
|
[#81](https://github.com/rprichard/winpty/issues/81)
|
||||||
|
[#98](https://github.com/rprichard/winpty/issues/98)
|
||||||
|
|
||||||
|
This release does not include binaries for the old MSYS1 project anymore.
|
||||||
|
MSYS2 will continue to be supported. See
|
||||||
|
https://github.com/rprichard/winpty/issues/97.
|
||||||
|
|
||||||
|
# Version 0.4.2 (2017-01-18)
|
||||||
|
|
||||||
|
This release improves WSL support (i.e. Bash-on-Windows):
|
||||||
|
|
||||||
|
* winpty generates more correct input escape sequences for WSL programs that
|
||||||
|
enable an alternate input mode using DECCKM. This bug affected arrow keys
|
||||||
|
and Home/End in WSL programs such as `vim`, `mc`, and `less`.
|
||||||
|
[#90](https://github.com/rprichard/winpty/issues/90)
|
||||||
|
* winpty now recognizes the `COMMON_LVB_REVERSE_VIDEO` and
|
||||||
|
`COMMON_LVB_UNDERSCORE` text attributes. The Windows console uses these
|
||||||
|
attributes to implement the SGR.4(Underline) and SGR.7(Negative) modes in
|
||||||
|
its VT handling. This change affects WSL pager status bars, man pages, etc.
|
||||||
|
|
||||||
|
The build system no longer has a "version suffix" mechanism, so passing
|
||||||
|
`VERSION_SUFFIX=<suffix>` to make or `-D VERSION_SUFFIX=<suffix>` to gyp now
|
||||||
|
has no effect. AFAIK, the mechanism was never used publicly.
|
||||||
|
[67a34b6c03](https://github.com/rprichard/winpty/commit/67a34b6c03557a5c2e0a2bdd502c2210921d8f3e)
|
||||||
|
|
||||||
|
# Version 0.4.1 (2017-01-03)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* This version fixes a bug where the `winpty-agent.exe` process could read
|
||||||
|
past the end of a buffer.
|
||||||
|
[#94](https://github.com/rprichard/winpty/issues/94)
|
||||||
|
|
||||||
|
# Version 0.4.0 (2016-06-28)
|
||||||
|
|
||||||
|
The winpty library has a new API that should be easier for embedding.
|
||||||
|
[880c00c69e](https://github.com/rprichard/winpty/commit/880c00c69eeca73643ddb576f02c5badbec81f56)
|
||||||
|
|
||||||
|
User-visible changes:
|
||||||
|
|
||||||
|
* winpty now automatically puts the terminal into mouse mode when it detects
|
||||||
|
that the console has left QuickEdit mode. The `--mouse` option still forces
|
||||||
|
the terminal into mouse mode. In principle, an option could be added to
|
||||||
|
suppress terminal mode, but hopefully it won't be necessary. There is a
|
||||||
|
script in the `misc` subdirectory, `misc/ConinMode.ps1`, that can change
|
||||||
|
the QuickEdit mode from the command-line.
|
||||||
|
* winpty now passes keyboard escapes to `bash.exe` in the Windows Subsystem
|
||||||
|
for Linux.
|
||||||
|
[#82](https://github.com/rprichard/winpty/issues/82)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* By default, `winpty.dll` avoids calling `SetProcessWindowStation` within
|
||||||
|
the calling process.
|
||||||
|
[#58](https://github.com/rprichard/winpty/issues/58)
|
||||||
|
* Fixed an uninitialized memory bug that could have crashed winpty.
|
||||||
|
[#80](https://github.com/rprichard/winpty/issues/80)
|
||||||
|
* winpty now works better with very large and very small terminal windows.
|
||||||
|
It resizes the console font according to the number of columns.
|
||||||
|
[#61](https://github.com/rprichard/winpty/issues/61)
|
||||||
|
* winpty no longer uses Mark to freeze the console on Windows 10. The Mark
|
||||||
|
command could interfere with the cursor position, corrupting the data in
|
||||||
|
the screen buffer.
|
||||||
|
[#79](https://github.com/rprichard/winpty/issues/79)
|
||||||
|
|
||||||
|
# Version 0.3.0 (2016-05-20)
|
||||||
|
|
||||||
|
User-visible changes:
|
||||||
|
|
||||||
|
* The UNIX adapter is renamed from `console.exe` to `winpty.exe` to be
|
||||||
|
consistent with MSYS2. The name `winpty.exe` is less likely to conflict
|
||||||
|
with another program and is easier to search for online (e.g. for someone
|
||||||
|
unfamiliar with winpty).
|
||||||
|
* The UNIX adapter now clears the `TERM` variable.
|
||||||
|
[#43](https://github.com/rprichard/winpty/issues/43)
|
||||||
|
* An escape character appearing in a console screen buffer cell is converted
|
||||||
|
to a '?'.
|
||||||
|
[#47](https://github.com/rprichard/winpty/issues/47)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* A major bug affecting XP users was fixed.
|
||||||
|
[#67](https://github.com/rprichard/winpty/issues/67)
|
||||||
|
* Fixed an incompatibility with ConEmu where winpty hung if ConEmu's
|
||||||
|
"Process 'start'" feature was enabled.
|
||||||
|
[#70](https://github.com/rprichard/winpty/issues/70)
|
||||||
|
* Fixed a bug where `cmd.exe` sometimes printed the message,
|
||||||
|
`Not enough storage is available to process this command.`.
|
||||||
|
[#74](https://github.com/rprichard/winpty/issues/74)
|
||||||
|
|
||||||
|
Many changes internally:
|
||||||
|
|
||||||
|
* The codebase is switched from C++03 to C++11 and uses exceptions internally.
|
||||||
|
No exceptions are thrown across the C APIs defined in `winpty.h`.
|
||||||
|
* This version drops support for the original MinGW compiler packaged with
|
||||||
|
Cygwin (`i686-pc-mingw32-g++`). The MinGW-w64 compiler is still supported,
|
||||||
|
as is the MinGW distributed at mingw.org. Compiling with MSVC now requires
|
||||||
|
MSVC 2013 or newer. Windows XP is still supported.
|
||||||
|
[ec3eae8df5](https://github.com/rprichard/winpty/commit/ec3eae8df5bbbb36d7628d168b0815638d122f37)
|
||||||
|
* Pipe security is improved. winpty works harder to produce unique pipe names
|
||||||
|
and includes a random component in the name. winpty secures pipes with a
|
||||||
|
DACL that prevents arbitrary users from connecting to its pipes. winpty now
|
||||||
|
passes `PIPE_REJECT_REMOTE_CLIENTS` on Vista and up, and it verifies that
|
||||||
|
the pipe client PID is correct, again on Vista and up. When connecting to a
|
||||||
|
named pipe, winpty uses the `SECURITY_IDENTIFICATION` flag to restrict
|
||||||
|
impersonation. Previous versions *should* still be secure.
|
||||||
|
* `winpty-debugserver.exe` now has an `--everyone` flag that allows capturing
|
||||||
|
debug output from other users.
|
||||||
|
* The code now compiles cleanly with MSVC's "Security Development Lifecycle"
|
||||||
|
(`/SDL`) checks enabled.
|
||||||
|
|
||||||
|
# Version 0.2.2 (2016-02-25)
|
||||||
|
|
||||||
|
Minor bug fixes and enhancements:
|
||||||
|
|
||||||
|
* Fix a bug that generated spurious mouse input records when an incomplete
|
||||||
|
mouse escape sequence was seen.
|
||||||
|
* Fix a buffer overflow bug in `winpty-debugserver.exe` affecting messages of
|
||||||
|
exactly 4096 bytes.
|
||||||
|
* For MSVC builds, add a `src/configurations.gypi` file that can be included
|
||||||
|
on the gyp command-line to enable 32-bit and 64-bit builds.
|
||||||
|
* `winpty-agent --show-input` mode: Flush stdout after each line.
|
||||||
|
* Makefile builds: generate a `build/winpty.lib` import library to accompany
|
||||||
|
`build/winpty.dll`.
|
||||||
|
|
||||||
|
# Version 0.2.1 (2015-12-19)
|
||||||
|
|
||||||
|
* The main project source was moved into a `src` directory for better code
|
||||||
|
organization and to fix
|
||||||
|
[#51](https://github.com/rprichard/winpty/issues/51).
|
||||||
|
* winpty recognizes many more escape sequences, including:
|
||||||
|
* putty/rxvt's F1-F4 keys
|
||||||
|
[#40](https://github.com/rprichard/winpty/issues/40)
|
||||||
|
* the Linux virtual console's F1-F5 keys
|
||||||
|
* the "application numpad" keys (e.g. enabled with DECPAM)
|
||||||
|
* Fixed handling of Shift-Alt-O and Alt-[.
|
||||||
|
* Added support for mouse input. The UNIX adapter has a `--mouse` argument
|
||||||
|
that puts the terminal into mouse mode, but the agent recognizes mouse
|
||||||
|
input even without the argument. The agent recognizes double-clicks using
|
||||||
|
Windows' double-click interval setting (i.e. GetDoubleClickTime).
|
||||||
|
[#57](https://github.com/rprichard/winpty/issues/57)
|
||||||
|
|
||||||
|
Changes to debugging interfaces:
|
||||||
|
|
||||||
|
* The `WINPTY_DEBUG` variable is now a comma-separated list. The old
|
||||||
|
behavior (i.e. tracing) is enabled with `WINPTY_DEBUG=trace`.
|
||||||
|
* The UNIX adapter program now has a `--showkey` argument that dumps input
|
||||||
|
bytes.
|
||||||
|
* The `winpty-agent.exe` program has a `--show-input` argument that dumps
|
||||||
|
`INPUT_RECORD` records. (It omits mouse events unless `--with-mouse` is
|
||||||
|
also specified.) The agent also responds to `WINPTY_DEBUG=trace,input`,
|
||||||
|
which logs input bytes and synthesized console events, and it responds to
|
||||||
|
`WINPTY_DEBUG=trace,dump_input_map`, which dumps the internal table of
|
||||||
|
escape sequences.
|
||||||
|
|
||||||
|
# Version 0.2.0 (2015-11-13)
|
||||||
|
|
||||||
|
No changes to the API, but many small changes to the implementation. The big
|
||||||
|
changes include:
|
||||||
|
|
||||||
|
* Support for 64-bit Cygwin and MSYS2
|
||||||
|
* Support for Windows 10
|
||||||
|
* Better Unicode support (especially East Asian languages)
|
||||||
|
|
||||||
|
Details:
|
||||||
|
|
||||||
|
* The `configure` script recognizes 64-bit Cygwin and MSYS2 environments and
|
||||||
|
selects the appropriate compiler.
|
||||||
|
* winpty works much better with the upgraded console in Windows 10. The
|
||||||
|
`conhost.exe` hang can still occur, but only with certain programs, and
|
||||||
|
is much less likely to occur. With the new console, use Mark instead of
|
||||||
|
SelectAll, for better performance.
|
||||||
|
[#31](https://github.com/rprichard/winpty/issues/31)
|
||||||
|
[#30](https://github.com/rprichard/winpty/issues/30)
|
||||||
|
[#53](https://github.com/rprichard/winpty/issues/53)
|
||||||
|
* The UNIX adapter now calls `setlocale(LC_ALL, "")` to set the locale.
|
||||||
|
* Improved Unicode support. When a console is started with an East Asian code
|
||||||
|
page, winpty now chooses an East Asian font rather than Consolas / Lucida
|
||||||
|
Console. Selecting the right font helps synchronize character widths
|
||||||
|
between the console and terminal. (It's not perfect, though.)
|
||||||
|
[#41](https://github.com/rprichard/winpty/issues/41)
|
||||||
|
* winpty now more-or-less works with programs that change the screen buffer
|
||||||
|
or resize the original screen buffer. If the screen buffer height changes,
|
||||||
|
winpty switches to a "direct mode", where it makes no effort to track
|
||||||
|
scrolling. In direct mode, it merely syncs snapshots of the console to the
|
||||||
|
terminal. Caveats:
|
||||||
|
* Changing the screen buffer (i.e. `SetConsoleActiveScreenBuffer`)
|
||||||
|
breaks winpty on Windows 7. This problem can eventually be mitigated,
|
||||||
|
but never completely fixed, due to Windows 7 bugginess.
|
||||||
|
* Resizing the original screen buffer can hang `conhost.exe` on Windows 10.
|
||||||
|
Enabling the legacy console is a workaround.
|
||||||
|
* If a program changes the screen buffer and then exits, relying on the OS
|
||||||
|
to restore the original screen buffer, that restoration probably will not
|
||||||
|
happen with winpty. winpty's behavior can probably be improved here.
|
||||||
|
* Improved color handling:
|
||||||
|
* DkGray-on-Black text was previously hiddenly completely. Now it is
|
||||||
|
output as DkGray, with a fallback to LtGray on terminals that don't
|
||||||
|
recognize the intense colors.
|
||||||
|
[#39](https://github.com/rprichard/winpty/issues/39).
|
||||||
|
* The console is always initialized to LtGray-on-Black, regardless of the
|
||||||
|
user setting, which matches the console color heuristic, which translates
|
||||||
|
LtGray-on-Black to "reset SGR parameters."
|
||||||
|
* Shift-Tab is recognized correctly now.
|
||||||
|
[#19](https://github.com/rprichard/winpty/issues/19)
|
||||||
|
* Add a `--version` argument to `winpty-agent.exe` and the UNIX adapter. The
|
||||||
|
argument reports the nominal version (i.e. the `VERSION.txt`) file, with a
|
||||||
|
"VERSION_SUFFIX" appended (defaulted to `-dev`), and a git commit hash, if
|
||||||
|
the `git` command successfully reports a hash during the build. The `git`
|
||||||
|
command is invoked by either `make` or `gyp`.
|
||||||
|
* The agent now combines `ReadConsoleOutputW` calls when it polls the console
|
||||||
|
buffer for changes, which may slightly reduce its CPU overhead.
|
||||||
|
[#44](https://github.com/rprichard/winpty/issues/44).
|
||||||
|
* A `gyp` file is added to help compile with MSVC.
|
||||||
|
* The code can now be compiled as C++11 code, though it isn't by default.
|
||||||
|
[bde8922e08](https://github.com/rprichard/winpty/commit/bde8922e08c3638e01ecc7b581b676c314163e3c)
|
||||||
|
* If winpty can't create a new window station, it charges ahead rather than
|
||||||
|
aborting. This situation might happen if winpty were started from an SSH
|
||||||
|
session.
|
||||||
|
* Debugging improvements:
|
||||||
|
* `WINPTYDBG` is renamed to `WINPTY_DEBUG`, and a new `WINPTY_SHOW_CONSOLE`
|
||||||
|
variable keeps the underlying console visible.
|
||||||
|
* A `winpty-debugserver.exe` program is built and shipped by default. It
|
||||||
|
collects the trace output enabled with `WINPTY_DEBUG`.
|
||||||
|
* The `Makefile` build of winpty now compiles `winpty-agent.exe` and
|
||||||
|
`winpty.dll` with -O2.
|
||||||
|
|
||||||
|
# Version 0.1.1 (2012-07-28)
|
||||||
|
|
||||||
|
Minor bugfix release.
|
||||||
|
|
||||||
|
# Version 0.1 (2012-04-17)
|
||||||
|
|
||||||
|
Initial release.
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
0.4.4-dev
|
||||||
+167
@@ -0,0 +1,167 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011-2015 Ryan Prichard
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
#
|
||||||
|
# findTool(desc, commandList)
|
||||||
|
#
|
||||||
|
# Searches commandLine for the first command in the PATH and returns it.
|
||||||
|
# Prints an error and aborts the script if no match is found.
|
||||||
|
#
|
||||||
|
FINDTOOL_OUT=""
|
||||||
|
function findTool {
|
||||||
|
DESC=$1
|
||||||
|
OPTIONS=$2
|
||||||
|
for CMD in ${OPTIONS}; do
|
||||||
|
if (which $CMD &>/dev/null) then
|
||||||
|
echo "Found $DESC: $CMD"
|
||||||
|
FINDTOOL_OUT="$CMD"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "Error: could not find $DESC. One of these should be in your PATH:"
|
||||||
|
for CMD in ${OPTIONS}; do
|
||||||
|
echo " * $CMD"
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
IS_CYGWIN=0
|
||||||
|
IS_MSYS1=0
|
||||||
|
IS_MSYS2=0
|
||||||
|
|
||||||
|
# Link parts of the Cygwin binary statically to aid in redistribution? The
|
||||||
|
# binary still links dynamically against the main DLL. The MinGW binaries are
|
||||||
|
# also statically linked and therefore depend only on Windows DLLs. I started
|
||||||
|
# linking the Cygwin/MSYS binary statically, because G++ 4.7 changed the
|
||||||
|
# Windows C++ ABI.
|
||||||
|
UNIX_LDFLAGS_STATIC='-static -static-libgcc -static-libstdc++'
|
||||||
|
|
||||||
|
# Detect the environment -- Cygwin or MSYS.
|
||||||
|
case $(uname -s) in
|
||||||
|
CYGWIN*)
|
||||||
|
echo 'uname -s identifies a Cygwin environment.'
|
||||||
|
IS_CYGWIN=1
|
||||||
|
case $(uname -m) in
|
||||||
|
i686)
|
||||||
|
echo 'uname -m identifies an i686 environment.'
|
||||||
|
UNIX_CXX=i686-pc-cygwin-g++
|
||||||
|
MINGW_CXX=i686-w64-mingw32-g++
|
||||||
|
;;
|
||||||
|
x86_64)
|
||||||
|
echo 'uname -m identifies an x86_64 environment.'
|
||||||
|
UNIX_CXX=x86_64-pc-cygwin-g++
|
||||||
|
MINGW_CXX=x86_64-w64-mingw32-g++
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo 'Error: uname -m did not match either i686 or x86_64.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
MSYS*|MINGW*)
|
||||||
|
# MSYS2 notes:
|
||||||
|
# - MSYS2 offers two shortcuts to open an environment:
|
||||||
|
# - MinGW-w64 Win32 Shell. This env reports a `uname -s` of
|
||||||
|
# MINGW32_NT-6.1 on 32-bit Win7. The MinGW-w64 compiler
|
||||||
|
# (i686-w64-mingw32-g++.exe) is in the PATH.
|
||||||
|
# - MSYS2 Shell. `uname -s` instead reports MSYS_NT-6.1.
|
||||||
|
# The i686-w64-mingw32-g++ compiler is not in the PATH.
|
||||||
|
# - MSYS2 appears to use MinGW-w64, not the older mingw.org.
|
||||||
|
# MSYS notes:
|
||||||
|
# - `uname -s` is always MINGW32_NT-6.1 on Win7.
|
||||||
|
echo 'uname -s identifies an MSYS/MSYS2 environment.'
|
||||||
|
case $(uname -m) in
|
||||||
|
i686)
|
||||||
|
echo 'uname -m identifies an i686 environment.'
|
||||||
|
UNIX_CXX=i686-pc-msys-g++
|
||||||
|
if echo "$(uname -r)" | grep '^1[.]' > /dev/null; then
|
||||||
|
# The MSYS-targeting compiler for the original 32-bit-only
|
||||||
|
# MSYS does not recognize the -static-libstdc++ flag, and
|
||||||
|
# it does not work with -static, because it tries to link
|
||||||
|
# statically with the core MSYS library and fails.
|
||||||
|
#
|
||||||
|
# Distinguish between the two using the major version
|
||||||
|
# number of `uname -r`:
|
||||||
|
#
|
||||||
|
# MSYS uname -r: 1.0.18(0.48/3/2)
|
||||||
|
# MSYS2 uname -r: 2.0.0(0.284/5/3)
|
||||||
|
#
|
||||||
|
# This is suboptimal because MSYS2 is not actually the
|
||||||
|
# second version of MSYS--it's a brand-new fork of Cygwin.
|
||||||
|
#
|
||||||
|
IS_MSYS1=1
|
||||||
|
UNIX_LDFLAGS_STATIC=
|
||||||
|
MINGW_CXX=mingw32-g++
|
||||||
|
else
|
||||||
|
IS_MSYS2=1
|
||||||
|
MINGW_CXX=i686-w64-mingw32-g++.exe
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
x86_64)
|
||||||
|
echo 'uname -m identifies an x86_64 environment.'
|
||||||
|
IS_MSYS2=1
|
||||||
|
UNIX_CXX=x86_64-pc-msys-g++
|
||||||
|
MINGW_CXX=x86_64-w64-mingw32-g++
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo 'Error: uname -m did not match either i686 or x86_64.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo 'Error: uname -s did not match either CYGWIN* or MINGW*.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Search the PATH and pick the first match.
|
||||||
|
findTool "Cygwin/MSYS G++ compiler" "$UNIX_CXX"
|
||||||
|
UNIX_CXX=$FINDTOOL_OUT
|
||||||
|
findTool "MinGW G++ compiler" "$MINGW_CXX"
|
||||||
|
MINGW_CXX=$FINDTOOL_OUT
|
||||||
|
|
||||||
|
# Write config files.
|
||||||
|
echo Writing config.mk
|
||||||
|
echo UNIX_CXX=$UNIX_CXX > config.mk
|
||||||
|
echo UNIX_LDFLAGS_STATIC=$UNIX_LDFLAGS_STATIC >> config.mk
|
||||||
|
echo MINGW_CXX=$MINGW_CXX >> config.mk
|
||||||
|
|
||||||
|
if test $IS_MSYS1 = 1; then
|
||||||
|
echo UNIX_CXXFLAGS += -DWINPTY_TARGET_MSYS1 >> config.mk
|
||||||
|
# The MSYS1 MinGW compiler has a bug that prevents inclusion of algorithm
|
||||||
|
# and math.h in normal C++11 mode. The workaround is to enable the gnu++11
|
||||||
|
# mode instead. The bug was fixed on 2015-07-31, but as of 2016-02-26, the
|
||||||
|
# fix apparently hasn't been released. See
|
||||||
|
# http://ehc.ac/p/mingw/bugs/2250/.
|
||||||
|
echo MINGW_ENABLE_CXX11_FLAG := -std=gnu++11 >> config.mk
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -d .git -a -f .git/HEAD -a -f .git/index && git rev-parse HEAD >&/dev/null; then
|
||||||
|
echo "Commit info: git"
|
||||||
|
echo 'COMMIT_HASH = $(shell git rev-parse HEAD)' >> config.mk
|
||||||
|
echo 'COMMIT_HASH_DEP := config.mk .git/HEAD .git/index' >> config.mk
|
||||||
|
else
|
||||||
|
echo "Commit info: none"
|
||||||
|
echo 'COMMIT_HASH := none' >> config.mk
|
||||||
|
echo 'COMMIT_HASH_DEP := config.mk' >> config.mk
|
||||||
|
fi
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
void dumpInfoToTrace() {
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
assert(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info));
|
||||||
|
trace("win=(%d,%d,%d,%d)",
|
||||||
|
(int)info.srWindow.Left,
|
||||||
|
(int)info.srWindow.Top,
|
||||||
|
(int)info.srWindow.Right,
|
||||||
|
(int)info.srWindow.Bottom);
|
||||||
|
trace("buf=(%d,%d)",
|
||||||
|
(int)info.dwSize.X,
|
||||||
|
(int)info.dwSize.Y);
|
||||||
|
trace("cur=(%d,%d)",
|
||||||
|
(int)info.dwCursorPosition.X,
|
||||||
|
(int)info.dwCursorPosition.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
// Reducing the buffer height can move the window up.
|
||||||
|
setBufferSize(80, 25);
|
||||||
|
setWindowPos(0, 20, 80, 5);
|
||||||
|
Sleep(2000);
|
||||||
|
setBufferSize(80, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
// Reducing the buffer height moves the window up and the buffer
|
||||||
|
// contents up too.
|
||||||
|
setBufferSize(80, 25);
|
||||||
|
setWindowPos(0, 20, 80, 5);
|
||||||
|
setCursorPos(0, 20);
|
||||||
|
printf("TEST1\nTEST2\nTEST3\nTEST4\n");
|
||||||
|
fflush(stdout);
|
||||||
|
Sleep(2000);
|
||||||
|
setBufferSize(80, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
// Reducing the buffer width can move the window left.
|
||||||
|
setBufferSize(80, 25);
|
||||||
|
setWindowPos(40, 0, 40, 25);
|
||||||
|
Sleep(2000);
|
||||||
|
setBufferSize(60, 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
// Sometimes the buffer contents are shifted up; sometimes they're
|
||||||
|
// shifted down. It seems to depend on the cursor position?
|
||||||
|
|
||||||
|
// setBufferSize(80, 25);
|
||||||
|
// setWindowPos(0, 20, 80, 5);
|
||||||
|
// setCursorPos(0, 20);
|
||||||
|
// printf("TESTa\nTESTb\nTESTc\nTESTd\nTESTe");
|
||||||
|
// fflush(stdout);
|
||||||
|
// setCursorPos(0, 0);
|
||||||
|
// printf("TEST1\nTEST2\nTEST3\nTEST4\nTEST5");
|
||||||
|
// fflush(stdout);
|
||||||
|
// setCursorPos(0, 24);
|
||||||
|
// Sleep(5000);
|
||||||
|
// setBufferSize(80, 24);
|
||||||
|
|
||||||
|
setBufferSize(80, 20);
|
||||||
|
setWindowPos(0, 10, 80, 10);
|
||||||
|
setCursorPos(0, 18);
|
||||||
|
|
||||||
|
printf("TEST1\nTEST2");
|
||||||
|
fflush(stdout);
|
||||||
|
setCursorPos(0, 18);
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
setBufferSize(80, 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpInfoToTrace();
|
||||||
|
Sleep(30000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
// A test program for CreateConsoleScreenBuffer / SetConsoleActiveScreenBuffer
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
HANDLE childBuffer = CreateConsoleScreenBuffer(
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
|
||||||
|
|
||||||
|
SetConsoleActiveScreenBuffer(childBuffer);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
char buf[1024];
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
|
||||||
|
assert(GetConsoleScreenBufferInfo(origBuffer, &info));
|
||||||
|
trace("child.size=(%d,%d)", (int)info.dwSize.X, (int)info.dwSize.Y);
|
||||||
|
trace("child.cursor=(%d,%d)", (int)info.dwCursorPosition.X, (int)info.dwCursorPosition.Y);
|
||||||
|
trace("child.window=(%d,%d,%d,%d)",
|
||||||
|
(int)info.srWindow.Left, (int)info.srWindow.Top,
|
||||||
|
(int)info.srWindow.Right, (int)info.srWindow.Bottom);
|
||||||
|
trace("child.maxSize=(%d,%d)", (int)info.dwMaximumWindowSize.X, (int)info.dwMaximumWindowSize.Y);
|
||||||
|
|
||||||
|
int ch = getch();
|
||||||
|
sprintf(buf, "%02x\n", ch);
|
||||||
|
DWORD actual = 0;
|
||||||
|
WriteFile(childBuffer, buf, strlen(buf), &actual, NULL);
|
||||||
|
if (ch == 0x1b/*ESC*/ || ch == 0x03/*CTRL-C*/)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ch == 'b') {
|
||||||
|
setBufferSize(origBuffer, 40, 25);
|
||||||
|
} else if (ch == 'w') {
|
||||||
|
setWindowPos(origBuffer, 1, 1, 38, 23);
|
||||||
|
} else if (ch == 'c') {
|
||||||
|
setCursorPos(origBuffer, 10, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleActiveScreenBuffer(origBuffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Demonstrates that console clearing sets each cell's character to SP, not
|
||||||
|
* NUL, and it sets the attribute of each cell to the current text attribute.
|
||||||
|
*
|
||||||
|
* This confirms the MSDN instruction in the "Clearing the Screen" article.
|
||||||
|
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022(v=vs.85).aspx
|
||||||
|
* It advises using GetConsoleScreenBufferInfo to get the current text
|
||||||
|
* attribute, then FillConsoleOutputCharacter and FillConsoleOutputAttribute to
|
||||||
|
* write to the console buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(conout, 0x24);
|
||||||
|
system("cls");
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(80, 25);
|
||||||
|
setWindowPos(0, 0, 80, 25);
|
||||||
|
|
||||||
|
CHAR_INFO buf;
|
||||||
|
COORD bufSize = { 1, 1 };
|
||||||
|
COORD bufCoord = { 0, 0 };
|
||||||
|
SMALL_RECT rect = { 5, 5, 5, 5 };
|
||||||
|
BOOL ret;
|
||||||
|
DWORD actual;
|
||||||
|
COORD writeCoord = { 5, 5 };
|
||||||
|
|
||||||
|
// After cls, each cell's character is a space, and its attributes are the
|
||||||
|
// default text attributes.
|
||||||
|
ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect);
|
||||||
|
assert(ret && buf.Char.UnicodeChar == L' ' && buf.Attributes == 0x24);
|
||||||
|
|
||||||
|
// Nevertheless, it is possible to change a cell to NUL.
|
||||||
|
ret = FillConsoleOutputCharacterW(conout, L'\0', 1, writeCoord, &actual);
|
||||||
|
assert(ret && actual == 1);
|
||||||
|
ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect);
|
||||||
|
assert(ret && buf.Char.UnicodeChar == L'\0' && buf.Attributes == 0x24);
|
||||||
|
|
||||||
|
// As well as a 0 attribute. (As one would expect, the cell is
|
||||||
|
// black-on-black.)
|
||||||
|
ret = FillConsoleOutputAttribute(conout, 0, 1, writeCoord, &actual);
|
||||||
|
assert(ret && actual == 1);
|
||||||
|
ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect);
|
||||||
|
assert(ret && buf.Char.UnicodeChar == L'\0' && buf.Attributes == 0);
|
||||||
|
ret = FillConsoleOutputCharacterW(conout, L'X', 1, writeCoord, &actual);
|
||||||
|
assert(ret && actual == 1);
|
||||||
|
ret = ReadConsoleOutputW(conout, &buf, bufSize, bufCoord, &rect);
|
||||||
|
assert(ret && buf.Char.UnicodeChar == L'X' && buf.Attributes == 0);
|
||||||
|
|
||||||
|
// The 'X' is invisible.
|
||||||
|
countDown(3);
|
||||||
|
|
||||||
|
ret = FillConsoleOutputAttribute(conout, 0x42, 1, writeCoord, &actual);
|
||||||
|
assert(ret && actual == 1);
|
||||||
|
|
||||||
|
countDown(5);
|
||||||
|
}
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
static HANDLE getConin() {
|
||||||
|
HANDLE conin = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
if (conin == INVALID_HANDLE_VALUE) {
|
||||||
|
fprintf(stderr, "error: cannot get stdin\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return conin;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD getConsoleMode() {
|
||||||
|
DWORD mode = 0;
|
||||||
|
if (!GetConsoleMode(getConin(), &mode)) {
|
||||||
|
fprintf(stderr, "error: GetConsoleMode failed (is stdin a console?)\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setConsoleMode(DWORD mode) {
|
||||||
|
if (!SetConsoleMode(getConin(), mode)) {
|
||||||
|
fprintf(stderr, "error: SetConsoleMode failed (is stdin a console?)\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long parseInt(const std::string &s) {
|
||||||
|
errno = 0;
|
||||||
|
char *endptr = nullptr;
|
||||||
|
long result = strtol(s.c_str(), &endptr, 0);
|
||||||
|
if (errno != 0 || !endptr || *endptr != '\0') {
|
||||||
|
fprintf(stderr, "error: could not parse integral argument '%s'\n", s.c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
printf("Usage: ConinMode [verb] [options]\n");
|
||||||
|
printf("Verbs:\n");
|
||||||
|
printf(" [info] Dumps info about mode flags.\n");
|
||||||
|
printf(" get Prints the mode DWORD.\n");
|
||||||
|
printf(" set VALUE Sets the mode to VALUE, which can be decimal, hex, or octal.\n");
|
||||||
|
printf(" set VALUE MASK\n");
|
||||||
|
printf(" Same as `set VALUE`, but only alters the bits in MASK.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
DWORD value;
|
||||||
|
} kInputFlags[] = {
|
||||||
|
"ENABLE_PROCESSED_INPUT", ENABLE_PROCESSED_INPUT, // 0x0001
|
||||||
|
"ENABLE_LINE_INPUT", ENABLE_LINE_INPUT, // 0x0002
|
||||||
|
"ENABLE_ECHO_INPUT", ENABLE_ECHO_INPUT, // 0x0004
|
||||||
|
"ENABLE_WINDOW_INPUT", ENABLE_WINDOW_INPUT, // 0x0008
|
||||||
|
"ENABLE_MOUSE_INPUT", ENABLE_MOUSE_INPUT, // 0x0010
|
||||||
|
"ENABLE_INSERT_MODE", ENABLE_INSERT_MODE, // 0x0020
|
||||||
|
"ENABLE_QUICK_EDIT_MODE", ENABLE_QUICK_EDIT_MODE, // 0x0040
|
||||||
|
"ENABLE_EXTENDED_FLAGS", ENABLE_EXTENDED_FLAGS, // 0x0080
|
||||||
|
"ENABLE_VIRTUAL_TERMINAL_INPUT", 0x0200/*ENABLE_VIRTUAL_TERMINAL_INPUT*/, // 0x0200
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
std::vector<std::string> args;
|
||||||
|
for (size_t i = 1; i < argc; ++i) {
|
||||||
|
args.push_back(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.empty() || args.size() == 1 && args[0] == "info") {
|
||||||
|
DWORD mode = getConsoleMode();
|
||||||
|
printf("mode: 0x%lx\n", mode);
|
||||||
|
for (const auto &flag : kInputFlags) {
|
||||||
|
printf("%-29s 0x%04lx %s\n", flag.name, flag.value, flag.value & mode ? "ON" : "off");
|
||||||
|
mode &= ~flag.value;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
if (mode & (1u << i)) {
|
||||||
|
printf("Unrecognized flag: %04x\n", (1u << i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto verb = args[0];
|
||||||
|
|
||||||
|
if (verb == "set") {
|
||||||
|
if (args.size() == 2) {
|
||||||
|
const DWORD newMode = parseInt(args[1]);
|
||||||
|
setConsoleMode(newMode);
|
||||||
|
} else if (args.size() == 3) {
|
||||||
|
const DWORD mode = parseInt(args[1]);
|
||||||
|
const DWORD mask = parseInt(args[2]);
|
||||||
|
const int newMode = (getConsoleMode() & ~mask) | (mode & mask);
|
||||||
|
setConsoleMode(newMode);
|
||||||
|
} else {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
} else if (verb == "get") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
printf("0x%lx\n", getConsoleMode());
|
||||||
|
} else {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+116
@@ -0,0 +1,116 @@
|
|||||||
|
#
|
||||||
|
# PowerShell script for controlling the console QuickEdit and InsertMode flags.
|
||||||
|
#
|
||||||
|
# Turn QuickEdit off to interact with mouse-driven console programs.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# powershell .\ConinMode.ps1 [Options]
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# -QuickEdit [on/off]
|
||||||
|
# -InsertMode [on/off]
|
||||||
|
# -Mode [integer]
|
||||||
|
#
|
||||||
|
|
||||||
|
param (
|
||||||
|
[ValidateSet("on", "off")][string] $QuickEdit,
|
||||||
|
[ValidateSet("on", "off")][string] $InsertMode,
|
||||||
|
[int] $Mode
|
||||||
|
)
|
||||||
|
|
||||||
|
$signature = @'
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern IntPtr GetStdHandle(int nStdHandle);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern uint GetConsoleMode(
|
||||||
|
IntPtr hConsoleHandle,
|
||||||
|
out uint lpMode);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern uint SetConsoleMode(
|
||||||
|
IntPtr hConsoleHandle,
|
||||||
|
uint dwMode);
|
||||||
|
|
||||||
|
public const int STD_INPUT_HANDLE = -10;
|
||||||
|
public const int ENABLE_INSERT_MODE = 0x0020;
|
||||||
|
public const int ENABLE_QUICK_EDIT_MODE = 0x0040;
|
||||||
|
public const int ENABLE_EXTENDED_FLAGS = 0x0080;
|
||||||
|
'@
|
||||||
|
|
||||||
|
$WinAPI = Add-Type -MemberDefinition $signature `
|
||||||
|
-Name WinAPI -Namespace ConinModeScript `
|
||||||
|
-PassThru
|
||||||
|
|
||||||
|
function GetConIn {
|
||||||
|
$ret = $WinAPI::GetStdHandle($WinAPI::STD_INPUT_HANDLE)
|
||||||
|
if ($ret -eq -1) {
|
||||||
|
throw "error: cannot get stdin"
|
||||||
|
}
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetConsoleMode {
|
||||||
|
$conin = GetConIn
|
||||||
|
$mode = 0
|
||||||
|
$ret = $WinAPI::GetConsoleMode($conin, [ref]$mode)
|
||||||
|
if ($ret -eq 0) {
|
||||||
|
throw "GetConsoleMode failed (is stdin a console?)"
|
||||||
|
}
|
||||||
|
return $mode
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetConsoleMode($mode) {
|
||||||
|
$conin = GetConIn
|
||||||
|
$ret = $WinAPI::SetConsoleMode($conin, $mode)
|
||||||
|
if ($ret -eq 0) {
|
||||||
|
throw "SetConsoleMode failed (is stdin a console?)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldMode = GetConsoleMode
|
||||||
|
$newMode = $oldMode
|
||||||
|
$doingSomething = $false
|
||||||
|
|
||||||
|
if ($PSBoundParameters.ContainsKey("Mode")) {
|
||||||
|
$newMode = $Mode
|
||||||
|
$doingSomething = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($QuickEdit + $InsertMode -ne "") {
|
||||||
|
if (!($newMode -band $WinAPI::ENABLE_EXTENDED_FLAGS)) {
|
||||||
|
# We can't enable an extended flag without overwriting the existing
|
||||||
|
# QuickEdit/InsertMode flags. AFAICT, there is no way to query their
|
||||||
|
# existing values, so at least we can choose sensible defaults.
|
||||||
|
$newMode = $newMode -bor $WinAPI::ENABLE_EXTENDED_FLAGS
|
||||||
|
$newMode = $newMode -bor $WinAPI::ENABLE_QUICK_EDIT_MODE
|
||||||
|
$newMode = $newMode -bor $WinAPI::ENABLE_INSERT_MODE
|
||||||
|
$doingSomething = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($QuickEdit -eq "on") {
|
||||||
|
$newMode = $newMode -bor $WinAPI::ENABLE_QUICK_EDIT_MODE
|
||||||
|
$doingSomething = $true
|
||||||
|
} elseif ($QuickEdit -eq "off") {
|
||||||
|
$newMode = $newMode -band (-bnot $WinAPI::ENABLE_QUICK_EDIT_MODE)
|
||||||
|
$doingSomething = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($InsertMode -eq "on") {
|
||||||
|
$newMode = $newMode -bor $WinAPI::ENABLE_INSERT_MODE
|
||||||
|
$doingSomething = $true
|
||||||
|
} elseif ($InsertMode -eq "off") {
|
||||||
|
$newMode = $newMode -band (-bnot $WinAPI::ENABLE_INSERT_MODE)
|
||||||
|
$doingSomething = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($doingSomething) {
|
||||||
|
echo "old mode: $oldMode"
|
||||||
|
SetConsoleMode $newMode
|
||||||
|
$newMode = GetConsoleMode
|
||||||
|
echo "new mode: $newMode"
|
||||||
|
} else {
|
||||||
|
echo "mode: $oldMode"
|
||||||
|
}
|
||||||
+113
@@ -0,0 +1,113 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
static HANDLE getConout() {
|
||||||
|
HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if (conout == INVALID_HANDLE_VALUE) {
|
||||||
|
fprintf(stderr, "error: cannot get stdout\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return conout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD getConsoleMode() {
|
||||||
|
DWORD mode = 0;
|
||||||
|
if (!GetConsoleMode(getConout(), &mode)) {
|
||||||
|
fprintf(stderr, "error: GetConsoleMode failed (is stdout a console?)\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setConsoleMode(DWORD mode) {
|
||||||
|
if (!SetConsoleMode(getConout(), mode)) {
|
||||||
|
fprintf(stderr, "error: SetConsoleMode failed (is stdout a console?)\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long parseInt(const std::string &s) {
|
||||||
|
errno = 0;
|
||||||
|
char *endptr = nullptr;
|
||||||
|
long result = strtol(s.c_str(), &endptr, 0);
|
||||||
|
if (errno != 0 || !endptr || *endptr != '\0') {
|
||||||
|
fprintf(stderr, "error: could not parse integral argument '%s'\n", s.c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
printf("Usage: ConoutMode [verb] [options]\n");
|
||||||
|
printf("Verbs:\n");
|
||||||
|
printf(" [info] Dumps info about mode flags.\n");
|
||||||
|
printf(" get Prints the mode DWORD.\n");
|
||||||
|
printf(" set VALUE Sets the mode to VALUE, which can be decimal, hex, or octal.\n");
|
||||||
|
printf(" set VALUE MASK\n");
|
||||||
|
printf(" Same as `set VALUE`, but only alters the bits in MASK.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
DWORD value;
|
||||||
|
} kOutputFlags[] = {
|
||||||
|
"ENABLE_PROCESSED_OUTPUT", ENABLE_PROCESSED_OUTPUT, // 0x0001
|
||||||
|
"ENABLE_WRAP_AT_EOL_OUTPUT", ENABLE_WRAP_AT_EOL_OUTPUT, // 0x0002
|
||||||
|
"ENABLE_VIRTUAL_TERMINAL_PROCESSING", 0x0004/*ENABLE_VIRTUAL_TERMINAL_PROCESSING*/, // 0x0004
|
||||||
|
"DISABLE_NEWLINE_AUTO_RETURN", 0x0008/*DISABLE_NEWLINE_AUTO_RETURN*/, // 0x0008
|
||||||
|
"ENABLE_LVB_GRID_WORLDWIDE", 0x0010/*ENABLE_LVB_GRID_WORLDWIDE*/, //0x0010
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
std::vector<std::string> args;
|
||||||
|
for (size_t i = 1; i < argc; ++i) {
|
||||||
|
args.push_back(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.empty() || args.size() == 1 && args[0] == "info") {
|
||||||
|
DWORD mode = getConsoleMode();
|
||||||
|
printf("mode: 0x%lx\n", mode);
|
||||||
|
for (const auto &flag : kOutputFlags) {
|
||||||
|
printf("%-34s 0x%04lx %s\n", flag.name, flag.value, flag.value & mode ? "ON" : "off");
|
||||||
|
mode &= ~flag.value;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
if (mode & (1u << i)) {
|
||||||
|
printf("Unrecognized flag: %04x\n", (1u << i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto verb = args[0];
|
||||||
|
|
||||||
|
if (verb == "set") {
|
||||||
|
if (args.size() == 2) {
|
||||||
|
const DWORD newMode = parseInt(args[1]);
|
||||||
|
setConsoleMode(newMode);
|
||||||
|
} else if (args.size() == 3) {
|
||||||
|
const DWORD mode = parseInt(args[1]);
|
||||||
|
const DWORD mask = parseInt(args[2]);
|
||||||
|
const int newMode = (getConsoleMode() & ~mask) | (mode & mask);
|
||||||
|
setConsoleMode(newMode);
|
||||||
|
} else {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
} else if (verb == "get") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
printf("0x%lx\n", getConsoleMode());
|
||||||
|
} else {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
#!python
|
||||||
|
# Run with native CPython. Needs pywin32 extensions.
|
||||||
|
|
||||||
|
# Copyright (c) 2011-2012 Ryan Prichard
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
import winerror
|
||||||
|
import win32pipe
|
||||||
|
import win32file
|
||||||
|
import win32api
|
||||||
|
import sys
|
||||||
|
import pywintypes
|
||||||
|
import time
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: %s message" % sys.argv[0])
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
message = "[%05.3f %s]: %s" % (time.time() % 100000, sys.argv[0], sys.argv[1])
|
||||||
|
|
||||||
|
win32pipe.CallNamedPipe(
|
||||||
|
"\\\\.\\pipe\\DebugServer",
|
||||||
|
message.encode(),
|
||||||
|
16,
|
||||||
|
win32pipe.NMPWAIT_WAIT_FOREVER)
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!python
|
||||||
|
#
|
||||||
|
# Run with native CPython. Needs pywin32 extensions.
|
||||||
|
|
||||||
|
# Copyright (c) 2011-2012 Ryan Prichard
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
import win32pipe
|
||||||
|
import win32api
|
||||||
|
import win32file
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# A message may not be larger than this size.
|
||||||
|
MSG_SIZE=4096
|
||||||
|
|
||||||
|
serverPipe = win32pipe.CreateNamedPipe(
|
||||||
|
"\\\\.\\pipe\\DebugServer",
|
||||||
|
win32pipe.PIPE_ACCESS_DUPLEX,
|
||||||
|
win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE,
|
||||||
|
win32pipe.PIPE_UNLIMITED_INSTANCES,
|
||||||
|
MSG_SIZE,
|
||||||
|
MSG_SIZE,
|
||||||
|
10 * 1000,
|
||||||
|
None)
|
||||||
|
while True:
|
||||||
|
win32pipe.ConnectNamedPipe(serverPipe, None)
|
||||||
|
(ret, data) = win32file.ReadFile(serverPipe, MSG_SIZE)
|
||||||
|
print(data.decode())
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
# The client uses CallNamedPipe to send its message. CallNamedPipe waits
|
||||||
|
# for a reply message. If I send a reply, however, using WriteFile, then
|
||||||
|
# sometimes WriteFile fails with:
|
||||||
|
# pywintypes.error: (232, 'WriteFile', 'The pipe is being closed.')
|
||||||
|
# I can't figure out how to write a strictly correct pipe server, but if
|
||||||
|
# I comment out the WriteFile line, then everything seems to work. I
|
||||||
|
# think the DisconnectNamedPipe call aborts the client's CallNamedPipe
|
||||||
|
# call normally.
|
||||||
|
|
||||||
|
try:
|
||||||
|
win32file.WriteFile(serverPipe, b'OK')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
win32pipe.DisconnectNamedPipe(serverPipe)
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import sys
|
||||||
|
|
||||||
|
for i in range(1, int(sys.argv[1]) + 1):
|
||||||
|
print i, "X" * 78
|
||||||
Generated
Vendored
+46
@@ -0,0 +1,46 @@
|
|||||||
|
Note regarding ENABLE_EXTENDED_FLAGS (2016-05-30)
|
||||||
|
|
||||||
|
There is a complicated interaction between the ENABLE_EXTENDED_FLAGS flag
|
||||||
|
and the ENABLE_QUICK_EDIT_MODE and ENABLE_INSERT_MODE flags (presumably for
|
||||||
|
backwards compatibility?). I studied the behavior on Windows 7 and Windows
|
||||||
|
10, with both the old and new consoles, and I didn't see any differences
|
||||||
|
between versions. Here's what I seemed to observe:
|
||||||
|
|
||||||
|
- The console has three flags internally:
|
||||||
|
- QuickEdit
|
||||||
|
- InsertMode
|
||||||
|
- ExtendedFlags
|
||||||
|
|
||||||
|
- SetConsoleMode psuedocode:
|
||||||
|
void SetConsoleMode(..., DWORD mode) {
|
||||||
|
ExtendedFlags = (mode & (ENABLE_EXTENDED_FLAGS
|
||||||
|
| ENABLE_QUICK_EDIT_MODE
|
||||||
|
| ENABLE_INSERT_MODE )) != 0;
|
||||||
|
if (ExtendedFlags) {
|
||||||
|
QuickEdit = (mode & ENABLE_QUICK_EDIT_MODE) != 0;
|
||||||
|
InsertMode = (mode & ENABLE_INSERT_MODE) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- Setting QuickEdit or InsertMode from the properties dialog GUI does not
|
||||||
|
affect the ExtendedFlags setting -- it simply toggles the one flag.
|
||||||
|
|
||||||
|
- GetConsoleMode psuedocode:
|
||||||
|
GetConsoleMode(..., DWORD *result) {
|
||||||
|
if (ExtendedFlags) {
|
||||||
|
*result |= ENABLE_EXTENDED_FLAGS;
|
||||||
|
if (QuickEdit) { *result |= ENABLE_QUICK_EDIT_MODE; }
|
||||||
|
if (InsertMode) { *result |= ENABLE_INSERT_MODE; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Effectively, the ExtendedFlags flags controls whether the other two flags
|
||||||
|
are visible/controlled by the user application. If they aren't visible,
|
||||||
|
though, there is no way for the user application to make them visible,
|
||||||
|
except by overwriting their values! Calling SetConsoleMode with just
|
||||||
|
ENABLE_EXTENDED_FLAGS would clear the extended flags we want to read.
|
||||||
|
|
||||||
|
Consequently, if a program temporarily alters the QuickEdit flag (e.g. to
|
||||||
|
enable mouse input), it cannot restore the original values of the QuickEdit
|
||||||
|
and InsertMode flags, UNLESS every other console program cooperates by
|
||||||
|
keeping the ExtendedFlags flag set.
|
||||||
Generated
Vendored
+528
@@ -0,0 +1,528 @@
|
|||||||
|
==================================
|
||||||
|
Code Page 437, Consolas font
|
||||||
|
==================================
|
||||||
|
|
||||||
|
Options: -face "Consolas" -family 0x36
|
||||||
|
Chars: A2 A3 2014 3044 30FC 4000
|
||||||
|
|
||||||
|
FontSurvey "-face \"Consolas\" -family 0x36"
|
||||||
|
|
||||||
|
Windows 7
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,3 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 1,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 2,5 BAD (HHHHHH)
|
||||||
|
Size 6: 3,6 BAD (HHHHHH)
|
||||||
|
Size 7: 3,6 BAD (HHHHHH)
|
||||||
|
Size 8: 4,8 BAD (HHHHHH)
|
||||||
|
Size 9: 4,9 BAD (HHHHHH)
|
||||||
|
Size 10: 5,10 BAD (HHHHHH)
|
||||||
|
Size 11: 5,11 BAD (HHHHHH)
|
||||||
|
Size 12: 6,12 BAD (HHHHHH)
|
||||||
|
Size 13: 6,13 BAD (HHHHHH)
|
||||||
|
Size 14: 7,14 BAD (HHHHHH)
|
||||||
|
Size 15: 7,15 BAD (HHHHHH)
|
||||||
|
Size 16: 8,16 BAD (HHHHHH)
|
||||||
|
Size 17: 8,17 BAD (HHHHHH)
|
||||||
|
Size 18: 8,18 BAD (HHHHHH)
|
||||||
|
Size 19: 9,19 BAD (HHHHHH)
|
||||||
|
Size 20: 9,20 BAD (HHHHHH)
|
||||||
|
Size 21: 10,22 BAD (HHHHHH)
|
||||||
|
Size 22: 10,22 BAD (HHHHHH)
|
||||||
|
Size 23: 11,23 BAD (HHHHHH)
|
||||||
|
Size 24: 11,24 BAD (HHHHHH)
|
||||||
|
Size 25: 12,25 BAD (HHHHHH)
|
||||||
|
Size 26: 12,26 BAD (HHHHHH)
|
||||||
|
Size 27: 13,27 BAD (HHHHHH)
|
||||||
|
Size 28: 13,28 BAD (HHHHHH)
|
||||||
|
Size 29: 14,29 BAD (HHHHHH)
|
||||||
|
Size 30: 14,30 BAD (HHHHHH)
|
||||||
|
Size 31: 15,31 BAD (HHHHHH)
|
||||||
|
Size 32: 15,32 BAD (HHHHHH)
|
||||||
|
Size 33: 15,33 BAD (HHHHHH)
|
||||||
|
Size 34: 16,34 BAD (HHHHHH)
|
||||||
|
Size 35: 16,36 BAD (HHHHHH)
|
||||||
|
Size 36: 17,36 BAD (HHHHHH)
|
||||||
|
Size 37: 17,37 BAD (HHHHHH)
|
||||||
|
Size 38: 18,38 BAD (HHHHHH)
|
||||||
|
Size 39: 18,39 BAD (HHHHHH)
|
||||||
|
Size 40: 19,40 BAD (HHHHHH)
|
||||||
|
Size 41: 19,41 BAD (HHHHHH)
|
||||||
|
Size 42: 20,42 BAD (HHHHHH)
|
||||||
|
Size 43: 20,43 BAD (HHHHHH)
|
||||||
|
Size 44: 21,44 BAD (HHHHHH)
|
||||||
|
Size 45: 21,45 BAD (HHHHHH)
|
||||||
|
Size 46: 22,46 BAD (HHHHHH)
|
||||||
|
Size 47: 22,47 BAD (HHHHHH)
|
||||||
|
Size 48: 23,48 BAD (HHHHHH)
|
||||||
|
Size 49: 23,49 BAD (HHHHHH)
|
||||||
|
Size 50: 23,50 BAD (HHHHHH)
|
||||||
|
Size 51: 24,51 BAD (HHHHHH)
|
||||||
|
Size 52: 24,52 BAD (HHHHHH)
|
||||||
|
Size 53: 25,53 BAD (HHHHHH)
|
||||||
|
Size 54: 25,54 BAD (HHHHHH)
|
||||||
|
Size 55: 26,55 BAD (HHHHHH)
|
||||||
|
Size 56: 26,56 BAD (HHHHHH)
|
||||||
|
Size 57: 27,57 BAD (HHHHHH)
|
||||||
|
Size 58: 27,58 BAD (HHHHHH)
|
||||||
|
Size 59: 28,59 BAD (HHHHHH)
|
||||||
|
Size 60: 28,60 BAD (HHHHHH)
|
||||||
|
Size 61: 29,61 BAD (HHHHHH)
|
||||||
|
Size 62: 29,62 BAD (HHHHHH)
|
||||||
|
Size 63: 30,64 BAD (HHHHHH)
|
||||||
|
Size 64: 30,64 BAD (HHHHHH)
|
||||||
|
Size 65: 31,65 BAD (HHHHHH)
|
||||||
|
Size 66: 31,66 BAD (HHHHHH)
|
||||||
|
Size 67: 31,67 BAD (HHHHHH)
|
||||||
|
Size 68: 32,68 BAD (HHHHHH)
|
||||||
|
Size 69: 32,69 BAD (HHHHHH)
|
||||||
|
Size 70: 33,70 BAD (HHHHHH)
|
||||||
|
Size 71: 33,71 BAD (HHHHHH)
|
||||||
|
Size 72: 34,72 BAD (HHHHHH)
|
||||||
|
Size 73: 34,73 BAD (HHHHHH)
|
||||||
|
Size 74: 35,74 BAD (HHHHHH)
|
||||||
|
Size 75: 35,75 BAD (HHHHHH)
|
||||||
|
Size 76: 36,76 BAD (HHHHHH)
|
||||||
|
Size 77: 36,77 BAD (HHHHHH)
|
||||||
|
Size 78: 37,78 BAD (HHHHHH)
|
||||||
|
Size 79: 37,79 BAD (HHHHHH)
|
||||||
|
Size 80: 38,80 BAD (HHHHHH)
|
||||||
|
Size 81: 38,81 BAD (HHHHHH)
|
||||||
|
Size 82: 39,82 BAD (HHHHHH)
|
||||||
|
Size 83: 39,83 BAD (HHHHHH)
|
||||||
|
Size 84: 39,84 BAD (HHHHHH)
|
||||||
|
Size 85: 40,85 BAD (HHHHHH)
|
||||||
|
Size 86: 40,86 BAD (HHHHHH)
|
||||||
|
Size 87: 41,87 BAD (HHHHHH)
|
||||||
|
Size 88: 41,88 BAD (HHHHHH)
|
||||||
|
Size 89: 42,89 BAD (HHHHHH)
|
||||||
|
Size 90: 42,90 BAD (HHHHHH)
|
||||||
|
Size 91: 43,91 BAD (HHHHHH)
|
||||||
|
Size 92: 43,92 BAD (HHHHHH)
|
||||||
|
Size 93: 44,93 BAD (HHHHHH)
|
||||||
|
Size 94: 44,94 BAD (HHHHHH)
|
||||||
|
Size 95: 45,95 BAD (HHHHHH)
|
||||||
|
Size 96: 45,96 BAD (HHHHHH)
|
||||||
|
Size 97: 46,97 BAD (HHHHHH)
|
||||||
|
Size 98: 46,98 BAD (HHHHHH)
|
||||||
|
Size 99: 46,99 BAD (HHHHHH)
|
||||||
|
Size 100: 47,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 8
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,3 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 1,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 2,5 BAD (HHHHHH)
|
||||||
|
Size 6: 3,6 BAD (HHHHHH)
|
||||||
|
Size 7: 3,6 BAD (HHHHHH)
|
||||||
|
Size 8: 4,8 BAD (HHHHHH)
|
||||||
|
Size 9: 4,9 BAD (HHHHHH)
|
||||||
|
Size 10: 5,10 BAD (HHHHHH)
|
||||||
|
Size 11: 5,11 BAD (HHHHHH)
|
||||||
|
Size 12: 6,12 BAD (HHHHHH)
|
||||||
|
Size 13: 6,13 BAD (HHHHHH)
|
||||||
|
Size 14: 7,14 BAD (HHHHHH)
|
||||||
|
Size 15: 7,15 BAD (HHHHHH)
|
||||||
|
Size 16: 8,16 BAD (HHHHHH)
|
||||||
|
Size 17: 8,17 BAD (HHHHHH)
|
||||||
|
Size 18: 8,18 BAD (HHHHHH)
|
||||||
|
Size 19: 9,19 BAD (HHHHHH)
|
||||||
|
Size 20: 9,20 BAD (HHHHHH)
|
||||||
|
Size 21: 10,22 BAD (HHHHHH)
|
||||||
|
Size 22: 10,22 BAD (HHHHHH)
|
||||||
|
Size 23: 11,23 BAD (HHHHHH)
|
||||||
|
Size 24: 11,24 BAD (HHHHHH)
|
||||||
|
Size 25: 12,25 BAD (HHHHHH)
|
||||||
|
Size 26: 12,26 BAD (HHHHHH)
|
||||||
|
Size 27: 13,27 BAD (HHHHHH)
|
||||||
|
Size 28: 13,28 BAD (HHHHHH)
|
||||||
|
Size 29: 14,29 BAD (HHHHHH)
|
||||||
|
Size 30: 14,30 BAD (HHHHHH)
|
||||||
|
Size 31: 15,31 BAD (HHHHHH)
|
||||||
|
Size 32: 15,32 BAD (HHHHHH)
|
||||||
|
Size 33: 15,33 BAD (HHHHHH)
|
||||||
|
Size 34: 16,34 BAD (HHHHHH)
|
||||||
|
Size 35: 16,36 BAD (HHHHHH)
|
||||||
|
Size 36: 17,36 BAD (HHHHHH)
|
||||||
|
Size 37: 17,37 BAD (HHHHHH)
|
||||||
|
Size 38: 18,38 BAD (HHHHHH)
|
||||||
|
Size 39: 18,39 BAD (HHHHHH)
|
||||||
|
Size 40: 19,40 BAD (HHHHHH)
|
||||||
|
Size 41: 19,41 BAD (HHHHHH)
|
||||||
|
Size 42: 20,42 BAD (HHHHHH)
|
||||||
|
Size 43: 20,43 BAD (HHHHHH)
|
||||||
|
Size 44: 21,44 BAD (HHHHHH)
|
||||||
|
Size 45: 21,45 BAD (HHHHHH)
|
||||||
|
Size 46: 22,46 BAD (HHHHHH)
|
||||||
|
Size 47: 22,47 BAD (HHHHHH)
|
||||||
|
Size 48: 23,48 BAD (HHHHHH)
|
||||||
|
Size 49: 23,49 BAD (HHHHHH)
|
||||||
|
Size 50: 23,50 BAD (HHHHHH)
|
||||||
|
Size 51: 24,51 BAD (HHHHHH)
|
||||||
|
Size 52: 24,52 BAD (HHHHHH)
|
||||||
|
Size 53: 25,53 BAD (HHHHHH)
|
||||||
|
Size 54: 25,54 BAD (HHHHHH)
|
||||||
|
Size 55: 26,55 BAD (HHHHHH)
|
||||||
|
Size 56: 26,56 BAD (HHHHHH)
|
||||||
|
Size 57: 27,57 BAD (HHHHHH)
|
||||||
|
Size 58: 27,58 BAD (HHHHHH)
|
||||||
|
Size 59: 28,59 BAD (HHHHHH)
|
||||||
|
Size 60: 28,60 BAD (HHHHHH)
|
||||||
|
Size 61: 29,61 BAD (HHHHHH)
|
||||||
|
Size 62: 29,62 BAD (HHHHHH)
|
||||||
|
Size 63: 30,64 BAD (HHHHHH)
|
||||||
|
Size 64: 30,64 BAD (HHHHHH)
|
||||||
|
Size 65: 31,65 BAD (HHHHHH)
|
||||||
|
Size 66: 31,66 BAD (HHHHHH)
|
||||||
|
Size 67: 31,67 BAD (HHHHHH)
|
||||||
|
Size 68: 32,68 BAD (HHHHHH)
|
||||||
|
Size 69: 32,69 BAD (HHHHHH)
|
||||||
|
Size 70: 33,70 BAD (HHHHHH)
|
||||||
|
Size 71: 33,71 BAD (HHHHHH)
|
||||||
|
Size 72: 34,72 BAD (HHHHHH)
|
||||||
|
Size 73: 34,73 BAD (HHHHHH)
|
||||||
|
Size 74: 35,74 BAD (HHHHHH)
|
||||||
|
Size 75: 35,75 BAD (HHHHHH)
|
||||||
|
Size 76: 36,76 BAD (HHHHHH)
|
||||||
|
Size 77: 36,77 BAD (HHHHHH)
|
||||||
|
Size 78: 37,78 BAD (HHHHHH)
|
||||||
|
Size 79: 37,79 BAD (HHHHHH)
|
||||||
|
Size 80: 38,80 BAD (HHHHHH)
|
||||||
|
Size 81: 38,81 BAD (HHHHHH)
|
||||||
|
Size 82: 39,82 BAD (HHHHHH)
|
||||||
|
Size 83: 39,83 BAD (HHHHHH)
|
||||||
|
Size 84: 39,84 BAD (HHHHHH)
|
||||||
|
Size 85: 40,85 BAD (HHHHHH)
|
||||||
|
Size 86: 40,86 BAD (HHHHHH)
|
||||||
|
Size 87: 41,87 BAD (HHHHHH)
|
||||||
|
Size 88: 41,88 BAD (HHHHHH)
|
||||||
|
Size 89: 42,89 BAD (HHHHHH)
|
||||||
|
Size 90: 42,90 BAD (HHHHHH)
|
||||||
|
Size 91: 43,91 BAD (HHHHHH)
|
||||||
|
Size 92: 43,92 BAD (HHHHHH)
|
||||||
|
Size 93: 44,93 BAD (HHHHHH)
|
||||||
|
Size 94: 44,94 BAD (HHHHHH)
|
||||||
|
Size 95: 45,95 BAD (HHHHHH)
|
||||||
|
Size 96: 45,96 BAD (HHHHHH)
|
||||||
|
Size 97: 46,97 BAD (HHHHHH)
|
||||||
|
Size 98: 46,98 BAD (HHHHHH)
|
||||||
|
Size 99: 46,99 BAD (HHHHHH)
|
||||||
|
Size 100: 47,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 8.1
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Size 1: 1,3 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 1,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 2,5 BAD (HHHHHH)
|
||||||
|
Size 6: 3,6 BAD (HHHHHH)
|
||||||
|
Size 7: 3,6 BAD (HHHHHH)
|
||||||
|
Size 8: 4,8 BAD (HHHHHH)
|
||||||
|
Size 9: 4,9 BAD (HHHHHH)
|
||||||
|
Size 10: 5,10 BAD (HHHHHH)
|
||||||
|
Size 11: 5,11 BAD (HHHHHH)
|
||||||
|
Size 12: 6,12 BAD (HHHHHH)
|
||||||
|
Size 13: 6,13 BAD (HHHHHH)
|
||||||
|
Size 14: 7,14 BAD (HHHHHH)
|
||||||
|
Size 15: 7,15 BAD (HHHHHH)
|
||||||
|
Size 16: 8,16 BAD (HHHHHH)
|
||||||
|
Size 17: 8,17 BAD (HHHHHH)
|
||||||
|
Size 18: 8,18 BAD (HHHHHH)
|
||||||
|
Size 19: 9,19 BAD (HHHHHH)
|
||||||
|
Size 20: 9,20 BAD (HHHHHH)
|
||||||
|
Size 21: 10,22 BAD (HHHHHH)
|
||||||
|
Size 22: 10,22 BAD (HHHHHH)
|
||||||
|
Size 23: 11,23 BAD (HHHHHH)
|
||||||
|
Size 24: 11,24 BAD (HHHHHH)
|
||||||
|
Size 25: 12,25 BAD (HHHHHH)
|
||||||
|
Size 26: 12,26 BAD (HHHHHH)
|
||||||
|
Size 27: 13,27 BAD (HHHHHH)
|
||||||
|
Size 28: 13,28 BAD (HHHHHH)
|
||||||
|
Size 29: 14,29 BAD (HHHHHH)
|
||||||
|
Size 30: 14,30 BAD (HHHHHH)
|
||||||
|
Size 31: 15,31 BAD (HHHHHH)
|
||||||
|
Size 32: 15,32 BAD (HHHHHH)
|
||||||
|
Size 33: 15,33 BAD (HHHHHH)
|
||||||
|
Size 34: 16,34 BAD (HHHHHH)
|
||||||
|
Size 35: 16,36 BAD (HHHHHH)
|
||||||
|
Size 36: 17,36 BAD (HHHHHH)
|
||||||
|
Size 37: 17,37 BAD (HHHHHH)
|
||||||
|
Size 38: 18,38 BAD (HHHHHH)
|
||||||
|
Size 39: 18,39 BAD (HHHHHH)
|
||||||
|
Size 40: 19,40 BAD (HHHHHH)
|
||||||
|
Size 41: 19,41 BAD (HHHHHH)
|
||||||
|
Size 42: 20,42 BAD (HHHHHH)
|
||||||
|
Size 43: 20,43 BAD (HHHHHH)
|
||||||
|
Size 44: 21,44 BAD (HHHHHH)
|
||||||
|
Size 45: 21,45 BAD (HHHHHH)
|
||||||
|
Size 46: 22,46 BAD (HHHHHH)
|
||||||
|
Size 47: 22,47 BAD (HHHHHH)
|
||||||
|
Size 48: 23,48 BAD (HHHHHH)
|
||||||
|
Size 49: 23,49 BAD (HHHHHH)
|
||||||
|
Size 50: 23,50 BAD (HHHHHH)
|
||||||
|
Size 51: 24,51 BAD (HHHHHH)
|
||||||
|
Size 52: 24,52 BAD (HHHHHH)
|
||||||
|
Size 53: 25,53 BAD (HHHHHH)
|
||||||
|
Size 54: 25,54 BAD (HHHHHH)
|
||||||
|
Size 55: 26,55 BAD (HHHHHH)
|
||||||
|
Size 56: 26,56 BAD (HHHHHH)
|
||||||
|
Size 57: 27,57 BAD (HHHHHH)
|
||||||
|
Size 58: 27,58 BAD (HHHHHH)
|
||||||
|
Size 59: 28,59 BAD (HHHHHH)
|
||||||
|
Size 60: 28,60 BAD (HHHHHH)
|
||||||
|
Size 61: 29,61 BAD (HHHHHH)
|
||||||
|
Size 62: 29,62 BAD (HHHHHH)
|
||||||
|
Size 63: 30,64 BAD (HHHHHH)
|
||||||
|
Size 64: 30,64 BAD (HHHHHH)
|
||||||
|
Size 65: 31,65 BAD (HHHHHH)
|
||||||
|
Size 66: 31,66 BAD (HHHHHH)
|
||||||
|
Size 67: 31,67 BAD (HHHHHH)
|
||||||
|
Size 68: 32,68 BAD (HHHHHH)
|
||||||
|
Size 69: 32,69 BAD (HHHHHH)
|
||||||
|
Size 70: 33,70 BAD (HHHHHH)
|
||||||
|
Size 71: 33,71 BAD (HHHHHH)
|
||||||
|
Size 72: 34,72 BAD (HHHHHH)
|
||||||
|
Size 73: 34,73 BAD (HHHHHH)
|
||||||
|
Size 74: 35,74 BAD (HHHHHH)
|
||||||
|
Size 75: 35,75 BAD (HHHHHH)
|
||||||
|
Size 76: 36,76 BAD (HHHHHH)
|
||||||
|
Size 77: 36,77 BAD (HHHHHH)
|
||||||
|
Size 78: 37,78 BAD (HHHHHH)
|
||||||
|
Size 79: 37,79 BAD (HHHHHH)
|
||||||
|
Size 80: 38,80 BAD (HHHHHH)
|
||||||
|
Size 81: 38,81 BAD (HHHHHH)
|
||||||
|
Size 82: 39,82 BAD (HHHHHH)
|
||||||
|
Size 83: 39,83 BAD (HHHHHH)
|
||||||
|
Size 84: 39,84 BAD (HHHHHH)
|
||||||
|
Size 85: 40,85 BAD (HHHHHH)
|
||||||
|
Size 86: 40,86 BAD (HHHHHH)
|
||||||
|
Size 87: 41,87 BAD (HHHHHH)
|
||||||
|
Size 88: 41,88 BAD (HHHHHH)
|
||||||
|
Size 89: 42,89 BAD (HHHHHH)
|
||||||
|
Size 90: 42,90 BAD (HHHHHH)
|
||||||
|
Size 91: 43,91 BAD (HHHHHH)
|
||||||
|
Size 92: 43,92 BAD (HHHHHH)
|
||||||
|
Size 93: 44,93 BAD (HHHHHH)
|
||||||
|
Size 94: 44,94 BAD (HHHHHH)
|
||||||
|
Size 95: 45,95 BAD (HHHHHH)
|
||||||
|
Size 96: 45,96 BAD (HHHHHH)
|
||||||
|
Size 97: 46,97 BAD (HHHHHH)
|
||||||
|
Size 98: 46,98 BAD (HHHHHH)
|
||||||
|
Size 99: 46,99 BAD (HHHHHH)
|
||||||
|
Size 100: 47,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 10 14342 Old Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,3 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 1,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 2,5 BAD (HHHHHH)
|
||||||
|
Size 6: 3,6 BAD (HHHHHH)
|
||||||
|
Size 7: 3,6 BAD (HHHHHH)
|
||||||
|
Size 8: 4,8 BAD (HHHHHH)
|
||||||
|
Size 9: 4,9 BAD (HHHHHH)
|
||||||
|
Size 10: 5,10 BAD (HHHHHH)
|
||||||
|
Size 11: 5,11 BAD (HHHHHH)
|
||||||
|
Size 12: 6,12 BAD (HHHHHH)
|
||||||
|
Size 13: 6,13 BAD (HHHHHH)
|
||||||
|
Size 14: 7,14 BAD (HHHHHH)
|
||||||
|
Size 15: 7,15 BAD (HHHHHH)
|
||||||
|
Size 16: 8,16 BAD (HHHHHH)
|
||||||
|
Size 17: 8,17 BAD (HHHHHH)
|
||||||
|
Size 18: 8,18 BAD (HHHHHH)
|
||||||
|
Size 19: 9,19 BAD (HHHHHH)
|
||||||
|
Size 20: 9,20 BAD (HHHHHH)
|
||||||
|
Size 21: 10,22 BAD (HHHHHH)
|
||||||
|
Size 22: 10,22 BAD (HHHHHH)
|
||||||
|
Size 23: 11,23 BAD (HHHHHH)
|
||||||
|
Size 24: 11,24 BAD (HHHHHH)
|
||||||
|
Size 25: 12,25 BAD (HHHHHH)
|
||||||
|
Size 26: 12,26 BAD (HHHHHH)
|
||||||
|
Size 27: 13,27 BAD (HHHHHH)
|
||||||
|
Size 28: 13,28 BAD (HHHHHH)
|
||||||
|
Size 29: 14,29 BAD (HHHHHH)
|
||||||
|
Size 30: 14,30 BAD (HHHHHH)
|
||||||
|
Size 31: 15,31 BAD (HHHHHH)
|
||||||
|
Size 32: 15,32 BAD (HHHHHH)
|
||||||
|
Size 33: 15,33 BAD (HHHHHH)
|
||||||
|
Size 34: 16,34 BAD (HHHHHH)
|
||||||
|
Size 35: 16,36 BAD (HHHHHH)
|
||||||
|
Size 36: 17,36 BAD (HHHHHH)
|
||||||
|
Size 37: 17,37 BAD (HHHHHH)
|
||||||
|
Size 38: 18,38 BAD (HHHHHH)
|
||||||
|
Size 39: 18,39 BAD (HHHHHH)
|
||||||
|
Size 40: 19,40 BAD (HHHHHH)
|
||||||
|
Size 41: 19,41 BAD (HHHHHH)
|
||||||
|
Size 42: 20,42 BAD (HHHHHH)
|
||||||
|
Size 43: 20,43 BAD (HHHHHH)
|
||||||
|
Size 44: 21,44 BAD (HHHHHH)
|
||||||
|
Size 45: 21,45 BAD (HHHHHH)
|
||||||
|
Size 46: 22,46 BAD (HHHHHH)
|
||||||
|
Size 47: 22,47 BAD (HHHHHH)
|
||||||
|
Size 48: 23,48 BAD (HHHHHH)
|
||||||
|
Size 49: 23,49 BAD (HHHHHH)
|
||||||
|
Size 50: 23,50 BAD (HHHHHH)
|
||||||
|
Size 51: 24,51 BAD (HHHHHH)
|
||||||
|
Size 52: 24,52 BAD (HHHHHH)
|
||||||
|
Size 53: 25,53 BAD (HHHHHH)
|
||||||
|
Size 54: 25,54 BAD (HHHHHH)
|
||||||
|
Size 55: 26,55 BAD (HHHHHH)
|
||||||
|
Size 56: 26,56 BAD (HHHHHH)
|
||||||
|
Size 57: 27,57 BAD (HHHHHH)
|
||||||
|
Size 58: 27,58 BAD (HHHHHH)
|
||||||
|
Size 59: 28,59 BAD (HHHHHH)
|
||||||
|
Size 60: 28,60 BAD (HHHHHH)
|
||||||
|
Size 61: 29,61 BAD (HHHHHH)
|
||||||
|
Size 62: 29,62 BAD (HHHHHH)
|
||||||
|
Size 63: 30,64 BAD (HHHHHH)
|
||||||
|
Size 64: 30,64 BAD (HHHHHH)
|
||||||
|
Size 65: 31,65 BAD (HHHHHH)
|
||||||
|
Size 66: 31,66 BAD (HHHHHH)
|
||||||
|
Size 67: 31,67 BAD (HHHHHH)
|
||||||
|
Size 68: 32,68 BAD (HHHHHH)
|
||||||
|
Size 69: 32,69 BAD (HHHHHH)
|
||||||
|
Size 70: 33,70 BAD (HHHHHH)
|
||||||
|
Size 71: 33,71 BAD (HHHHHH)
|
||||||
|
Size 72: 34,72 BAD (HHHHHH)
|
||||||
|
Size 73: 34,73 BAD (HHHHHH)
|
||||||
|
Size 74: 35,74 BAD (HHHHHH)
|
||||||
|
Size 75: 35,75 BAD (HHHHHH)
|
||||||
|
Size 76: 36,76 BAD (HHHHHH)
|
||||||
|
Size 77: 36,77 BAD (HHHHHH)
|
||||||
|
Size 78: 37,78 BAD (HHHHHH)
|
||||||
|
Size 79: 37,79 BAD (HHHHHH)
|
||||||
|
Size 80: 38,80 BAD (HHHHHH)
|
||||||
|
Size 81: 38,81 BAD (HHHHHH)
|
||||||
|
Size 82: 39,82 BAD (HHHHHH)
|
||||||
|
Size 83: 39,83 BAD (HHHHHH)
|
||||||
|
Size 84: 39,84 BAD (HHHHHH)
|
||||||
|
Size 85: 40,85 BAD (HHHHHH)
|
||||||
|
Size 86: 40,86 BAD (HHHHHH)
|
||||||
|
Size 87: 41,87 BAD (HHHHHH)
|
||||||
|
Size 88: 41,88 BAD (HHHHHH)
|
||||||
|
Size 89: 42,89 BAD (HHHHHH)
|
||||||
|
Size 90: 42,90 BAD (HHHHHH)
|
||||||
|
Size 91: 43,91 BAD (HHHHHH)
|
||||||
|
Size 92: 43,92 BAD (HHHHHH)
|
||||||
|
Size 93: 44,93 BAD (HHHHHH)
|
||||||
|
Size 94: 44,94 BAD (HHHHHH)
|
||||||
|
Size 95: 45,95 BAD (HHHHHH)
|
||||||
|
Size 96: 45,96 BAD (HHHHHH)
|
||||||
|
Size 97: 46,97 BAD (HHHHHH)
|
||||||
|
Size 98: 46,98 BAD (HHHHHH)
|
||||||
|
Size 99: 46,99 BAD (HHHHHH)
|
||||||
|
Size 100: 47,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 10 14342 New Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,1 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 1,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 2,5 BAD (HHHHHH)
|
||||||
|
Size 6: 3,6 BAD (HHHHHH)
|
||||||
|
Size 7: 3,7 BAD (HHHHHH)
|
||||||
|
Size 8: 4,8 BAD (HHHHHH)
|
||||||
|
Size 9: 4,9 BAD (HHHHHH)
|
||||||
|
Size 10: 5,10 BAD (HHHHHH)
|
||||||
|
Size 11: 5,11 BAD (HHHHHH)
|
||||||
|
Size 12: 6,12 BAD (HHHHHH)
|
||||||
|
Size 13: 6,13 BAD (HHHHHH)
|
||||||
|
Size 14: 7,14 BAD (HHHHHH)
|
||||||
|
Size 15: 7,15 BAD (HHHHHH)
|
||||||
|
Size 16: 8,16 BAD (HHHHHH)
|
||||||
|
Size 17: 8,17 BAD (HHHHHH)
|
||||||
|
Size 18: 8,18 BAD (HHHHHH)
|
||||||
|
Size 19: 9,19 BAD (HHHHHH)
|
||||||
|
Size 20: 9,20 BAD (HHHHHH)
|
||||||
|
Size 21: 10,21 BAD (HHHHHH)
|
||||||
|
Size 22: 10,22 BAD (HHHHHH)
|
||||||
|
Size 23: 11,23 BAD (HHHHHH)
|
||||||
|
Size 24: 11,24 BAD (HHHHHH)
|
||||||
|
Size 25: 12,25 BAD (HHHHHH)
|
||||||
|
Size 26: 12,26 BAD (HHHHHH)
|
||||||
|
Size 27: 13,27 BAD (HHHHHH)
|
||||||
|
Size 28: 13,28 BAD (HHHHHH)
|
||||||
|
Size 29: 14,29 BAD (HHHHHH)
|
||||||
|
Size 30: 14,30 BAD (HHHHHH)
|
||||||
|
Size 31: 15,31 BAD (HHHHHH)
|
||||||
|
Size 32: 15,32 BAD (HHHHHH)
|
||||||
|
Size 33: 15,33 BAD (HHHHHH)
|
||||||
|
Size 34: 16,34 BAD (HHHHHH)
|
||||||
|
Size 35: 16,35 BAD (HHHHHH)
|
||||||
|
Size 36: 17,36 BAD (HHHHHH)
|
||||||
|
Size 37: 17,37 BAD (HHHHHH)
|
||||||
|
Size 38: 18,38 BAD (HHHHHH)
|
||||||
|
Size 39: 18,39 BAD (HHHHHH)
|
||||||
|
Size 40: 19,40 BAD (HHHHHH)
|
||||||
|
Size 41: 19,41 BAD (HHHHHH)
|
||||||
|
Size 42: 20,42 BAD (HHHHHH)
|
||||||
|
Size 43: 20,43 BAD (HHHHHH)
|
||||||
|
Size 44: 21,44 BAD (HHHHHH)
|
||||||
|
Size 45: 21,45 BAD (HHHHHH)
|
||||||
|
Size 46: 22,46 BAD (HHHHHH)
|
||||||
|
Size 47: 22,47 BAD (HHHHHH)
|
||||||
|
Size 48: 23,48 BAD (HHHHHH)
|
||||||
|
Size 49: 23,49 BAD (HHHHHH)
|
||||||
|
Size 50: 23,50 BAD (HHHHHH)
|
||||||
|
Size 51: 24,51 BAD (HHHHHH)
|
||||||
|
Size 52: 24,52 BAD (HHHHHH)
|
||||||
|
Size 53: 25,53 BAD (HHHHHH)
|
||||||
|
Size 54: 25,54 BAD (HHHHHH)
|
||||||
|
Size 55: 26,55 BAD (HHHHHH)
|
||||||
|
Size 56: 26,56 BAD (HHHHHH)
|
||||||
|
Size 57: 27,57 BAD (HHHHHH)
|
||||||
|
Size 58: 27,58 BAD (HHHHHH)
|
||||||
|
Size 59: 28,59 BAD (HHHHHH)
|
||||||
|
Size 60: 28,60 BAD (HHHHHH)
|
||||||
|
Size 61: 29,61 BAD (HHHHHH)
|
||||||
|
Size 62: 29,62 BAD (HHHHHH)
|
||||||
|
Size 63: 30,63 BAD (HHHHHH)
|
||||||
|
Size 64: 30,64 BAD (HHHHHH)
|
||||||
|
Size 65: 31,65 BAD (HHHHHH)
|
||||||
|
Size 66: 31,66 BAD (HHHHHH)
|
||||||
|
Size 67: 31,67 BAD (HHHHHH)
|
||||||
|
Size 68: 32,68 BAD (HHHHHH)
|
||||||
|
Size 69: 32,69 BAD (HHHHHH)
|
||||||
|
Size 70: 33,70 BAD (HHHHHH)
|
||||||
|
Size 71: 33,71 BAD (HHHHHH)
|
||||||
|
Size 72: 34,72 BAD (HHHHHH)
|
||||||
|
Size 73: 34,73 BAD (HHHHHH)
|
||||||
|
Size 74: 35,74 BAD (HHHHHH)
|
||||||
|
Size 75: 35,75 BAD (HHHHHH)
|
||||||
|
Size 76: 36,76 BAD (HHHHHH)
|
||||||
|
Size 77: 36,77 BAD (HHHHHH)
|
||||||
|
Size 78: 37,78 BAD (HHHHHH)
|
||||||
|
Size 79: 37,79 BAD (HHHHHH)
|
||||||
|
Size 80: 38,80 BAD (HHHHHH)
|
||||||
|
Size 81: 38,81 BAD (HHHHHH)
|
||||||
|
Size 82: 39,82 BAD (HHHHHH)
|
||||||
|
Size 83: 39,83 BAD (HHHHHH)
|
||||||
|
Size 84: 39,84 BAD (HHHHHH)
|
||||||
|
Size 85: 40,85 BAD (HHHHHH)
|
||||||
|
Size 86: 40,86 BAD (HHHHHH)
|
||||||
|
Size 87: 41,87 BAD (HHHHHH)
|
||||||
|
Size 88: 41,88 BAD (HHHHHH)
|
||||||
|
Size 89: 42,89 BAD (HHHHHH)
|
||||||
|
Size 90: 42,90 BAD (HHHHHH)
|
||||||
|
Size 91: 43,91 BAD (HHHHHH)
|
||||||
|
Size 92: 43,92 BAD (HHHHHH)
|
||||||
|
Size 93: 44,93 BAD (HHHHHH)
|
||||||
|
Size 94: 44,94 BAD (HHHHHH)
|
||||||
|
Size 95: 45,95 BAD (HHHHHH)
|
||||||
|
Size 96: 45,96 BAD (HHHHHH)
|
||||||
|
Size 97: 46,97 BAD (HHHHHH)
|
||||||
|
Size 98: 46,98 BAD (HHHHHH)
|
||||||
|
Size 99: 46,99 BAD (HHHHHH)
|
||||||
|
Size 100: 47,100 BAD (HHHHHH)
|
||||||
Generated
Vendored
+633
@@ -0,0 +1,633 @@
|
|||||||
|
==================================
|
||||||
|
Code Page 437, Lucida Console font
|
||||||
|
==================================
|
||||||
|
|
||||||
|
Options: -face "Lucida Console" -family 0x36
|
||||||
|
Chars: A2 A3 2014 3044 30FC 4000
|
||||||
|
|
||||||
|
FontSurvey "-face \"Lucida Console\" -family 0x36"
|
||||||
|
|
||||||
|
Vista
|
||||||
|
-----
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 2,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 3,5 BAD (HHHHHH)
|
||||||
|
Size 6: 4,6 BAD (HHHHHH)
|
||||||
|
Size 7: 4,7 BAD (HHHHHH)
|
||||||
|
Size 8: 5,8 BAD (HHHHHH)
|
||||||
|
Size 9: 5,9 BAD (HHHHHH)
|
||||||
|
Size 10: 6,10 BAD (HHHHHH)
|
||||||
|
Size 11: 7,11 BAD (HHHHHH)
|
||||||
|
Size 12: 7,12 BAD (HHHHHH)
|
||||||
|
Size 13: 8,13 BAD (HHHHHH)
|
||||||
|
Size 14: 8,14 BAD (HHHHHH)
|
||||||
|
Size 15: 9,15 BAD (HHHHHH)
|
||||||
|
Size 16: 10,16 BAD (HHHHHH)
|
||||||
|
Size 17: 10,17 BAD (HHHHHH)
|
||||||
|
Size 18: 11,18 BAD (HHHHHH)
|
||||||
|
Size 19: 11,19 BAD (HHHHHH)
|
||||||
|
Size 20: 12,20 BAD (HHHHHH)
|
||||||
|
Size 21: 13,21 BAD (HHHHHH)
|
||||||
|
Size 22: 13,22 BAD (HHHHHH)
|
||||||
|
Size 23: 14,23 BAD (HHHHHH)
|
||||||
|
Size 24: 14,24 BAD (HHHHHH)
|
||||||
|
Size 25: 15,25 BAD (HHHHHH)
|
||||||
|
Size 26: 16,26 BAD (HHHHHH)
|
||||||
|
Size 27: 16,27 BAD (HHHHHH)
|
||||||
|
Size 28: 17,28 BAD (HHHHHH)
|
||||||
|
Size 29: 17,29 BAD (HHHHHH)
|
||||||
|
Size 30: 18,30 BAD (HHHHHH)
|
||||||
|
Size 31: 19,31 BAD (HHHHHH)
|
||||||
|
Size 32: 19,32 BAD (HHHHHH)
|
||||||
|
Size 33: 20,33 BAD (HHHHHH)
|
||||||
|
Size 34: 20,34 BAD (HHHHHH)
|
||||||
|
Size 35: 21,35 BAD (HHHHHH)
|
||||||
|
Size 36: 22,36 BAD (HHHHHH)
|
||||||
|
Size 37: 22,37 BAD (HHHHHH)
|
||||||
|
Size 38: 23,38 BAD (HHHHHH)
|
||||||
|
Size 39: 23,39 BAD (HHHHHH)
|
||||||
|
Size 40: 24,40 BAD (HHHHHH)
|
||||||
|
Size 41: 25,41 BAD (HHHHHH)
|
||||||
|
Size 42: 25,42 BAD (HHHHHH)
|
||||||
|
Size 43: 26,43 BAD (HHHHHH)
|
||||||
|
Size 44: 27,44 BAD (HHHHHH)
|
||||||
|
Size 45: 27,45 BAD (HHHHHH)
|
||||||
|
Size 46: 28,46 BAD (HHHHHH)
|
||||||
|
Size 47: 28,47 BAD (HHHHHH)
|
||||||
|
Size 48: 29,48 BAD (HHHHHH)
|
||||||
|
Size 49: 30,49 BAD (HHHHHH)
|
||||||
|
Size 50: 30,50 BAD (HHHHHH)
|
||||||
|
Size 51: 31,51 BAD (HHHHHH)
|
||||||
|
Size 52: 31,52 BAD (HHHHHH)
|
||||||
|
Size 53: 32,53 BAD (HHHHHH)
|
||||||
|
Size 54: 33,54 BAD (HHHHHH)
|
||||||
|
Size 55: 33,55 BAD (HHHHHH)
|
||||||
|
Size 56: 34,56 BAD (HHHHHH)
|
||||||
|
Size 57: 34,57 BAD (HHHHHH)
|
||||||
|
Size 58: 35,58 BAD (HHHHHH)
|
||||||
|
Size 59: 36,59 BAD (HHHHHH)
|
||||||
|
Size 60: 36,60 BAD (HHHHHH)
|
||||||
|
Size 61: 37,61 BAD (HHHHHH)
|
||||||
|
Size 62: 37,62 BAD (HHHHHH)
|
||||||
|
Size 63: 38,63 BAD (HHHHHH)
|
||||||
|
Size 64: 39,65 BAD (HHHHHH)
|
||||||
|
Size 65: 39,65 BAD (HHHHHH)
|
||||||
|
Size 66: 40,66 BAD (HHHHHH)
|
||||||
|
Size 67: 40,67 BAD (HHHHHH)
|
||||||
|
Size 68: 41,68 BAD (HHHHHH)
|
||||||
|
Size 69: 42,69 BAD (HHHHHH)
|
||||||
|
Size 70: 42,70 BAD (HHHHHH)
|
||||||
|
Size 71: 43,71 BAD (HHHHHH)
|
||||||
|
Size 72: 43,72 BAD (HHHHHH)
|
||||||
|
Size 73: 44,73 BAD (HHHHHH)
|
||||||
|
Size 74: 45,74 BAD (HHHHHH)
|
||||||
|
Size 75: 45,75 BAD (HHHHHH)
|
||||||
|
Size 76: 46,76 BAD (HHHHHH)
|
||||||
|
Size 77: 46,77 BAD (HHHHHH)
|
||||||
|
Size 78: 47,78 BAD (HHHHHH)
|
||||||
|
Size 79: 48,79 BAD (HHHHHH)
|
||||||
|
Size 80: 48,80 BAD (HHHHHH)
|
||||||
|
Size 81: 49,81 BAD (HHHHHH)
|
||||||
|
Size 82: 49,82 BAD (HHHHHH)
|
||||||
|
Size 83: 50,83 BAD (HHHHHH)
|
||||||
|
Size 84: 51,84 BAD (HHHHHH)
|
||||||
|
Size 85: 51,85 BAD (HHHHHH)
|
||||||
|
Size 86: 52,86 BAD (HHHHHH)
|
||||||
|
Size 87: 52,87 BAD (HHHHHH)
|
||||||
|
Size 88: 53,88 BAD (HHHHHH)
|
||||||
|
Size 89: 54,89 BAD (HHHHHH)
|
||||||
|
Size 90: 54,90 BAD (HHHHHH)
|
||||||
|
Size 91: 55,91 BAD (HHHHHH)
|
||||||
|
Size 92: 55,92 BAD (HHHHHH)
|
||||||
|
Size 93: 56,93 BAD (HHHHHH)
|
||||||
|
Size 94: 57,94 BAD (HHHHHH)
|
||||||
|
Size 95: 57,95 BAD (HHHHHH)
|
||||||
|
Size 96: 58,96 BAD (HHHHHH)
|
||||||
|
Size 97: 58,97 BAD (HHHHHH)
|
||||||
|
Size 98: 59,98 BAD (HHHHHH)
|
||||||
|
Size 99: 60,99 BAD (HHHHHH)
|
||||||
|
Size 100: 60,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
|
||||||
|
Windows 7
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 2,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 3,5 BAD (HHHHHH)
|
||||||
|
Size 6: 4,6 BAD (HHHHHH)
|
||||||
|
Size 7: 4,7 BAD (HHHHHH)
|
||||||
|
Size 8: 5,8 BAD (HHHHHH)
|
||||||
|
Size 9: 5,9 BAD (HHHHHH)
|
||||||
|
Size 10: 6,10 BAD (HHHHHH)
|
||||||
|
Size 11: 7,11 BAD (HHHHHH)
|
||||||
|
Size 12: 7,12 BAD (HHHHHH)
|
||||||
|
Size 13: 8,13 BAD (HHHHHH)
|
||||||
|
Size 14: 8,14 BAD (HHHHHH)
|
||||||
|
Size 15: 9,15 BAD (HHHHHH)
|
||||||
|
Size 16: 10,16 BAD (HHHHHH)
|
||||||
|
Size 17: 10,17 BAD (HHHHHH)
|
||||||
|
Size 18: 11,18 BAD (HHHHHH)
|
||||||
|
Size 19: 11,19 BAD (HHHHHH)
|
||||||
|
Size 20: 12,20 BAD (HHHHHH)
|
||||||
|
Size 21: 13,21 BAD (HHHHHH)
|
||||||
|
Size 22: 13,22 BAD (HHHHHH)
|
||||||
|
Size 23: 14,23 BAD (HHHHHH)
|
||||||
|
Size 24: 14,24 BAD (HHHHHH)
|
||||||
|
Size 25: 15,25 BAD (HHHHHH)
|
||||||
|
Size 26: 16,26 BAD (HHHHHH)
|
||||||
|
Size 27: 16,27 BAD (HHHHHH)
|
||||||
|
Size 28: 17,28 BAD (HHHHHH)
|
||||||
|
Size 29: 17,29 BAD (HHHHHH)
|
||||||
|
Size 30: 18,30 BAD (HHHHHH)
|
||||||
|
Size 31: 19,31 BAD (HHHHHH)
|
||||||
|
Size 32: 19,32 BAD (HHHHHH)
|
||||||
|
Size 33: 20,33 BAD (HHHHHH)
|
||||||
|
Size 34: 20,34 BAD (HHHHHH)
|
||||||
|
Size 35: 21,35 BAD (HHHHHH)
|
||||||
|
Size 36: 22,36 BAD (HHHHHH)
|
||||||
|
Size 37: 22,37 BAD (HHHHHH)
|
||||||
|
Size 38: 23,38 BAD (HHHHHH)
|
||||||
|
Size 39: 23,39 BAD (HHHHHH)
|
||||||
|
Size 40: 24,40 BAD (HHHHHH)
|
||||||
|
Size 41: 25,41 BAD (HHHHHH)
|
||||||
|
Size 42: 25,42 BAD (HHHHHH)
|
||||||
|
Size 43: 26,43 BAD (HHHHHH)
|
||||||
|
Size 44: 27,44 BAD (HHHHHH)
|
||||||
|
Size 45: 27,45 BAD (HHHHHH)
|
||||||
|
Size 46: 28,46 BAD (HHHHHH)
|
||||||
|
Size 47: 28,47 BAD (HHHHHH)
|
||||||
|
Size 48: 29,48 BAD (HHHHHH)
|
||||||
|
Size 49: 30,49 BAD (HHHHHH)
|
||||||
|
Size 50: 30,50 BAD (HHHHHH)
|
||||||
|
Size 51: 31,51 BAD (HHHHHH)
|
||||||
|
Size 52: 31,52 BAD (HHHHHH)
|
||||||
|
Size 53: 32,53 BAD (HHHHHH)
|
||||||
|
Size 54: 33,54 BAD (HHHHHH)
|
||||||
|
Size 55: 33,55 BAD (HHHHHH)
|
||||||
|
Size 56: 34,56 BAD (HHHHHH)
|
||||||
|
Size 57: 34,57 BAD (HHHHHH)
|
||||||
|
Size 58: 35,58 BAD (HHHHHH)
|
||||||
|
Size 59: 36,59 BAD (HHHHHH)
|
||||||
|
Size 60: 36,60 BAD (HHHHHH)
|
||||||
|
Size 61: 37,61 BAD (HHHHHH)
|
||||||
|
Size 62: 37,62 BAD (HHHHHH)
|
||||||
|
Size 63: 38,63 BAD (HHHHHH)
|
||||||
|
Size 64: 39,65 BAD (HHHHHH)
|
||||||
|
Size 65: 39,65 BAD (HHHHHH)
|
||||||
|
Size 66: 40,66 BAD (HHHHHH)
|
||||||
|
Size 67: 40,67 BAD (HHHHHH)
|
||||||
|
Size 68: 41,68 BAD (HHHHHH)
|
||||||
|
Size 69: 42,69 BAD (HHHHHH)
|
||||||
|
Size 70: 42,70 BAD (HHHHHH)
|
||||||
|
Size 71: 43,71 BAD (HHHHHH)
|
||||||
|
Size 72: 43,72 BAD (HHHHHH)
|
||||||
|
Size 73: 44,73 BAD (HHHHHH)
|
||||||
|
Size 74: 45,74 BAD (HHHHHH)
|
||||||
|
Size 75: 45,75 BAD (HHHHHH)
|
||||||
|
Size 76: 46,76 BAD (HHHHHH)
|
||||||
|
Size 77: 46,77 BAD (HHHHHH)
|
||||||
|
Size 78: 47,78 BAD (HHHHHH)
|
||||||
|
Size 79: 48,79 BAD (HHHHHH)
|
||||||
|
Size 80: 48,80 BAD (HHHHHH)
|
||||||
|
Size 81: 49,81 BAD (HHHHHH)
|
||||||
|
Size 82: 49,82 BAD (HHHHHH)
|
||||||
|
Size 83: 50,83 BAD (HHHHHH)
|
||||||
|
Size 84: 51,84 BAD (HHHHHH)
|
||||||
|
Size 85: 51,85 BAD (HHHHHH)
|
||||||
|
Size 86: 52,86 BAD (HHHHHH)
|
||||||
|
Size 87: 52,87 BAD (HHHHHH)
|
||||||
|
Size 88: 53,88 BAD (HHHHHH)
|
||||||
|
Size 89: 54,89 BAD (HHHHHH)
|
||||||
|
Size 90: 54,90 BAD (HHHHHH)
|
||||||
|
Size 91: 55,91 BAD (HHHHHH)
|
||||||
|
Size 92: 55,92 BAD (HHHHHH)
|
||||||
|
Size 93: 56,93 BAD (HHHHHH)
|
||||||
|
Size 94: 57,94 BAD (HHHHHH)
|
||||||
|
Size 95: 57,95 BAD (HHHHHH)
|
||||||
|
Size 96: 58,96 BAD (HHHHHH)
|
||||||
|
Size 97: 58,97 BAD (HHHHHH)
|
||||||
|
Size 98: 59,98 BAD (HHHHHH)
|
||||||
|
Size 99: 60,99 BAD (HHHHHH)
|
||||||
|
Size 100: 60,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 8
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 2,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 3,5 BAD (HHHHHH)
|
||||||
|
Size 6: 4,6 BAD (HHHHHH)
|
||||||
|
Size 7: 4,7 BAD (HHHHHH)
|
||||||
|
Size 8: 5,8 BAD (HHHHHH)
|
||||||
|
Size 9: 5,9 BAD (HHHHHH)
|
||||||
|
Size 10: 6,10 BAD (HHHHHH)
|
||||||
|
Size 11: 7,11 BAD (HHHHHH)
|
||||||
|
Size 12: 7,12 BAD (HHHHHH)
|
||||||
|
Size 13: 8,13 BAD (HHHHHH)
|
||||||
|
Size 14: 8,14 BAD (HHHHHH)
|
||||||
|
Size 15: 9,15 BAD (HHHHHH)
|
||||||
|
Size 16: 10,16 BAD (HHHHHH)
|
||||||
|
Size 17: 10,17 BAD (HHHHHH)
|
||||||
|
Size 18: 11,18 BAD (HHHHHH)
|
||||||
|
Size 19: 11,19 BAD (HHHHHH)
|
||||||
|
Size 20: 12,20 BAD (HHHHHH)
|
||||||
|
Size 21: 13,21 BAD (HHHHHH)
|
||||||
|
Size 22: 13,22 BAD (HHHHHH)
|
||||||
|
Size 23: 14,23 BAD (HHHHHH)
|
||||||
|
Size 24: 14,24 BAD (HHHHHH)
|
||||||
|
Size 25: 15,25 BAD (HHHHHH)
|
||||||
|
Size 26: 16,26 BAD (HHHHHH)
|
||||||
|
Size 27: 16,27 BAD (HHHHHH)
|
||||||
|
Size 28: 17,28 BAD (HHHHHH)
|
||||||
|
Size 29: 17,29 BAD (HHHHHH)
|
||||||
|
Size 30: 18,30 BAD (HHHHHH)
|
||||||
|
Size 31: 19,31 BAD (HHHHHH)
|
||||||
|
Size 32: 19,32 BAD (HHHHHH)
|
||||||
|
Size 33: 20,33 BAD (HHHHHH)
|
||||||
|
Size 34: 20,34 BAD (HHHHHH)
|
||||||
|
Size 35: 21,35 BAD (HHHHHH)
|
||||||
|
Size 36: 22,36 BAD (HHHHHH)
|
||||||
|
Size 37: 22,37 BAD (HHHHHH)
|
||||||
|
Size 38: 23,38 BAD (HHHHHH)
|
||||||
|
Size 39: 23,39 BAD (HHHHHH)
|
||||||
|
Size 40: 24,40 BAD (HHHHHH)
|
||||||
|
Size 41: 25,41 BAD (HHHHHH)
|
||||||
|
Size 42: 25,42 BAD (HHHHHH)
|
||||||
|
Size 43: 26,43 BAD (HHHHHH)
|
||||||
|
Size 44: 27,44 BAD (HHHHHH)
|
||||||
|
Size 45: 27,45 BAD (HHHHHH)
|
||||||
|
Size 46: 28,46 BAD (HHHHHH)
|
||||||
|
Size 47: 28,47 BAD (HHHHHH)
|
||||||
|
Size 48: 29,48 BAD (HHHHHH)
|
||||||
|
Size 49: 30,49 BAD (HHHHHH)
|
||||||
|
Size 50: 30,50 BAD (HHHHHH)
|
||||||
|
Size 51: 31,51 BAD (HHHHHH)
|
||||||
|
Size 52: 31,52 BAD (HHHHHH)
|
||||||
|
Size 53: 32,53 BAD (HHHHHH)
|
||||||
|
Size 54: 33,54 BAD (HHHHHH)
|
||||||
|
Size 55: 33,55 BAD (HHHHHH)
|
||||||
|
Size 56: 34,56 BAD (HHHHHH)
|
||||||
|
Size 57: 34,57 BAD (HHHHHH)
|
||||||
|
Size 58: 35,58 BAD (HHHHHH)
|
||||||
|
Size 59: 36,59 BAD (HHHHHH)
|
||||||
|
Size 60: 36,60 BAD (HHHHHH)
|
||||||
|
Size 61: 37,61 BAD (HHHHHH)
|
||||||
|
Size 62: 37,62 BAD (HHHHHH)
|
||||||
|
Size 63: 38,63 BAD (HHHHHH)
|
||||||
|
Size 64: 39,65 BAD (HHHHHH)
|
||||||
|
Size 65: 39,65 BAD (HHHHHH)
|
||||||
|
Size 66: 40,66 BAD (HHHHHH)
|
||||||
|
Size 67: 40,67 BAD (HHHHHH)
|
||||||
|
Size 68: 41,68 BAD (HHHHHH)
|
||||||
|
Size 69: 42,69 BAD (HHHHHH)
|
||||||
|
Size 70: 42,70 BAD (HHHHHH)
|
||||||
|
Size 71: 43,71 BAD (HHHHHH)
|
||||||
|
Size 72: 43,72 BAD (HHHHHH)
|
||||||
|
Size 73: 44,73 BAD (HHHHHH)
|
||||||
|
Size 74: 45,74 BAD (HHHHHH)
|
||||||
|
Size 75: 45,75 BAD (HHHHHH)
|
||||||
|
Size 76: 46,76 BAD (HHHHHH)
|
||||||
|
Size 77: 46,77 BAD (HHHHHH)
|
||||||
|
Size 78: 47,78 BAD (HHHHHH)
|
||||||
|
Size 79: 48,79 BAD (HHHHHH)
|
||||||
|
Size 80: 48,80 BAD (HHHHHH)
|
||||||
|
Size 81: 49,81 BAD (HHHHHH)
|
||||||
|
Size 82: 49,82 BAD (HHHHHH)
|
||||||
|
Size 83: 50,83 BAD (HHHHHH)
|
||||||
|
Size 84: 51,84 BAD (HHHHHH)
|
||||||
|
Size 85: 51,85 BAD (HHHHHH)
|
||||||
|
Size 86: 52,86 BAD (HHHHHH)
|
||||||
|
Size 87: 52,87 BAD (HHHHHH)
|
||||||
|
Size 88: 53,88 BAD (HHHHHH)
|
||||||
|
Size 89: 54,89 BAD (HHHHHH)
|
||||||
|
Size 90: 54,90 BAD (HHHHHH)
|
||||||
|
Size 91: 55,91 BAD (HHHHHH)
|
||||||
|
Size 92: 55,92 BAD (HHHHHH)
|
||||||
|
Size 93: 56,93 BAD (HHHHHH)
|
||||||
|
Size 94: 57,94 BAD (HHHHHH)
|
||||||
|
Size 95: 57,95 BAD (HHHHHH)
|
||||||
|
Size 96: 58,96 BAD (HHHHHH)
|
||||||
|
Size 97: 58,97 BAD (HHHHHH)
|
||||||
|
Size 98: 59,98 BAD (HHHHHH)
|
||||||
|
Size 99: 60,99 BAD (HHHHHH)
|
||||||
|
Size 100: 60,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 8.1
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 2,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 3,5 BAD (HHHHHH)
|
||||||
|
Size 6: 4,6 BAD (HHHHHH)
|
||||||
|
Size 7: 4,7 BAD (HHHHHH)
|
||||||
|
Size 8: 5,8 BAD (HHHHHH)
|
||||||
|
Size 9: 5,9 BAD (HHHHHH)
|
||||||
|
Size 10: 6,10 BAD (HHHHHH)
|
||||||
|
Size 11: 7,11 BAD (HHHHHH)
|
||||||
|
Size 12: 7,12 BAD (HHHHHH)
|
||||||
|
Size 13: 8,13 BAD (HHHHHH)
|
||||||
|
Size 14: 8,14 BAD (HHHHHH)
|
||||||
|
Size 15: 9,15 BAD (HHHHHH)
|
||||||
|
Size 16: 10,16 BAD (HHHHHH)
|
||||||
|
Size 17: 10,17 BAD (HHHHHH)
|
||||||
|
Size 18: 11,18 BAD (HHHHHH)
|
||||||
|
Size 19: 11,19 BAD (HHHHHH)
|
||||||
|
Size 20: 12,20 BAD (HHHHHH)
|
||||||
|
Size 21: 13,21 BAD (HHHHHH)
|
||||||
|
Size 22: 13,22 BAD (HHHHHH)
|
||||||
|
Size 23: 14,23 BAD (HHHHHH)
|
||||||
|
Size 24: 14,24 BAD (HHHHHH)
|
||||||
|
Size 25: 15,25 BAD (HHHHHH)
|
||||||
|
Size 26: 16,26 BAD (HHHHHH)
|
||||||
|
Size 27: 16,27 BAD (HHHHHH)
|
||||||
|
Size 28: 17,28 BAD (HHHHHH)
|
||||||
|
Size 29: 17,29 BAD (HHHHHH)
|
||||||
|
Size 30: 18,30 BAD (HHHHHH)
|
||||||
|
Size 31: 19,31 BAD (HHHHHH)
|
||||||
|
Size 32: 19,32 BAD (HHHHHH)
|
||||||
|
Size 33: 20,33 BAD (HHHHHH)
|
||||||
|
Size 34: 20,34 BAD (HHHHHH)
|
||||||
|
Size 35: 21,35 BAD (HHHHHH)
|
||||||
|
Size 36: 22,36 BAD (HHHHHH)
|
||||||
|
Size 37: 22,37 BAD (HHHHHH)
|
||||||
|
Size 38: 23,38 BAD (HHHHHH)
|
||||||
|
Size 39: 23,39 BAD (HHHHHH)
|
||||||
|
Size 40: 24,40 BAD (HHHHHH)
|
||||||
|
Size 41: 25,41 BAD (HHHHHH)
|
||||||
|
Size 42: 25,42 BAD (HHHHHH)
|
||||||
|
Size 43: 26,43 BAD (HHHHHH)
|
||||||
|
Size 44: 27,44 BAD (HHHHHH)
|
||||||
|
Size 45: 27,45 BAD (HHHHHH)
|
||||||
|
Size 46: 28,46 BAD (HHHHHH)
|
||||||
|
Size 47: 28,47 BAD (HHHHHH)
|
||||||
|
Size 48: 29,48 BAD (HHHHHH)
|
||||||
|
Size 49: 30,49 BAD (HHHHHH)
|
||||||
|
Size 50: 30,50 BAD (HHHHHH)
|
||||||
|
Size 51: 31,51 BAD (HHHHHH)
|
||||||
|
Size 52: 31,52 BAD (HHHHHH)
|
||||||
|
Size 53: 32,53 BAD (HHHHHH)
|
||||||
|
Size 54: 33,54 BAD (HHHHHH)
|
||||||
|
Size 55: 33,55 BAD (HHHHHH)
|
||||||
|
Size 56: 34,56 BAD (HHHHHH)
|
||||||
|
Size 57: 34,57 BAD (HHHHHH)
|
||||||
|
Size 58: 35,58 BAD (HHHHHH)
|
||||||
|
Size 59: 36,59 BAD (HHHHHH)
|
||||||
|
Size 60: 36,60 BAD (HHHHHH)
|
||||||
|
Size 61: 37,61 BAD (HHHHHH)
|
||||||
|
Size 62: 37,62 BAD (HHHHHH)
|
||||||
|
Size 63: 38,63 BAD (HHHHHH)
|
||||||
|
Size 64: 39,65 BAD (HHHHHH)
|
||||||
|
Size 65: 39,65 BAD (HHHHHH)
|
||||||
|
Size 66: 40,66 BAD (HHHHHH)
|
||||||
|
Size 67: 40,67 BAD (HHHHHH)
|
||||||
|
Size 68: 41,68 BAD (HHHHHH)
|
||||||
|
Size 69: 42,69 BAD (HHHHHH)
|
||||||
|
Size 70: 42,70 BAD (HHHHHH)
|
||||||
|
Size 71: 43,71 BAD (HHHHHH)
|
||||||
|
Size 72: 43,72 BAD (HHHHHH)
|
||||||
|
Size 73: 44,73 BAD (HHHHHH)
|
||||||
|
Size 74: 45,74 BAD (HHHHHH)
|
||||||
|
Size 75: 45,75 BAD (HHHHHH)
|
||||||
|
Size 76: 46,76 BAD (HHHHHH)
|
||||||
|
Size 77: 46,77 BAD (HHHHHH)
|
||||||
|
Size 78: 47,78 BAD (HHHHHH)
|
||||||
|
Size 79: 48,79 BAD (HHHHHH)
|
||||||
|
Size 80: 48,80 BAD (HHHHHH)
|
||||||
|
Size 81: 49,81 BAD (HHHHHH)
|
||||||
|
Size 82: 49,82 BAD (HHHHHH)
|
||||||
|
Size 83: 50,83 BAD (HHHHHH)
|
||||||
|
Size 84: 51,84 BAD (HHHHHH)
|
||||||
|
Size 85: 51,85 BAD (HHHHHH)
|
||||||
|
Size 86: 52,86 BAD (HHHHHH)
|
||||||
|
Size 87: 52,87 BAD (HHHHHH)
|
||||||
|
Size 88: 53,88 BAD (HHHHHH)
|
||||||
|
Size 89: 54,89 BAD (HHHHHH)
|
||||||
|
Size 90: 54,90 BAD (HHHHHH)
|
||||||
|
Size 91: 55,91 BAD (HHHHHH)
|
||||||
|
Size 92: 55,92 BAD (HHHHHH)
|
||||||
|
Size 93: 56,93 BAD (HHHHHH)
|
||||||
|
Size 94: 57,94 BAD (HHHHHH)
|
||||||
|
Size 95: 57,95 BAD (HHHHHH)
|
||||||
|
Size 96: 58,96 BAD (HHHHHH)
|
||||||
|
Size 97: 58,97 BAD (HHHHHH)
|
||||||
|
Size 98: 59,98 BAD (HHHHHH)
|
||||||
|
Size 99: 60,99 BAD (HHHHHH)
|
||||||
|
Size 100: 60,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 10 14342 Old Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 2,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 3,5 BAD (HHHHHH)
|
||||||
|
Size 6: 4,6 BAD (HHHHHH)
|
||||||
|
Size 7: 4,7 BAD (HHHHHH)
|
||||||
|
Size 8: 5,8 BAD (HHHHHH)
|
||||||
|
Size 9: 5,9 BAD (HHHHHH)
|
||||||
|
Size 10: 6,10 BAD (HHHHHH)
|
||||||
|
Size 11: 7,11 BAD (HHHHHH)
|
||||||
|
Size 12: 7,12 BAD (HHHHHH)
|
||||||
|
Size 13: 8,13 BAD (HHHHHH)
|
||||||
|
Size 14: 8,14 BAD (HHHHHH)
|
||||||
|
Size 15: 9,15 BAD (HHHHHH)
|
||||||
|
Size 16: 10,16 BAD (HHHHHH)
|
||||||
|
Size 17: 10,17 BAD (HHHHHH)
|
||||||
|
Size 18: 11,18 BAD (HHHHHH)
|
||||||
|
Size 19: 11,19 BAD (HHHHHH)
|
||||||
|
Size 20: 12,20 BAD (HHHHHH)
|
||||||
|
Size 21: 13,21 BAD (HHHHHH)
|
||||||
|
Size 22: 13,22 BAD (HHHHHH)
|
||||||
|
Size 23: 14,23 BAD (HHHHHH)
|
||||||
|
Size 24: 14,24 BAD (HHHHHH)
|
||||||
|
Size 25: 15,25 BAD (HHHHHH)
|
||||||
|
Size 26: 16,26 BAD (HHHHHH)
|
||||||
|
Size 27: 16,27 BAD (HHHHHH)
|
||||||
|
Size 28: 17,28 BAD (HHHHHH)
|
||||||
|
Size 29: 17,29 BAD (HHHHHH)
|
||||||
|
Size 30: 18,30 BAD (HHHHHH)
|
||||||
|
Size 31: 19,31 BAD (HHHHHH)
|
||||||
|
Size 32: 19,32 BAD (HHHHHH)
|
||||||
|
Size 33: 20,33 BAD (HHHHHH)
|
||||||
|
Size 34: 20,34 BAD (HHHHHH)
|
||||||
|
Size 35: 21,35 BAD (HHHHHH)
|
||||||
|
Size 36: 22,36 BAD (HHHHHH)
|
||||||
|
Size 37: 22,37 BAD (HHHHHH)
|
||||||
|
Size 38: 23,38 BAD (HHHHHH)
|
||||||
|
Size 39: 23,39 BAD (HHHHHH)
|
||||||
|
Size 40: 24,40 BAD (HHHHHH)
|
||||||
|
Size 41: 25,41 BAD (HHHHHH)
|
||||||
|
Size 42: 25,42 BAD (HHHHHH)
|
||||||
|
Size 43: 26,43 BAD (HHHHHH)
|
||||||
|
Size 44: 27,44 BAD (HHHHHH)
|
||||||
|
Size 45: 27,45 BAD (HHHHHH)
|
||||||
|
Size 46: 28,46 BAD (HHHHHH)
|
||||||
|
Size 47: 28,47 BAD (HHHHHH)
|
||||||
|
Size 48: 29,48 BAD (HHHHHH)
|
||||||
|
Size 49: 30,49 BAD (HHHHHH)
|
||||||
|
Size 50: 30,50 BAD (HHHHHH)
|
||||||
|
Size 51: 31,51 BAD (HHHHHH)
|
||||||
|
Size 52: 31,52 BAD (HHHHHH)
|
||||||
|
Size 53: 32,53 BAD (HHHHHH)
|
||||||
|
Size 54: 33,54 BAD (HHHHHH)
|
||||||
|
Size 55: 33,55 BAD (HHHHHH)
|
||||||
|
Size 56: 34,56 BAD (HHHHHH)
|
||||||
|
Size 57: 34,57 BAD (HHHHHH)
|
||||||
|
Size 58: 35,58 BAD (HHHHHH)
|
||||||
|
Size 59: 36,59 BAD (HHHHHH)
|
||||||
|
Size 60: 36,60 BAD (HHHHHH)
|
||||||
|
Size 61: 37,61 BAD (HHHHHH)
|
||||||
|
Size 62: 37,62 BAD (HHHHHH)
|
||||||
|
Size 63: 38,63 BAD (HHHHHH)
|
||||||
|
Size 64: 39,65 BAD (HHHHHH)
|
||||||
|
Size 65: 39,65 BAD (HHHHHH)
|
||||||
|
Size 66: 40,66 BAD (HHHHHH)
|
||||||
|
Size 67: 40,67 BAD (HHHHHH)
|
||||||
|
Size 68: 41,68 BAD (HHHHHH)
|
||||||
|
Size 69: 42,69 BAD (HHHHHH)
|
||||||
|
Size 70: 42,70 BAD (HHHHHH)
|
||||||
|
Size 71: 43,71 BAD (HHHHHH)
|
||||||
|
Size 72: 43,72 BAD (HHHHHH)
|
||||||
|
Size 73: 44,73 BAD (HHHHHH)
|
||||||
|
Size 74: 45,74 BAD (HHHHHH)
|
||||||
|
Size 75: 45,75 BAD (HHHHHH)
|
||||||
|
Size 76: 46,76 BAD (HHHHHH)
|
||||||
|
Size 77: 46,77 BAD (HHHHHH)
|
||||||
|
Size 78: 47,78 BAD (HHHHHH)
|
||||||
|
Size 79: 48,79 BAD (HHHHHH)
|
||||||
|
Size 80: 48,80 BAD (HHHHHH)
|
||||||
|
Size 81: 49,81 BAD (HHHHHH)
|
||||||
|
Size 82: 49,82 BAD (HHHHHH)
|
||||||
|
Size 83: 50,83 BAD (HHHHHH)
|
||||||
|
Size 84: 51,84 BAD (HHHHHH)
|
||||||
|
Size 85: 51,85 BAD (HHHHHH)
|
||||||
|
Size 86: 52,86 BAD (HHHHHH)
|
||||||
|
Size 87: 52,87 BAD (HHHHHH)
|
||||||
|
Size 88: 53,88 BAD (HHHHHH)
|
||||||
|
Size 89: 54,89 BAD (HHHHHH)
|
||||||
|
Size 90: 54,90 BAD (HHHHHH)
|
||||||
|
Size 91: 55,91 BAD (HHHHHH)
|
||||||
|
Size 92: 55,92 BAD (HHHHHH)
|
||||||
|
Size 93: 56,93 BAD (HHHHHH)
|
||||||
|
Size 94: 57,94 BAD (HHHHHH)
|
||||||
|
Size 95: 57,95 BAD (HHHHHH)
|
||||||
|
Size 96: 58,96 BAD (HHHHHH)
|
||||||
|
Size 97: 58,97 BAD (HHHHHH)
|
||||||
|
Size 98: 59,98 BAD (HHHHHH)
|
||||||
|
Size 99: 60,99 BAD (HHHHHH)
|
||||||
|
Size 100: 60,100 BAD (HHHHHH)
|
||||||
|
|
||||||
|
Windows 10 14342 New Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,1 BAD (HHHHHH)
|
||||||
|
Size 2: 1,2 BAD (HHHHHH)
|
||||||
|
Size 3: 2,3 BAD (HHHHHH)
|
||||||
|
Size 4: 2,4 BAD (HHHHHH)
|
||||||
|
Size 5: 3,5 BAD (HHHHHH)
|
||||||
|
Size 6: 4,6 BAD (HHHHHH)
|
||||||
|
Size 7: 4,7 BAD (HHHHHH)
|
||||||
|
Size 8: 5,8 BAD (HHHHHH)
|
||||||
|
Size 9: 5,9 BAD (HHHHHH)
|
||||||
|
Size 10: 6,10 BAD (HHHHHH)
|
||||||
|
Size 11: 7,11 BAD (HHHHHH)
|
||||||
|
Size 12: 7,12 BAD (HHHHHH)
|
||||||
|
Size 13: 8,13 BAD (HHHHHH)
|
||||||
|
Size 14: 8,14 BAD (HHHHHH)
|
||||||
|
Size 15: 9,15 BAD (HHHHHH)
|
||||||
|
Size 16: 10,16 BAD (HHHHHH)
|
||||||
|
Size 17: 10,17 BAD (HHHHHH)
|
||||||
|
Size 18: 11,18 BAD (HHHHHH)
|
||||||
|
Size 19: 11,19 BAD (HHHHHH)
|
||||||
|
Size 20: 12,20 BAD (HHHHHH)
|
||||||
|
Size 21: 13,21 BAD (HHHHHH)
|
||||||
|
Size 22: 13,22 BAD (HHHHHH)
|
||||||
|
Size 23: 14,23 BAD (HHHHHH)
|
||||||
|
Size 24: 14,24 BAD (HHHHHH)
|
||||||
|
Size 25: 15,25 BAD (HHHHHH)
|
||||||
|
Size 26: 16,26 BAD (HHHHHH)
|
||||||
|
Size 27: 16,27 BAD (HHHHHH)
|
||||||
|
Size 28: 17,28 BAD (HHHHHH)
|
||||||
|
Size 29: 17,29 BAD (HHHHHH)
|
||||||
|
Size 30: 18,30 BAD (HHHHHH)
|
||||||
|
Size 31: 19,31 BAD (HHHHHH)
|
||||||
|
Size 32: 19,32 BAD (HHHHHH)
|
||||||
|
Size 33: 20,33 BAD (HHHHHH)
|
||||||
|
Size 34: 20,34 BAD (HHHHHH)
|
||||||
|
Size 35: 21,35 BAD (HHHHHH)
|
||||||
|
Size 36: 22,36 BAD (HHHHHH)
|
||||||
|
Size 37: 22,37 BAD (HHHHHH)
|
||||||
|
Size 38: 23,38 BAD (HHHHHH)
|
||||||
|
Size 39: 23,39 BAD (HHHHHH)
|
||||||
|
Size 40: 24,40 BAD (HHHHHH)
|
||||||
|
Size 41: 25,41 BAD (HHHHHH)
|
||||||
|
Size 42: 25,42 BAD (HHHHHH)
|
||||||
|
Size 43: 26,43 BAD (HHHHHH)
|
||||||
|
Size 44: 27,44 BAD (HHHHHH)
|
||||||
|
Size 45: 27,45 BAD (HHHHHH)
|
||||||
|
Size 46: 28,46 BAD (HHHHHH)
|
||||||
|
Size 47: 28,47 BAD (HHHHHH)
|
||||||
|
Size 48: 29,48 BAD (HHHHHH)
|
||||||
|
Size 49: 30,49 BAD (HHHHHH)
|
||||||
|
Size 50: 30,50 BAD (HHHHHH)
|
||||||
|
Size 51: 31,51 BAD (HHHHHH)
|
||||||
|
Size 52: 31,52 BAD (HHHHHH)
|
||||||
|
Size 53: 32,53 BAD (HHHHHH)
|
||||||
|
Size 54: 33,54 BAD (HHHHHH)
|
||||||
|
Size 55: 33,55 BAD (HHHHHH)
|
||||||
|
Size 56: 34,56 BAD (HHHHHH)
|
||||||
|
Size 57: 34,57 BAD (HHHHHH)
|
||||||
|
Size 58: 35,58 BAD (HHHHHH)
|
||||||
|
Size 59: 36,59 BAD (HHHHHH)
|
||||||
|
Size 60: 36,60 BAD (HHHHHH)
|
||||||
|
Size 61: 37,61 BAD (HHHHHH)
|
||||||
|
Size 62: 37,62 BAD (HHHHHH)
|
||||||
|
Size 63: 38,63 BAD (HHHHHH)
|
||||||
|
Size 64: 39,64 BAD (HHHHHH)
|
||||||
|
Size 65: 39,65 BAD (HHHHHH)
|
||||||
|
Size 66: 40,66 BAD (HHHHHH)
|
||||||
|
Size 67: 40,67 BAD (HHHHHH)
|
||||||
|
Size 68: 41,68 BAD (HHHHHH)
|
||||||
|
Size 69: 42,69 BAD (HHHHHH)
|
||||||
|
Size 70: 42,70 BAD (HHHHHH)
|
||||||
|
Size 71: 43,71 BAD (HHHHHH)
|
||||||
|
Size 72: 43,72 BAD (HHHHHH)
|
||||||
|
Size 73: 44,73 BAD (HHHHHH)
|
||||||
|
Size 74: 45,74 BAD (HHHHHH)
|
||||||
|
Size 75: 45,75 BAD (HHHHHH)
|
||||||
|
Size 76: 46,76 BAD (HHHHHH)
|
||||||
|
Size 77: 46,77 BAD (HHHHHH)
|
||||||
|
Size 78: 47,78 BAD (HHHHHH)
|
||||||
|
Size 79: 48,79 BAD (HHHHHH)
|
||||||
|
Size 80: 48,80 BAD (HHHHHH)
|
||||||
|
Size 81: 49,81 BAD (HHHHHH)
|
||||||
|
Size 82: 49,82 BAD (HHHHHH)
|
||||||
|
Size 83: 50,83 BAD (HHHHHH)
|
||||||
|
Size 84: 51,84 BAD (HHHHHH)
|
||||||
|
Size 85: 51,85 BAD (HHHHHH)
|
||||||
|
Size 86: 52,86 BAD (HHHHHH)
|
||||||
|
Size 87: 52,87 BAD (HHHHHH)
|
||||||
|
Size 88: 53,88 BAD (HHHHHH)
|
||||||
|
Size 89: 54,89 BAD (HHHHHH)
|
||||||
|
Size 90: 54,90 BAD (HHHHHH)
|
||||||
|
Size 91: 55,91 BAD (HHHHHH)
|
||||||
|
Size 92: 55,92 BAD (HHHHHH)
|
||||||
|
Size 93: 56,93 BAD (HHHHHH)
|
||||||
|
Size 94: 57,94 BAD (HHHHHH)
|
||||||
|
Size 95: 57,95 BAD (HHHHHH)
|
||||||
|
Size 96: 58,96 BAD (HHHHHH)
|
||||||
|
Size 97: 58,97 BAD (HHHHHH)
|
||||||
|
Size 98: 59,98 BAD (HHHHHH)
|
||||||
|
Size 99: 60,99 BAD (HHHHHH)
|
||||||
|
Size 100: 60,100 BAD (HHHHHH)
|
||||||
Generated
Vendored
+630
@@ -0,0 +1,630 @@
|
|||||||
|
=======================================
|
||||||
|
Code Page 932, Japanese, MS Gothic font
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
Options: -face-gothic -family 0x36
|
||||||
|
Chars: A2 A3 2014 3044 30FC 4000
|
||||||
|
|
||||||
|
Vista
|
||||||
|
-----
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,4 OK (HHHFFF)
|
||||||
|
Size 5: 3,5 OK (HHHFFF)
|
||||||
|
Size 6: 3,6 OK (HHHFFF)
|
||||||
|
Size 7: 4,7 OK (HHHFFF)
|
||||||
|
Size 8: 4,8 OK (HHHFFF)
|
||||||
|
Size 9: 5,9 OK (HHHFFF)
|
||||||
|
Size 10: 5,10 OK (HHHFFF)
|
||||||
|
Size 11: 6,11 OK (HHHFFF)
|
||||||
|
Size 12: 6,12 OK (HHHFFF)
|
||||||
|
Size 13: 7,13 OK (HHHFFF)
|
||||||
|
Size 14: 7,14 BAD (HHHFHH)
|
||||||
|
Size 15: 8,15 OK (HHHFFF)
|
||||||
|
Size 16: 8,16 BAD (HHHFHH)
|
||||||
|
Size 17: 9,17 OK (HHHFFF)
|
||||||
|
Size 18: 9,18 BAD (HHHFHH)
|
||||||
|
Size 19: 10,19 OK (HHHFFF)
|
||||||
|
Size 20: 10,20 BAD (HHHFHH)
|
||||||
|
Size 21: 11,21 OK (HHHFFF)
|
||||||
|
Size 22: 11,22 BAD (HHHFHH)
|
||||||
|
Size 23: 12,23 BAD (HHHFHH)
|
||||||
|
Size 24: 12,24 BAD (HHHFHH)
|
||||||
|
Size 25: 13,25 BAD (HHHFHH)
|
||||||
|
Size 26: 13,26 BAD (HHHFHH)
|
||||||
|
Size 27: 14,27 BAD (HHHFHH)
|
||||||
|
Size 28: 14,28 BAD (HHHFHH)
|
||||||
|
Size 29: 15,29 BAD (HHHFHH)
|
||||||
|
Size 30: 15,30 BAD (HHHFHH)
|
||||||
|
Size 31: 16,31 BAD (HHHFHH)
|
||||||
|
Size 32: 16,33 BAD (HHHFHH)
|
||||||
|
Size 33: 17,33 BAD (HHHFHH)
|
||||||
|
Size 34: 17,34 BAD (HHHFHH)
|
||||||
|
Size 35: 18,35 BAD (HHHFHH)
|
||||||
|
Size 36: 18,36 BAD (HHHFHH)
|
||||||
|
Size 37: 19,37 BAD (HHHFHH)
|
||||||
|
Size 38: 19,38 BAD (HHHFHH)
|
||||||
|
Size 39: 20,39 BAD (HHHFHH)
|
||||||
|
Size 40: 20,40 BAD (HHHFHH)
|
||||||
|
Size 41: 21,41 BAD (HHHFHH)
|
||||||
|
Size 42: 21,42 BAD (HHHFHH)
|
||||||
|
Size 43: 22,43 BAD (HHHFHH)
|
||||||
|
Size 44: 22,44 BAD (HHHFHH)
|
||||||
|
Size 45: 23,45 BAD (HHHFHH)
|
||||||
|
Size 46: 23,46 BAD (HHHFHH)
|
||||||
|
Size 47: 24,47 BAD (HHHFHH)
|
||||||
|
Size 48: 24,48 BAD (HHHFHH)
|
||||||
|
Size 49: 25,49 BAD (HHHFHH)
|
||||||
|
Size 50: 25,50 BAD (HHHFHH)
|
||||||
|
Size 51: 26,51 BAD (HHHFHH)
|
||||||
|
Size 52: 26,52 BAD (HHHFHH)
|
||||||
|
Size 53: 27,53 BAD (HHHFHH)
|
||||||
|
Size 54: 27,54 BAD (HHHFHH)
|
||||||
|
Size 55: 28,55 BAD (HHHFHH)
|
||||||
|
Size 56: 28,56 BAD (HHHFHH)
|
||||||
|
Size 57: 29,57 BAD (HHHFHH)
|
||||||
|
Size 58: 29,58 BAD (HHHFHH)
|
||||||
|
Size 59: 30,59 BAD (HHHFHH)
|
||||||
|
Size 60: 30,60 BAD (HHHFHH)
|
||||||
|
Size 61: 31,61 BAD (HHHFHH)
|
||||||
|
Size 62: 31,62 BAD (HHHFHH)
|
||||||
|
Size 63: 32,63 BAD (HHHFHH)
|
||||||
|
Size 64: 32,64 BAD (HHHFHH)
|
||||||
|
Size 65: 33,65 BAD (HHHFHH)
|
||||||
|
Size 66: 33,66 BAD (HHHFHH)
|
||||||
|
Size 67: 34,67 BAD (HHHFHH)
|
||||||
|
Size 68: 34,68 BAD (HHHFHH)
|
||||||
|
Size 69: 35,69 BAD (HHHFHH)
|
||||||
|
Size 70: 35,70 BAD (HHHFHH)
|
||||||
|
Size 71: 36,71 BAD (HHHFHH)
|
||||||
|
Size 72: 36,72 BAD (HHHFHH)
|
||||||
|
Size 73: 37,73 BAD (HHHFHH)
|
||||||
|
Size 74: 37,74 BAD (HHHFHH)
|
||||||
|
Size 75: 38,75 BAD (HHHFHH)
|
||||||
|
Size 76: 38,76 BAD (HHHFHH)
|
||||||
|
Size 77: 39,77 BAD (HHHFHH)
|
||||||
|
Size 78: 39,78 BAD (HHHFHH)
|
||||||
|
Size 79: 40,79 BAD (HHHFHH)
|
||||||
|
Size 80: 40,80 BAD (HHHFHH)
|
||||||
|
Size 81: 41,81 BAD (HHHFHH)
|
||||||
|
Size 82: 41,82 BAD (HHHFHH)
|
||||||
|
Size 83: 42,83 BAD (HHHFHH)
|
||||||
|
Size 84: 42,84 BAD (HHHFHH)
|
||||||
|
Size 85: 43,85 BAD (HHHFHH)
|
||||||
|
Size 86: 43,86 BAD (HHHFHH)
|
||||||
|
Size 87: 44,87 BAD (HHHFHH)
|
||||||
|
Size 88: 44,88 BAD (HHHFHH)
|
||||||
|
Size 89: 45,89 BAD (HHHFHH)
|
||||||
|
Size 90: 45,90 BAD (HHHFHH)
|
||||||
|
Size 91: 46,91 BAD (HHHFHH)
|
||||||
|
Size 92: 46,92 BAD (HHHFHH)
|
||||||
|
Size 93: 47,93 BAD (HHHFHH)
|
||||||
|
Size 94: 47,94 BAD (HHHFHH)
|
||||||
|
Size 95: 48,95 BAD (HHHFHH)
|
||||||
|
Size 96: 48,97 BAD (HHHFHH)
|
||||||
|
Size 97: 49,97 BAD (HHHFHH)
|
||||||
|
Size 98: 49,98 BAD (HHHFHH)
|
||||||
|
Size 99: 50,99 BAD (HHHFHH)
|
||||||
|
Size 100: 50,100 BAD (HHHFHH)
|
||||||
|
|
||||||
|
Windows 7
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,4 OK (HHHFFF)
|
||||||
|
Size 5: 3,5 OK (HHHFFF)
|
||||||
|
Size 6: 3,6 OK (HHHFFF)
|
||||||
|
Size 7: 4,7 OK (HHHFFF)
|
||||||
|
Size 8: 4,8 OK (HHHFFF)
|
||||||
|
Size 9: 5,9 OK (HHHFFF)
|
||||||
|
Size 10: 5,10 OK (HHHFFF)
|
||||||
|
Size 11: 6,11 OK (HHHFFF)
|
||||||
|
Size 12: 6,12 OK (HHHFFF)
|
||||||
|
Size 13: 7,13 OK (HHHFFF)
|
||||||
|
Size 14: 7,14 BAD (FFFFFF)
|
||||||
|
Size 15: 8,15 OK (HHHFFF)
|
||||||
|
Size 16: 8,16 BAD (FFFFFF)
|
||||||
|
Size 17: 9,17 OK (HHHFFF)
|
||||||
|
Size 18: 9,18 BAD (FFFFFF)
|
||||||
|
Size 19: 10,19 OK (HHHFFF)
|
||||||
|
Size 20: 10,20 BAD (FFFFFF)
|
||||||
|
Size 21: 11,21 OK (HHHFFF)
|
||||||
|
Size 22: 11,22 BAD (FFFFFF)
|
||||||
|
Size 23: 12,23 BAD (FFFFFF)
|
||||||
|
Size 24: 12,24 BAD (FFFFFF)
|
||||||
|
Size 25: 13,25 BAD (FFFFFF)
|
||||||
|
Size 26: 13,26 BAD (FFFFFF)
|
||||||
|
Size 27: 14,27 BAD (FFFFFF)
|
||||||
|
Size 28: 14,28 BAD (FFFFFF)
|
||||||
|
Size 29: 15,29 BAD (FFFFFF)
|
||||||
|
Size 30: 15,30 BAD (FFFFFF)
|
||||||
|
Size 31: 16,31 BAD (FFFFFF)
|
||||||
|
Size 32: 16,33 BAD (FFFFFF)
|
||||||
|
Size 33: 17,33 BAD (FFFFFF)
|
||||||
|
Size 34: 17,34 BAD (FFFFFF)
|
||||||
|
Size 35: 18,35 BAD (FFFFFF)
|
||||||
|
Size 36: 18,36 BAD (FFFFFF)
|
||||||
|
Size 37: 19,37 BAD (FFFFFF)
|
||||||
|
Size 38: 19,38 BAD (FFFFFF)
|
||||||
|
Size 39: 20,39 BAD (FFFFFF)
|
||||||
|
Size 40: 20,40 BAD (FFFFFF)
|
||||||
|
Size 41: 21,41 BAD (FFFFFF)
|
||||||
|
Size 42: 21,42 BAD (FFFFFF)
|
||||||
|
Size 43: 22,43 BAD (FFFFFF)
|
||||||
|
Size 44: 22,44 BAD (FFFFFF)
|
||||||
|
Size 45: 23,45 BAD (FFFFFF)
|
||||||
|
Size 46: 23,46 BAD (FFFFFF)
|
||||||
|
Size 47: 24,47 BAD (FFFFFF)
|
||||||
|
Size 48: 24,48 BAD (FFFFFF)
|
||||||
|
Size 49: 25,49 BAD (FFFFFF)
|
||||||
|
Size 50: 25,50 BAD (FFFFFF)
|
||||||
|
Size 51: 26,51 BAD (FFFFFF)
|
||||||
|
Size 52: 26,52 BAD (FFFFFF)
|
||||||
|
Size 53: 27,53 BAD (FFFFFF)
|
||||||
|
Size 54: 27,54 BAD (FFFFFF)
|
||||||
|
Size 55: 28,55 BAD (FFFFFF)
|
||||||
|
Size 56: 28,56 BAD (FFFFFF)
|
||||||
|
Size 57: 29,57 BAD (FFFFFF)
|
||||||
|
Size 58: 29,58 BAD (FFFFFF)
|
||||||
|
Size 59: 30,59 BAD (FFFFFF)
|
||||||
|
Size 60: 30,60 BAD (FFFFFF)
|
||||||
|
Size 61: 31,61 BAD (FFFFFF)
|
||||||
|
Size 62: 31,62 BAD (FFFFFF)
|
||||||
|
Size 63: 32,63 BAD (FFFFFF)
|
||||||
|
Size 64: 32,64 BAD (FFFFFF)
|
||||||
|
Size 65: 33,65 BAD (FFFFFF)
|
||||||
|
Size 66: 33,66 BAD (FFFFFF)
|
||||||
|
Size 67: 34,67 BAD (FFFFFF)
|
||||||
|
Size 68: 34,68 BAD (FFFFFF)
|
||||||
|
Size 69: 35,69 BAD (FFFFFF)
|
||||||
|
Size 70: 35,70 BAD (FFFFFF)
|
||||||
|
Size 71: 36,71 BAD (FFFFFF)
|
||||||
|
Size 72: 36,72 BAD (FFFFFF)
|
||||||
|
Size 73: 37,73 BAD (FFFFFF)
|
||||||
|
Size 74: 37,74 BAD (FFFFFF)
|
||||||
|
Size 75: 38,75 BAD (FFFFFF)
|
||||||
|
Size 76: 38,76 BAD (FFFFFF)
|
||||||
|
Size 77: 39,77 BAD (FFFFFF)
|
||||||
|
Size 78: 39,78 BAD (FFFFFF)
|
||||||
|
Size 79: 40,79 BAD (FFFFFF)
|
||||||
|
Size 80: 40,80 BAD (FFFFFF)
|
||||||
|
Size 81: 41,81 BAD (FFFFFF)
|
||||||
|
Size 82: 41,82 BAD (FFFFFF)
|
||||||
|
Size 83: 42,83 BAD (FFFFFF)
|
||||||
|
Size 84: 42,84 BAD (FFFFFF)
|
||||||
|
Size 85: 43,85 BAD (FFFFFF)
|
||||||
|
Size 86: 43,86 BAD (FFFFFF)
|
||||||
|
Size 87: 44,87 BAD (FFFFFF)
|
||||||
|
Size 88: 44,88 BAD (FFFFFF)
|
||||||
|
Size 89: 45,89 BAD (FFFFFF)
|
||||||
|
Size 90: 45,90 BAD (FFFFFF)
|
||||||
|
Size 91: 46,91 BAD (FFFFFF)
|
||||||
|
Size 92: 46,92 BAD (FFFFFF)
|
||||||
|
Size 93: 47,93 BAD (FFFFFF)
|
||||||
|
Size 94: 47,94 BAD (FFFFFF)
|
||||||
|
Size 95: 48,95 BAD (FFFFFF)
|
||||||
|
Size 96: 48,97 BAD (FFFFFF)
|
||||||
|
Size 97: 49,97 BAD (FFFFFF)
|
||||||
|
Size 98: 49,98 BAD (FFFFFF)
|
||||||
|
Size 99: 50,99 BAD (FFFFFF)
|
||||||
|
Size 100: 50,100 BAD (FFFFFF)
|
||||||
|
|
||||||
|
Windows 8
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (FFFFHH)
|
||||||
|
Size 2: 1,2 BAD (FFFFHH)
|
||||||
|
Size 3: 2,3 BAD (FFFFFF)
|
||||||
|
Size 4: 2,4 BAD (FFFFHH)
|
||||||
|
Size 5: 3,5 BAD (FFFFFF)
|
||||||
|
Size 6: 3,6 BAD (FFFFHH)
|
||||||
|
Size 7: 4,7 BAD (FFFFFF)
|
||||||
|
Size 8: 4,8 BAD (FFFFHH)
|
||||||
|
Size 9: 5,9 BAD (FFFFFF)
|
||||||
|
Size 10: 5,10 BAD (FFFFHH)
|
||||||
|
Size 11: 6,11 BAD (FFFFFF)
|
||||||
|
Size 12: 6,12 BAD (FFFFHH)
|
||||||
|
Size 13: 7,13 BAD (FFFFFF)
|
||||||
|
Size 14: 7,14 BAD (FFFFHH)
|
||||||
|
Size 15: 8,15 BAD (FFFFFF)
|
||||||
|
Size 16: 8,16 BAD (FFFFHH)
|
||||||
|
Size 17: 9,17 BAD (FFFFFF)
|
||||||
|
Size 18: 9,18 BAD (FFFFHH)
|
||||||
|
Size 19: 10,19 BAD (FFFFFF)
|
||||||
|
Size 20: 10,20 BAD (FFFFFF)
|
||||||
|
Size 21: 11,21 BAD (FFFFFF)
|
||||||
|
Size 22: 11,22 BAD (FFFFFF)
|
||||||
|
Size 23: 12,23 BAD (FFFFFF)
|
||||||
|
Size 24: 12,24 BAD (FFFFFF)
|
||||||
|
Size 25: 13,25 BAD (FFFFFF)
|
||||||
|
Size 26: 13,26 BAD (FFFFFF)
|
||||||
|
Size 27: 14,27 BAD (FFFFFF)
|
||||||
|
Size 28: 14,28 BAD (FFFFFF)
|
||||||
|
Size 29: 15,29 BAD (FFFFFF)
|
||||||
|
Size 30: 15,30 BAD (FFFFFF)
|
||||||
|
Size 31: 16,31 BAD (FFFFFF)
|
||||||
|
Size 32: 16,33 BAD (FFFFFF)
|
||||||
|
Size 33: 17,33 BAD (FFFFFF)
|
||||||
|
Size 34: 17,34 BAD (FFFFFF)
|
||||||
|
Size 35: 18,35 BAD (FFFFFF)
|
||||||
|
Size 36: 18,36 BAD (FFFFFF)
|
||||||
|
Size 37: 19,37 BAD (FFFFFF)
|
||||||
|
Size 38: 19,38 BAD (FFFFFF)
|
||||||
|
Size 39: 20,39 BAD (FFFFFF)
|
||||||
|
Size 40: 20,40 BAD (FFFFFF)
|
||||||
|
Size 41: 21,41 BAD (FFFFFF)
|
||||||
|
Size 42: 21,42 BAD (FFFFFF)
|
||||||
|
Size 43: 22,43 BAD (FFFFFF)
|
||||||
|
Size 44: 22,44 BAD (FFFFFF)
|
||||||
|
Size 45: 23,45 BAD (FFFFFF)
|
||||||
|
Size 46: 23,46 BAD (FFFFFF)
|
||||||
|
Size 47: 24,47 BAD (FFFFFF)
|
||||||
|
Size 48: 24,48 BAD (FFFFFF)
|
||||||
|
Size 49: 25,49 BAD (FFFFFF)
|
||||||
|
Size 50: 25,50 BAD (FFFFFF)
|
||||||
|
Size 51: 26,51 BAD (FFFFFF)
|
||||||
|
Size 52: 26,52 BAD (FFFFFF)
|
||||||
|
Size 53: 27,53 BAD (FFFFFF)
|
||||||
|
Size 54: 27,54 BAD (FFFFFF)
|
||||||
|
Size 55: 28,55 BAD (FFFFFF)
|
||||||
|
Size 56: 28,56 BAD (FFFFFF)
|
||||||
|
Size 57: 29,57 BAD (FFFFFF)
|
||||||
|
Size 58: 29,58 BAD (FFFFFF)
|
||||||
|
Size 59: 30,59 BAD (FFFFFF)
|
||||||
|
Size 60: 30,60 BAD (FFFFFF)
|
||||||
|
Size 61: 31,61 BAD (FFFFFF)
|
||||||
|
Size 62: 31,62 BAD (FFFFFF)
|
||||||
|
Size 63: 32,63 BAD (FFFFFF)
|
||||||
|
Size 64: 32,64 BAD (FFFFFF)
|
||||||
|
Size 65: 33,65 BAD (FFFFFF)
|
||||||
|
Size 66: 33,66 BAD (FFFFFF)
|
||||||
|
Size 67: 34,67 BAD (FFFFFF)
|
||||||
|
Size 68: 34,68 BAD (FFFFFF)
|
||||||
|
Size 69: 35,69 BAD (FFFFFF)
|
||||||
|
Size 70: 35,70 BAD (FFFFFF)
|
||||||
|
Size 71: 36,71 BAD (FFFFFF)
|
||||||
|
Size 72: 36,72 BAD (FFFFFF)
|
||||||
|
Size 73: 37,73 BAD (FFFFFF)
|
||||||
|
Size 74: 37,74 BAD (FFFFFF)
|
||||||
|
Size 75: 38,75 BAD (FFFFFF)
|
||||||
|
Size 76: 38,76 BAD (FFFFFF)
|
||||||
|
Size 77: 39,77 BAD (FFFFFF)
|
||||||
|
Size 78: 39,78 BAD (FFFFFF)
|
||||||
|
Size 79: 40,79 BAD (FFFFFF)
|
||||||
|
Size 80: 40,80 BAD (FFFFFF)
|
||||||
|
Size 81: 41,81 BAD (FFFFFF)
|
||||||
|
Size 82: 41,82 BAD (FFFFFF)
|
||||||
|
Size 83: 42,83 BAD (FFFFFF)
|
||||||
|
Size 84: 42,84 BAD (FFFFFF)
|
||||||
|
Size 85: 43,85 BAD (FFFFFF)
|
||||||
|
Size 86: 43,86 BAD (FFFFFF)
|
||||||
|
Size 87: 44,87 BAD (FFFFFF)
|
||||||
|
Size 88: 44,88 BAD (FFFFFF)
|
||||||
|
Size 89: 45,89 BAD (FFFFFF)
|
||||||
|
Size 90: 45,90 BAD (FFFFFF)
|
||||||
|
Size 91: 46,91 BAD (FFFFFF)
|
||||||
|
Size 92: 46,92 BAD (FFFFFF)
|
||||||
|
Size 93: 47,93 BAD (FFFFFF)
|
||||||
|
Size 94: 47,94 BAD (FFFFFF)
|
||||||
|
Size 95: 48,95 BAD (FFFFFF)
|
||||||
|
Size 96: 48,97 BAD (FFFFFF)
|
||||||
|
Size 97: 49,97 BAD (FFFFFF)
|
||||||
|
Size 98: 49,98 BAD (FFFFFF)
|
||||||
|
Size 99: 50,99 BAD (FFFFFF)
|
||||||
|
Size 100: 50,100 BAD (FFFFFF)
|
||||||
|
|
||||||
|
Windows 8.1
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (FFFFHH)
|
||||||
|
Size 2: 1,2 BAD (FFFFHH)
|
||||||
|
Size 3: 2,3 BAD (FFFFFF)
|
||||||
|
Size 4: 2,4 BAD (FFFFHH)
|
||||||
|
Size 5: 3,5 BAD (FFFFFF)
|
||||||
|
Size 6: 3,6 BAD (FFFFHH)
|
||||||
|
Size 7: 4,7 BAD (FFFFFF)
|
||||||
|
Size 8: 4,8 BAD (FFFFHH)
|
||||||
|
Size 9: 5,9 BAD (FFFFFF)
|
||||||
|
Size 10: 5,10 BAD (FFFFHH)
|
||||||
|
Size 11: 6,11 BAD (FFFFFF)
|
||||||
|
Size 12: 6,12 BAD (FFFFHH)
|
||||||
|
Size 13: 7,13 BAD (FFFFFF)
|
||||||
|
Size 14: 7,14 BAD (FFFFHH)
|
||||||
|
Size 15: 8,15 BAD (FFFFFF)
|
||||||
|
Size 16: 8,16 BAD (FFFFHH)
|
||||||
|
Size 17: 9,17 BAD (FFFFFF)
|
||||||
|
Size 18: 9,18 BAD (FFFFHH)
|
||||||
|
Size 19: 10,19 BAD (FFFFFF)
|
||||||
|
Size 20: 10,20 BAD (FFFFFF)
|
||||||
|
Size 21: 11,21 BAD (FFFFFF)
|
||||||
|
Size 22: 11,22 BAD (FFFFFF)
|
||||||
|
Size 23: 12,23 BAD (FFFFFF)
|
||||||
|
Size 24: 12,24 BAD (FFFFFF)
|
||||||
|
Size 25: 13,25 BAD (FFFFFF)
|
||||||
|
Size 26: 13,26 BAD (FFFFFF)
|
||||||
|
Size 27: 14,27 BAD (FFFFFF)
|
||||||
|
Size 28: 14,28 BAD (FFFFFF)
|
||||||
|
Size 29: 15,29 BAD (FFFFFF)
|
||||||
|
Size 30: 15,30 BAD (FFFFFF)
|
||||||
|
Size 31: 16,31 BAD (FFFFFF)
|
||||||
|
Size 32: 16,33 BAD (FFFFFF)
|
||||||
|
Size 33: 17,33 BAD (FFFFFF)
|
||||||
|
Size 34: 17,34 BAD (FFFFFF)
|
||||||
|
Size 35: 18,35 BAD (FFFFFF)
|
||||||
|
Size 36: 18,36 BAD (FFFFFF)
|
||||||
|
Size 37: 19,37 BAD (FFFFFF)
|
||||||
|
Size 38: 19,38 BAD (FFFFFF)
|
||||||
|
Size 39: 20,39 BAD (FFFFFF)
|
||||||
|
Size 40: 20,40 BAD (FFFFFF)
|
||||||
|
Size 41: 21,41 BAD (FFFFFF)
|
||||||
|
Size 42: 21,42 BAD (FFFFFF)
|
||||||
|
Size 43: 22,43 BAD (FFFFFF)
|
||||||
|
Size 44: 22,44 BAD (FFFFFF)
|
||||||
|
Size 45: 23,45 BAD (FFFFFF)
|
||||||
|
Size 46: 23,46 BAD (FFFFFF)
|
||||||
|
Size 47: 24,47 BAD (FFFFFF)
|
||||||
|
Size 48: 24,48 BAD (FFFFFF)
|
||||||
|
Size 49: 25,49 BAD (FFFFFF)
|
||||||
|
Size 50: 25,50 BAD (FFFFFF)
|
||||||
|
Size 51: 26,51 BAD (FFFFFF)
|
||||||
|
Size 52: 26,52 BAD (FFFFFF)
|
||||||
|
Size 53: 27,53 BAD (FFFFFF)
|
||||||
|
Size 54: 27,54 BAD (FFFFFF)
|
||||||
|
Size 55: 28,55 BAD (FFFFFF)
|
||||||
|
Size 56: 28,56 BAD (FFFFFF)
|
||||||
|
Size 57: 29,57 BAD (FFFFFF)
|
||||||
|
Size 58: 29,58 BAD (FFFFFF)
|
||||||
|
Size 59: 30,59 BAD (FFFFFF)
|
||||||
|
Size 60: 30,60 BAD (FFFFFF)
|
||||||
|
Size 61: 31,61 BAD (FFFFFF)
|
||||||
|
Size 62: 31,62 BAD (FFFFFF)
|
||||||
|
Size 63: 32,63 BAD (FFFFFF)
|
||||||
|
Size 64: 32,64 BAD (FFFFFF)
|
||||||
|
Size 65: 33,65 BAD (FFFFFF)
|
||||||
|
Size 66: 33,66 BAD (FFFFFF)
|
||||||
|
Size 67: 34,67 BAD (FFFFFF)
|
||||||
|
Size 68: 34,68 BAD (FFFFFF)
|
||||||
|
Size 69: 35,69 BAD (FFFFFF)
|
||||||
|
Size 70: 35,70 BAD (FFFFFF)
|
||||||
|
Size 71: 36,71 BAD (FFFFFF)
|
||||||
|
Size 72: 36,72 BAD (FFFFFF)
|
||||||
|
Size 73: 37,73 BAD (FFFFFF)
|
||||||
|
Size 74: 37,74 BAD (FFFFFF)
|
||||||
|
Size 75: 38,75 BAD (FFFFFF)
|
||||||
|
Size 76: 38,76 BAD (FFFFFF)
|
||||||
|
Size 77: 39,77 BAD (FFFFFF)
|
||||||
|
Size 78: 39,78 BAD (FFFFFF)
|
||||||
|
Size 79: 40,79 BAD (FFFFFF)
|
||||||
|
Size 80: 40,80 BAD (FFFFFF)
|
||||||
|
Size 81: 41,81 BAD (FFFFFF)
|
||||||
|
Size 82: 41,82 BAD (FFFFFF)
|
||||||
|
Size 83: 42,83 BAD (FFFFFF)
|
||||||
|
Size 84: 42,84 BAD (FFFFFF)
|
||||||
|
Size 85: 43,85 BAD (FFFFFF)
|
||||||
|
Size 86: 43,86 BAD (FFFFFF)
|
||||||
|
Size 87: 44,87 BAD (FFFFFF)
|
||||||
|
Size 88: 44,88 BAD (FFFFFF)
|
||||||
|
Size 89: 45,89 BAD (FFFFFF)
|
||||||
|
Size 90: 45,90 BAD (FFFFFF)
|
||||||
|
Size 91: 46,91 BAD (FFFFFF)
|
||||||
|
Size 92: 46,92 BAD (FFFFFF)
|
||||||
|
Size 93: 47,93 BAD (FFFFFF)
|
||||||
|
Size 94: 47,94 BAD (FFFFFF)
|
||||||
|
Size 95: 48,95 BAD (FFFFFF)
|
||||||
|
Size 96: 48,97 BAD (FFFFFF)
|
||||||
|
Size 97: 49,97 BAD (FFFFFF)
|
||||||
|
Size 98: 49,98 BAD (FFFFFF)
|
||||||
|
Size 99: 50,99 BAD (FFFFFF)
|
||||||
|
Size 100: 50,100 BAD (FFFFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 Old Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,2 BAD (FFFFHH)
|
||||||
|
Size 2: 1,2 BAD (FFFFHH)
|
||||||
|
Size 3: 2,3 BAD (FFFFFF)
|
||||||
|
Size 4: 2,4 BAD (FFFFHH)
|
||||||
|
Size 5: 3,5 BAD (FFFFFF)
|
||||||
|
Size 6: 3,6 BAD (FFFFHH)
|
||||||
|
Size 7: 4,7 BAD (FFFFFF)
|
||||||
|
Size 8: 4,8 BAD (FFFFHH)
|
||||||
|
Size 9: 5,9 BAD (FFFFFF)
|
||||||
|
Size 10: 5,10 BAD (FFFFHH)
|
||||||
|
Size 11: 6,11 BAD (FFFFFF)
|
||||||
|
Size 12: 6,12 BAD (FFFFHH)
|
||||||
|
Size 13: 7,13 BAD (FFFFFF)
|
||||||
|
Size 14: 7,14 BAD (FFFFHH)
|
||||||
|
Size 15: 8,15 BAD (FFFFFF)
|
||||||
|
Size 16: 8,16 BAD (FFFFHH)
|
||||||
|
Size 17: 9,17 BAD (FFFFFF)
|
||||||
|
Size 18: 9,18 BAD (FFFFHH)
|
||||||
|
Size 19: 10,19 BAD (FFFFFF)
|
||||||
|
Size 20: 10,20 BAD (FFFFFF)
|
||||||
|
Size 21: 11,21 BAD (FFFFFF)
|
||||||
|
Size 22: 11,22 BAD (FFFFFF)
|
||||||
|
Size 23: 12,23 BAD (FFFFFF)
|
||||||
|
Size 24: 12,24 BAD (FFFFFF)
|
||||||
|
Size 25: 13,25 BAD (FFFFFF)
|
||||||
|
Size 26: 13,26 BAD (FFFFFF)
|
||||||
|
Size 27: 14,27 BAD (FFFFFF)
|
||||||
|
Size 28: 14,28 BAD (FFFFFF)
|
||||||
|
Size 29: 15,29 BAD (FFFFFF)
|
||||||
|
Size 30: 15,30 BAD (FFFFFF)
|
||||||
|
Size 31: 16,31 BAD (FFFFFF)
|
||||||
|
Size 32: 16,33 BAD (FFFFFF)
|
||||||
|
Size 33: 17,33 BAD (FFFFFF)
|
||||||
|
Size 34: 17,34 BAD (FFFFFF)
|
||||||
|
Size 35: 18,35 BAD (FFFFFF)
|
||||||
|
Size 36: 18,36 BAD (FFFFFF)
|
||||||
|
Size 37: 19,37 BAD (FFFFFF)
|
||||||
|
Size 38: 19,38 BAD (FFFFFF)
|
||||||
|
Size 39: 20,39 BAD (FFFFFF)
|
||||||
|
Size 40: 20,40 BAD (FFFFFF)
|
||||||
|
Size 41: 21,41 BAD (FFFFFF)
|
||||||
|
Size 42: 21,42 BAD (FFFFFF)
|
||||||
|
Size 43: 22,43 BAD (FFFFFF)
|
||||||
|
Size 44: 22,44 BAD (FFFFFF)
|
||||||
|
Size 45: 23,45 BAD (FFFFFF)
|
||||||
|
Size 46: 23,46 BAD (FFFFFF)
|
||||||
|
Size 47: 24,47 BAD (FFFFFF)
|
||||||
|
Size 48: 24,48 BAD (FFFFFF)
|
||||||
|
Size 49: 25,49 BAD (FFFFFF)
|
||||||
|
Size 50: 25,50 BAD (FFFFFF)
|
||||||
|
Size 51: 26,51 BAD (FFFFFF)
|
||||||
|
Size 52: 26,52 BAD (FFFFFF)
|
||||||
|
Size 53: 27,53 BAD (FFFFFF)
|
||||||
|
Size 54: 27,54 BAD (FFFFFF)
|
||||||
|
Size 55: 28,55 BAD (FFFFFF)
|
||||||
|
Size 56: 28,56 BAD (FFFFFF)
|
||||||
|
Size 57: 29,57 BAD (FFFFFF)
|
||||||
|
Size 58: 29,58 BAD (FFFFFF)
|
||||||
|
Size 59: 30,59 BAD (FFFFFF)
|
||||||
|
Size 60: 30,60 BAD (FFFFFF)
|
||||||
|
Size 61: 31,61 BAD (FFFFFF)
|
||||||
|
Size 62: 31,62 BAD (FFFFFF)
|
||||||
|
Size 63: 32,63 BAD (FFFFFF)
|
||||||
|
Size 64: 32,64 BAD (FFFFFF)
|
||||||
|
Size 65: 33,65 BAD (FFFFFF)
|
||||||
|
Size 66: 33,66 BAD (FFFFFF)
|
||||||
|
Size 67: 34,67 BAD (FFFFFF)
|
||||||
|
Size 68: 34,68 BAD (FFFFFF)
|
||||||
|
Size 69: 35,69 BAD (FFFFFF)
|
||||||
|
Size 70: 35,70 BAD (FFFFFF)
|
||||||
|
Size 71: 36,71 BAD (FFFFFF)
|
||||||
|
Size 72: 36,72 BAD (FFFFFF)
|
||||||
|
Size 73: 37,73 BAD (FFFFFF)
|
||||||
|
Size 74: 37,74 BAD (FFFFFF)
|
||||||
|
Size 75: 38,75 BAD (FFFFFF)
|
||||||
|
Size 76: 38,76 BAD (FFFFFF)
|
||||||
|
Size 77: 39,77 BAD (FFFFFF)
|
||||||
|
Size 78: 39,78 BAD (FFFFFF)
|
||||||
|
Size 79: 40,79 BAD (FFFFFF)
|
||||||
|
Size 80: 40,80 BAD (FFFFFF)
|
||||||
|
Size 81: 41,81 BAD (FFFFFF)
|
||||||
|
Size 82: 41,82 BAD (FFFFFF)
|
||||||
|
Size 83: 42,83 BAD (FFFFFF)
|
||||||
|
Size 84: 42,84 BAD (FFFFFF)
|
||||||
|
Size 85: 43,85 BAD (FFFFFF)
|
||||||
|
Size 86: 43,86 BAD (FFFFFF)
|
||||||
|
Size 87: 44,87 BAD (FFFFFF)
|
||||||
|
Size 88: 44,88 BAD (FFFFFF)
|
||||||
|
Size 89: 45,89 BAD (FFFFFF)
|
||||||
|
Size 90: 45,90 BAD (FFFFFF)
|
||||||
|
Size 91: 46,91 BAD (FFFFFF)
|
||||||
|
Size 92: 46,92 BAD (FFFFFF)
|
||||||
|
Size 93: 47,93 BAD (FFFFFF)
|
||||||
|
Size 94: 47,94 BAD (FFFFFF)
|
||||||
|
Size 95: 48,95 BAD (FFFFFF)
|
||||||
|
Size 96: 48,97 BAD (FFFFFF)
|
||||||
|
Size 97: 49,97 BAD (FFFFFF)
|
||||||
|
Size 98: 49,98 BAD (FFFFFF)
|
||||||
|
Size 99: 50,99 BAD (FFFFFF)
|
||||||
|
Size 100: 50,100 BAD (FFFFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 New Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,1 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 OK (HHHFFF)
|
||||||
|
Size 4: 2,4 OK (HHHFFF)
|
||||||
|
Size 5: 3,5 OK (HHHFFF)
|
||||||
|
Size 6: 3,6 OK (HHHFFF)
|
||||||
|
Size 7: 4,7 OK (HHHFFF)
|
||||||
|
Size 8: 4,8 OK (HHHFFF)
|
||||||
|
Size 9: 5,9 OK (HHHFFF)
|
||||||
|
Size 10: 5,10 OK (HHHFFF)
|
||||||
|
Size 11: 6,11 OK (HHHFFF)
|
||||||
|
Size 12: 6,12 OK (HHHFFF)
|
||||||
|
Size 13: 7,13 OK (HHHFFF)
|
||||||
|
Size 14: 7,14 OK (HHHFFF)
|
||||||
|
Size 15: 8,15 OK (HHHFFF)
|
||||||
|
Size 16: 8,16 OK (HHHFFF)
|
||||||
|
Size 17: 9,17 OK (HHHFFF)
|
||||||
|
Size 18: 9,18 OK (HHHFFF)
|
||||||
|
Size 19: 10,19 OK (HHHFFF)
|
||||||
|
Size 20: 10,20 OK (HHHFFF)
|
||||||
|
Size 21: 11,21 OK (HHHFFF)
|
||||||
|
Size 22: 11,22 OK (HHHFFF)
|
||||||
|
Size 23: 12,23 OK (HHHFFF)
|
||||||
|
Size 24: 12,24 OK (HHHFFF)
|
||||||
|
Size 25: 13,25 OK (HHHFFF)
|
||||||
|
Size 26: 13,26 OK (HHHFFF)
|
||||||
|
Size 27: 14,27 OK (HHHFFF)
|
||||||
|
Size 28: 14,28 OK (HHHFFF)
|
||||||
|
Size 29: 15,29 OK (HHHFFF)
|
||||||
|
Size 30: 15,30 OK (HHHFFF)
|
||||||
|
Size 31: 16,31 OK (HHHFFF)
|
||||||
|
Size 32: 16,32 OK (HHHFFF)
|
||||||
|
Size 33: 17,33 OK (HHHFFF)
|
||||||
|
Size 34: 17,34 OK (HHHFFF)
|
||||||
|
Size 35: 18,35 OK (HHHFFF)
|
||||||
|
Size 36: 18,36 OK (HHHFFF)
|
||||||
|
Size 37: 19,37 OK (HHHFFF)
|
||||||
|
Size 38: 19,38 OK (HHHFFF)
|
||||||
|
Size 39: 20,39 OK (HHHFFF)
|
||||||
|
Size 40: 20,40 OK (HHHFFF)
|
||||||
|
Size 41: 21,41 OK (HHHFFF)
|
||||||
|
Size 42: 21,42 OK (HHHFFF)
|
||||||
|
Size 43: 22,43 OK (HHHFFF)
|
||||||
|
Size 44: 22,44 OK (HHHFFF)
|
||||||
|
Size 45: 23,45 OK (HHHFFF)
|
||||||
|
Size 46: 23,46 OK (HHHFFF)
|
||||||
|
Size 47: 24,47 OK (HHHFFF)
|
||||||
|
Size 48: 24,48 OK (HHHFFF)
|
||||||
|
Size 49: 25,49 OK (HHHFFF)
|
||||||
|
Size 50: 25,50 OK (HHHFFF)
|
||||||
|
Size 51: 26,51 OK (HHHFFF)
|
||||||
|
Size 52: 26,52 OK (HHHFFF)
|
||||||
|
Size 53: 27,53 OK (HHHFFF)
|
||||||
|
Size 54: 27,54 OK (HHHFFF)
|
||||||
|
Size 55: 28,55 OK (HHHFFF)
|
||||||
|
Size 56: 28,56 OK (HHHFFF)
|
||||||
|
Size 57: 29,57 OK (HHHFFF)
|
||||||
|
Size 58: 29,58 OK (HHHFFF)
|
||||||
|
Size 59: 30,59 OK (HHHFFF)
|
||||||
|
Size 60: 30,60 OK (HHHFFF)
|
||||||
|
Size 61: 31,61 OK (HHHFFF)
|
||||||
|
Size 62: 31,62 OK (HHHFFF)
|
||||||
|
Size 63: 32,63 OK (HHHFFF)
|
||||||
|
Size 64: 32,64 OK (HHHFFF)
|
||||||
|
Size 65: 33,65 OK (HHHFFF)
|
||||||
|
Size 66: 33,66 OK (HHHFFF)
|
||||||
|
Size 67: 34,67 OK (HHHFFF)
|
||||||
|
Size 68: 34,68 OK (HHHFFF)
|
||||||
|
Size 69: 35,69 OK (HHHFFF)
|
||||||
|
Size 70: 35,70 OK (HHHFFF)
|
||||||
|
Size 71: 36,71 OK (HHHFFF)
|
||||||
|
Size 72: 36,72 OK (HHHFFF)
|
||||||
|
Size 73: 37,73 OK (HHHFFF)
|
||||||
|
Size 74: 37,74 OK (HHHFFF)
|
||||||
|
Size 75: 38,75 OK (HHHFFF)
|
||||||
|
Size 76: 38,76 OK (HHHFFF)
|
||||||
|
Size 77: 39,77 OK (HHHFFF)
|
||||||
|
Size 78: 39,78 OK (HHHFFF)
|
||||||
|
Size 79: 40,79 OK (HHHFFF)
|
||||||
|
Size 80: 40,80 OK (HHHFFF)
|
||||||
|
Size 81: 41,81 OK (HHHFFF)
|
||||||
|
Size 82: 41,82 OK (HHHFFF)
|
||||||
|
Size 83: 42,83 OK (HHHFFF)
|
||||||
|
Size 84: 42,84 OK (HHHFFF)
|
||||||
|
Size 85: 43,85 OK (HHHFFF)
|
||||||
|
Size 86: 43,86 OK (HHHFFF)
|
||||||
|
Size 87: 44,87 OK (HHHFFF)
|
||||||
|
Size 88: 44,88 OK (HHHFFF)
|
||||||
|
Size 89: 45,89 OK (HHHFFF)
|
||||||
|
Size 90: 45,90 OK (HHHFFF)
|
||||||
|
Size 91: 46,91 OK (HHHFFF)
|
||||||
|
Size 92: 46,92 OK (HHHFFF)
|
||||||
|
Size 93: 47,93 OK (HHHFFF)
|
||||||
|
Size 94: 47,94 OK (HHHFFF)
|
||||||
|
Size 95: 48,95 OK (HHHFFF)
|
||||||
|
Size 96: 48,96 OK (HHHFFF)
|
||||||
|
Size 97: 49,97 OK (HHHFFF)
|
||||||
|
Size 98: 49,98 OK (HHHFFF)
|
||||||
|
Size 99: 50,99 OK (HHHFFF)
|
||||||
|
Size 100: 50,100 OK (HHHFFF)
|
||||||
Generated
Vendored
+630
@@ -0,0 +1,630 @@
|
|||||||
|
==========================================================
|
||||||
|
Code Page 936, Chinese Simplified (China/PRC), SimSun font
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
Options: -face-simsun -family 0x36
|
||||||
|
Chars: A2 A3 2014 3044 30FC 4000
|
||||||
|
|
||||||
|
Vista
|
||||||
|
-----
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (HHHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (HHHFHH)
|
||||||
|
Size 8: 4,9 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,10 BAD (HHHFHH)
|
||||||
|
Size 10: 5,11 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (HHHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,15 BAD (HHHFHH)
|
||||||
|
Size 14: 7,16 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,17 BAD (HHHFHH)
|
||||||
|
Size 16: 8,18 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,19 BAD (HHHFHH)
|
||||||
|
Size 18: 9,21 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,22 BAD (HHHFHH)
|
||||||
|
Size 20: 10,23 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,24 BAD (HHHFHH)
|
||||||
|
Size 22: 11,25 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,26 BAD (HHHFHH)
|
||||||
|
Size 24: 12,27 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,29 BAD (HHHFHH)
|
||||||
|
Size 26: 13,30 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,31 BAD (HHHFHH)
|
||||||
|
Size 28: 14,32 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,33 BAD (HHHFHH)
|
||||||
|
Size 30: 15,34 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,35 BAD (HHHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,38 BAD (HHHFHH)
|
||||||
|
Size 34: 17,39 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,40 BAD (HHHFHH)
|
||||||
|
Size 36: 18,41 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,42 BAD (HHHFHH)
|
||||||
|
Size 38: 19,43 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,44 BAD (HHHFHH)
|
||||||
|
Size 40: 20,46 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,47 BAD (HHHFHH)
|
||||||
|
Size 42: 21,48 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,49 BAD (HHHFHH)
|
||||||
|
Size 44: 22,50 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,51 BAD (HHHFHH)
|
||||||
|
Size 46: 23,52 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,54 BAD (HHHFHH)
|
||||||
|
Size 48: 24,55 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,56 BAD (HHHFHH)
|
||||||
|
Size 50: 25,57 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,58 BAD (HHHFHH)
|
||||||
|
Size 52: 26,59 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,60 BAD (HHHFHH)
|
||||||
|
Size 54: 27,62 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,63 BAD (HHHFHH)
|
||||||
|
Size 56: 28,64 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,65 BAD (HHHFHH)
|
||||||
|
Size 58: 29,66 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,67 BAD (HHHFHH)
|
||||||
|
Size 60: 30,68 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,70 BAD (HHHFHH)
|
||||||
|
Size 62: 31,71 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,72 BAD (HHHFHH)
|
||||||
|
Size 64: 32,73 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,74 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,75 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,76 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,78 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,79 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,80 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,81 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,82 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,83 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,84 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,86 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,87 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,88 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,89 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,90 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,91 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,92 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,94 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,95 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,96 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,97 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,98 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,99 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,100 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,102 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,103 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,104 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,105 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,106 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,107 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,108 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,111 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,111 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,112 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,113 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,114 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 7
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,9 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,10 BAD (FFHFHH)
|
||||||
|
Size 10: 5,11 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,15 BAD (FFHFHH)
|
||||||
|
Size 14: 7,16 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,17 BAD (FFHFHH)
|
||||||
|
Size 16: 8,18 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,19 BAD (FFHFHH)
|
||||||
|
Size 18: 9,21 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,22 BAD (FFHFHH)
|
||||||
|
Size 20: 10,23 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,24 BAD (FFHFHH)
|
||||||
|
Size 22: 11,25 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,26 BAD (FFHFHH)
|
||||||
|
Size 24: 12,27 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,29 BAD (FFHFHH)
|
||||||
|
Size 26: 13,30 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,31 BAD (FFHFHH)
|
||||||
|
Size 28: 14,32 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,33 BAD (FFHFHH)
|
||||||
|
Size 30: 15,34 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,35 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,38 BAD (FFHFHH)
|
||||||
|
Size 34: 17,39 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,40 BAD (FFHFHH)
|
||||||
|
Size 36: 18,41 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,42 BAD (FFHFHH)
|
||||||
|
Size 38: 19,43 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,44 BAD (FFHFHH)
|
||||||
|
Size 40: 20,46 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,47 BAD (FFHFHH)
|
||||||
|
Size 42: 21,48 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,49 BAD (FFHFHH)
|
||||||
|
Size 44: 22,50 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,51 BAD (FFHFHH)
|
||||||
|
Size 46: 23,52 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,54 BAD (FFHFHH)
|
||||||
|
Size 48: 24,55 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,56 BAD (FFHFHH)
|
||||||
|
Size 50: 25,57 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,58 BAD (FFHFHH)
|
||||||
|
Size 52: 26,59 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,60 BAD (FFHFHH)
|
||||||
|
Size 54: 27,62 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,63 BAD (FFHFHH)
|
||||||
|
Size 56: 28,64 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,65 BAD (FFHFHH)
|
||||||
|
Size 58: 29,66 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,67 BAD (FFHFHH)
|
||||||
|
Size 60: 30,68 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,70 BAD (FFHFHH)
|
||||||
|
Size 62: 31,71 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,72 BAD (FFHFHH)
|
||||||
|
Size 64: 32,73 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,74 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,75 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,76 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,78 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,79 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,80 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,81 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,82 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,83 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,84 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,86 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,87 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,88 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,89 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,90 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,91 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,92 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,94 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,95 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,96 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,97 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,98 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,99 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,100 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,102 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,103 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,104 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,105 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,106 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,107 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,108 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,111 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,111 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,112 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,113 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,114 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 8
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,9 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,10 BAD (FFHFHH)
|
||||||
|
Size 10: 5,11 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,15 BAD (FFHFHH)
|
||||||
|
Size 14: 7,16 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,17 BAD (FFHFHH)
|
||||||
|
Size 16: 8,18 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,19 BAD (FFHFHH)
|
||||||
|
Size 18: 9,21 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,22 BAD (FFHFHH)
|
||||||
|
Size 20: 10,23 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,24 BAD (FFHFHH)
|
||||||
|
Size 22: 11,25 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,26 BAD (FFHFHH)
|
||||||
|
Size 24: 12,27 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,29 BAD (FFHFHH)
|
||||||
|
Size 26: 13,30 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,31 BAD (FFHFHH)
|
||||||
|
Size 28: 14,32 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,33 BAD (FFHFHH)
|
||||||
|
Size 30: 15,34 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,35 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,38 BAD (FFHFHH)
|
||||||
|
Size 34: 17,39 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,40 BAD (FFHFHH)
|
||||||
|
Size 36: 18,41 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,42 BAD (FFHFHH)
|
||||||
|
Size 38: 19,43 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,44 BAD (FFHFHH)
|
||||||
|
Size 40: 20,46 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,47 BAD (FFHFHH)
|
||||||
|
Size 42: 21,48 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,49 BAD (FFHFHH)
|
||||||
|
Size 44: 22,50 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,51 BAD (FFHFHH)
|
||||||
|
Size 46: 23,52 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,54 BAD (FFHFHH)
|
||||||
|
Size 48: 24,55 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,56 BAD (FFHFHH)
|
||||||
|
Size 50: 25,57 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,58 BAD (FFHFHH)
|
||||||
|
Size 52: 26,59 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,60 BAD (FFHFHH)
|
||||||
|
Size 54: 27,62 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,63 BAD (FFHFHH)
|
||||||
|
Size 56: 28,64 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,65 BAD (FFHFHH)
|
||||||
|
Size 58: 29,66 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,67 BAD (FFHFHH)
|
||||||
|
Size 60: 30,68 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,70 BAD (FFHFHH)
|
||||||
|
Size 62: 31,71 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,72 BAD (FFHFHH)
|
||||||
|
Size 64: 32,73 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,74 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,75 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,76 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,78 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,79 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,80 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,81 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,82 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,83 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,84 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,86 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,87 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,88 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,89 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,90 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,91 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,92 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,94 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,95 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,96 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,97 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,98 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,99 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,100 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,102 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,103 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,104 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,105 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,106 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,107 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,108 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,111 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,111 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,112 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,113 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,114 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 8.1
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,9 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,10 BAD (FFHFHH)
|
||||||
|
Size 10: 5,11 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,15 BAD (FFHFHH)
|
||||||
|
Size 14: 7,16 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,17 BAD (FFHFHH)
|
||||||
|
Size 16: 8,18 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,19 BAD (FFHFHH)
|
||||||
|
Size 18: 9,21 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,22 BAD (FFHFHH)
|
||||||
|
Size 20: 10,23 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,24 BAD (FFHFHH)
|
||||||
|
Size 22: 11,25 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,26 BAD (FFHFHH)
|
||||||
|
Size 24: 12,27 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,29 BAD (FFHFHH)
|
||||||
|
Size 26: 13,30 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,31 BAD (FFHFHH)
|
||||||
|
Size 28: 14,32 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,33 BAD (FFHFHH)
|
||||||
|
Size 30: 15,34 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,35 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,38 BAD (FFHFHH)
|
||||||
|
Size 34: 17,39 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,40 BAD (FFHFHH)
|
||||||
|
Size 36: 18,41 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,42 BAD (FFHFHH)
|
||||||
|
Size 38: 19,43 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,44 BAD (FFHFHH)
|
||||||
|
Size 40: 20,46 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,47 BAD (FFHFHH)
|
||||||
|
Size 42: 21,48 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,49 BAD (FFHFHH)
|
||||||
|
Size 44: 22,50 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,51 BAD (FFHFHH)
|
||||||
|
Size 46: 23,52 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,54 BAD (FFHFHH)
|
||||||
|
Size 48: 24,55 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,56 BAD (FFHFHH)
|
||||||
|
Size 50: 25,57 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,58 BAD (FFHFHH)
|
||||||
|
Size 52: 26,59 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,60 BAD (FFHFHH)
|
||||||
|
Size 54: 27,62 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,63 BAD (FFHFHH)
|
||||||
|
Size 56: 28,64 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,65 BAD (FFHFHH)
|
||||||
|
Size 58: 29,66 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,67 BAD (FFHFHH)
|
||||||
|
Size 60: 30,68 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,70 BAD (FFHFHH)
|
||||||
|
Size 62: 31,71 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,72 BAD (FFHFHH)
|
||||||
|
Size 64: 32,73 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,74 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,75 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,76 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,78 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,79 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,80 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,81 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,82 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,83 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,84 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,86 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,87 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,88 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,89 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,90 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,91 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,92 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,94 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,95 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,96 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,97 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,98 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,99 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,100 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,102 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,103 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,104 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,105 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,106 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,107 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,108 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,111 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,111 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,112 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,113 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,114 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 Old Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,9 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,10 BAD (FFHFHH)
|
||||||
|
Size 10: 5,11 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,15 BAD (FFHFHH)
|
||||||
|
Size 14: 7,16 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,17 BAD (FFHFHH)
|
||||||
|
Size 16: 8,18 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,19 BAD (FFHFHH)
|
||||||
|
Size 18: 9,21 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,22 BAD (FFHFHH)
|
||||||
|
Size 20: 10,23 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,24 BAD (FFHFHH)
|
||||||
|
Size 22: 11,25 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,26 BAD (FFHFHH)
|
||||||
|
Size 24: 12,27 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,29 BAD (FFHFHH)
|
||||||
|
Size 26: 13,30 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,31 BAD (FFHFHH)
|
||||||
|
Size 28: 14,32 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,33 BAD (FFHFHH)
|
||||||
|
Size 30: 15,34 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,35 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,38 BAD (FFHFHH)
|
||||||
|
Size 34: 17,39 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,40 BAD (FFHFHH)
|
||||||
|
Size 36: 18,41 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,42 BAD (FFHFHH)
|
||||||
|
Size 38: 19,43 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,44 BAD (FFHFHH)
|
||||||
|
Size 40: 20,46 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,47 BAD (FFHFHH)
|
||||||
|
Size 42: 21,48 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,49 BAD (FFHFHH)
|
||||||
|
Size 44: 22,50 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,51 BAD (FFHFHH)
|
||||||
|
Size 46: 23,52 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,54 BAD (FFHFHH)
|
||||||
|
Size 48: 24,55 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,56 BAD (FFHFHH)
|
||||||
|
Size 50: 25,57 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,58 BAD (FFHFHH)
|
||||||
|
Size 52: 26,59 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,60 BAD (FFHFHH)
|
||||||
|
Size 54: 27,62 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,63 BAD (FFHFHH)
|
||||||
|
Size 56: 28,64 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,65 BAD (FFHFHH)
|
||||||
|
Size 58: 29,66 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,67 BAD (FFHFHH)
|
||||||
|
Size 60: 30,68 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,70 BAD (FFHFHH)
|
||||||
|
Size 62: 31,71 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,72 BAD (FFHFHH)
|
||||||
|
Size 64: 32,73 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,74 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,75 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,76 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,78 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,79 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,80 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,81 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,82 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,83 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,84 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,86 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,87 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,88 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,89 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,90 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,91 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,92 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,94 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,95 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,96 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,97 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,98 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,99 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,100 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,102 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,103 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,104 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,105 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,106 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,107 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,108 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,111 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,111 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,112 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,113 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,114 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 New Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,1 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 GOOD (HHFFFF)
|
||||||
|
Size 4: 2,4 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,5 GOOD (HHFFFF)
|
||||||
|
Size 6: 3,6 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,7 GOOD (HHFFFF)
|
||||||
|
Size 8: 4,8 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,9 GOOD (HHFFFF)
|
||||||
|
Size 10: 5,10 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,11 GOOD (HHFFFF)
|
||||||
|
Size 12: 6,12 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,13 GOOD (HHFFFF)
|
||||||
|
Size 14: 7,14 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,15 GOOD (HHFFFF)
|
||||||
|
Size 16: 8,16 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,17 GOOD (HHFFFF)
|
||||||
|
Size 18: 9,18 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,19 GOOD (HHFFFF)
|
||||||
|
Size 20: 10,20 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,21 GOOD (HHFFFF)
|
||||||
|
Size 22: 11,22 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,23 GOOD (HHFFFF)
|
||||||
|
Size 24: 12,24 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,25 GOOD (HHFFFF)
|
||||||
|
Size 26: 13,26 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,27 GOOD (HHFFFF)
|
||||||
|
Size 28: 14,28 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,29 GOOD (HHFFFF)
|
||||||
|
Size 30: 15,30 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,31 GOOD (HHFFFF)
|
||||||
|
Size 32: 16,32 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,33 GOOD (HHFFFF)
|
||||||
|
Size 34: 17,34 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,35 GOOD (HHFFFF)
|
||||||
|
Size 36: 18,36 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,37 GOOD (HHFFFF)
|
||||||
|
Size 38: 19,38 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,39 GOOD (HHFFFF)
|
||||||
|
Size 40: 20,40 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,41 GOOD (HHFFFF)
|
||||||
|
Size 42: 21,42 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,43 GOOD (HHFFFF)
|
||||||
|
Size 44: 22,44 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,45 GOOD (HHFFFF)
|
||||||
|
Size 46: 23,46 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,47 GOOD (HHFFFF)
|
||||||
|
Size 48: 24,48 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,49 GOOD (HHFFFF)
|
||||||
|
Size 50: 25,50 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,51 GOOD (HHFFFF)
|
||||||
|
Size 52: 26,52 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,53 GOOD (HHFFFF)
|
||||||
|
Size 54: 27,54 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,55 GOOD (HHFFFF)
|
||||||
|
Size 56: 28,56 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,57 GOOD (HHFFFF)
|
||||||
|
Size 58: 29,58 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,59 GOOD (HHFFFF)
|
||||||
|
Size 60: 30,60 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,61 GOOD (HHFFFF)
|
||||||
|
Size 62: 31,62 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,63 GOOD (HHFFFF)
|
||||||
|
Size 64: 32,64 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,65 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,66 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,67 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,68 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,69 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,70 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,71 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,72 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,73 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,74 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,75 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,76 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,77 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,78 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,79 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,80 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,81 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,82 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,83 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,84 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,85 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,86 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,87 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,88 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,89 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,90 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,91 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,92 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,93 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,94 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,95 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,96 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,97 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,98 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,99 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,100 GOOD (HHFFFF)
|
||||||
Generated
Vendored
+630
@@ -0,0 +1,630 @@
|
|||||||
|
=====================================
|
||||||
|
Code Page 949, Korean, GulimChe font
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Options: -face-gulimche -family 0x36
|
||||||
|
Chars: A2 A3 2014 3044 30FC 4000
|
||||||
|
|
||||||
|
Vista
|
||||||
|
-----
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,5 OK (HHHFFF)
|
||||||
|
Size 5: 3,6 BAD (HHHFHH)
|
||||||
|
Size 6: 3,7 OK (HHHFFF)
|
||||||
|
Size 7: 4,8 BAD (HHHFHH)
|
||||||
|
Size 8: 4,9 OK (HHHFFF)
|
||||||
|
Size 9: 5,10 BAD (HHHFHH)
|
||||||
|
Size 10: 5,11 OK (HHHFFF)
|
||||||
|
Size 11: 6,13 BAD (HHHFHH)
|
||||||
|
Size 12: 6,14 OK (HHHFFF)
|
||||||
|
Size 13: 7,15 BAD (HHHFHH)
|
||||||
|
Size 14: 7,16 OK (HHHFFF)
|
||||||
|
Size 15: 8,17 BAD (HHHFHH)
|
||||||
|
Size 16: 8,18 OK (HHHFFF)
|
||||||
|
Size 17: 9,20 BAD (HHHFHH)
|
||||||
|
Size 18: 9,21 OK (HHHFFF)
|
||||||
|
Size 19: 10,22 BAD (HHHFHH)
|
||||||
|
Size 20: 10,23 OK (HHHFFF)
|
||||||
|
Size 21: 11,24 BAD (HHHFHH)
|
||||||
|
Size 22: 11,25 OK (HHHFFF)
|
||||||
|
Size 23: 12,26 BAD (HHHFHH)
|
||||||
|
Size 24: 12,28 OK (HHHFFF)
|
||||||
|
Size 25: 13,29 BAD (HHHFHH)
|
||||||
|
Size 26: 13,30 OK (HHHFFF)
|
||||||
|
Size 27: 14,31 BAD (HHHFHH)
|
||||||
|
Size 28: 14,32 OK (HHHFFF)
|
||||||
|
Size 29: 15,33 BAD (HHHFHH)
|
||||||
|
Size 30: 15,34 OK (HHHFFF)
|
||||||
|
Size 31: 16,36 BAD (HHHFHH)
|
||||||
|
Size 32: 16,37 OK (HHHFFF)
|
||||||
|
Size 33: 17,38 BAD (HHHFHH)
|
||||||
|
Size 34: 17,39 OK (HHHFFF)
|
||||||
|
Size 35: 18,40 BAD (HHHFHH)
|
||||||
|
Size 36: 18,41 OK (HHHFFF)
|
||||||
|
Size 37: 19,42 BAD (HHHFHH)
|
||||||
|
Size 38: 19,44 OK (HHHFFF)
|
||||||
|
Size 39: 20,45 BAD (HHHFHH)
|
||||||
|
Size 40: 20,46 OK (HHHFFF)
|
||||||
|
Size 41: 21,47 BAD (HHHFHH)
|
||||||
|
Size 42: 21,48 OK (HHHFFF)
|
||||||
|
Size 43: 22,49 BAD (HHHFHH)
|
||||||
|
Size 44: 22,51 OK (HHHFFF)
|
||||||
|
Size 45: 23,52 BAD (HHHFHH)
|
||||||
|
Size 46: 23,53 OK (HHHFFF)
|
||||||
|
Size 47: 24,54 BAD (HHHFHH)
|
||||||
|
Size 48: 24,55 OK (HHHFFF)
|
||||||
|
Size 49: 25,56 BAD (HHHFHH)
|
||||||
|
Size 50: 25,57 OK (HHHFFF)
|
||||||
|
Size 51: 26,59 BAD (HHHFHH)
|
||||||
|
Size 52: 26,60 OK (HHHFFF)
|
||||||
|
Size 53: 27,61 BAD (HHHFHH)
|
||||||
|
Size 54: 27,62 OK (HHHFFF)
|
||||||
|
Size 55: 28,63 BAD (HHHFHH)
|
||||||
|
Size 56: 28,64 OK (HHHFFF)
|
||||||
|
Size 57: 29,65 BAD (HHHFHH)
|
||||||
|
Size 58: 29,67 OK (HHHFFF)
|
||||||
|
Size 59: 30,68 BAD (HHHFHH)
|
||||||
|
Size 60: 30,69 OK (HHHFFF)
|
||||||
|
Size 61: 31,70 BAD (HHHFHH)
|
||||||
|
Size 62: 31,71 OK (HHHFFF)
|
||||||
|
Size 63: 32,72 BAD (HHHFHH)
|
||||||
|
Size 64: 32,74 OK (HHHFFF)
|
||||||
|
Size 65: 33,75 BAD (HHHFHH)
|
||||||
|
Size 66: 33,76 OK (HHHFFF)
|
||||||
|
Size 67: 34,77 BAD (HHHFHH)
|
||||||
|
Size 68: 34,78 OK (HHHFFF)
|
||||||
|
Size 69: 35,79 BAD (HHHFHH)
|
||||||
|
Size 70: 35,80 OK (HHHFFF)
|
||||||
|
Size 71: 36,82 BAD (HHHFHH)
|
||||||
|
Size 72: 36,83 OK (HHHFFF)
|
||||||
|
Size 73: 37,84 BAD (HHHFHH)
|
||||||
|
Size 74: 37,85 OK (HHHFFF)
|
||||||
|
Size 75: 38,86 BAD (HHHFHH)
|
||||||
|
Size 76: 38,87 OK (HHHFFF)
|
||||||
|
Size 77: 39,88 BAD (HHHFHH)
|
||||||
|
Size 78: 39,90 OK (HHHFFF)
|
||||||
|
Size 79: 40,91 BAD (HHHFHH)
|
||||||
|
Size 80: 40,92 OK (HHHFFF)
|
||||||
|
Size 81: 41,93 BAD (HHHFHH)
|
||||||
|
Size 82: 41,94 OK (HHHFFF)
|
||||||
|
Size 83: 42,95 BAD (HHHFHH)
|
||||||
|
Size 84: 42,96 OK (HHHFFF)
|
||||||
|
Size 85: 43,98 BAD (HHHFHH)
|
||||||
|
Size 86: 43,99 OK (HHHFFF)
|
||||||
|
Size 87: 44,100 BAD (HHHFHH)
|
||||||
|
Size 88: 44,101 OK (HHHFFF)
|
||||||
|
Size 89: 45,102 BAD (HHHFHH)
|
||||||
|
Size 90: 45,103 OK (HHHFFF)
|
||||||
|
Size 91: 46,105 BAD (HHHFHH)
|
||||||
|
Size 92: 46,106 OK (HHHFFF)
|
||||||
|
Size 93: 47,107 BAD (HHHFHH)
|
||||||
|
Size 94: 47,108 OK (HHHFFF)
|
||||||
|
Size 95: 48,109 BAD (HHHFHH)
|
||||||
|
Size 96: 48,110 OK (HHHFFF)
|
||||||
|
Size 97: 49,111 BAD (HHHFHH)
|
||||||
|
Size 98: 49,113 OK (HHHFFF)
|
||||||
|
Size 99: 50,114 BAD (HHHFHH)
|
||||||
|
Size 100: 50,115 OK (HHHFFF)
|
||||||
|
|
||||||
|
Windows 7
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,5 OK (HHHFFF)
|
||||||
|
Size 5: 3,6 BAD (FFFFHH)
|
||||||
|
Size 6: 3,7 OK (HHHFFF)
|
||||||
|
Size 7: 4,8 BAD (FFFFHH)
|
||||||
|
Size 8: 4,9 OK (HHHFFF)
|
||||||
|
Size 9: 5,10 BAD (FFFFHH)
|
||||||
|
Size 10: 5,11 OK (HHHFFF)
|
||||||
|
Size 11: 6,13 BAD (FFFFHH)
|
||||||
|
Size 12: 6,14 OK (HHHFFF)
|
||||||
|
Size 13: 7,15 BAD (FFFFHH)
|
||||||
|
Size 14: 7,16 OK (HHHFFF)
|
||||||
|
Size 15: 8,17 BAD (FFFFHH)
|
||||||
|
Size 16: 8,18 OK (HHHFFF)
|
||||||
|
Size 17: 9,20 BAD (FFFFHH)
|
||||||
|
Size 18: 9,21 OK (HHHFFF)
|
||||||
|
Size 19: 10,22 BAD (FFFFHH)
|
||||||
|
Size 20: 10,23 OK (HHHFFF)
|
||||||
|
Size 21: 11,24 BAD (FFFFHH)
|
||||||
|
Size 22: 11,25 OK (HHHFFF)
|
||||||
|
Size 23: 12,26 BAD (FFFFHH)
|
||||||
|
Size 24: 12,28 OK (HHHFFF)
|
||||||
|
Size 25: 13,29 BAD (FFFFHH)
|
||||||
|
Size 26: 13,30 OK (HHHFFF)
|
||||||
|
Size 27: 14,31 BAD (FFFFHH)
|
||||||
|
Size 28: 14,32 OK (HHHFFF)
|
||||||
|
Size 29: 15,33 BAD (FFFFHH)
|
||||||
|
Size 30: 15,34 OK (HHHFFF)
|
||||||
|
Size 31: 16,36 BAD (FFFFHH)
|
||||||
|
Size 32: 16,37 OK (HHHFFF)
|
||||||
|
Size 33: 17,38 BAD (FFFFHH)
|
||||||
|
Size 34: 17,39 OK (HHHFFF)
|
||||||
|
Size 35: 18,40 BAD (FFFFHH)
|
||||||
|
Size 36: 18,41 OK (HHHFFF)
|
||||||
|
Size 37: 19,42 BAD (FFFFHH)
|
||||||
|
Size 38: 19,44 OK (HHHFFF)
|
||||||
|
Size 39: 20,45 BAD (FFFFHH)
|
||||||
|
Size 40: 20,46 OK (HHHFFF)
|
||||||
|
Size 41: 21,47 BAD (FFFFHH)
|
||||||
|
Size 42: 21,48 OK (HHHFFF)
|
||||||
|
Size 43: 22,49 BAD (FFFFHH)
|
||||||
|
Size 44: 22,51 OK (HHHFFF)
|
||||||
|
Size 45: 23,52 BAD (FFFFHH)
|
||||||
|
Size 46: 23,53 OK (HHHFFF)
|
||||||
|
Size 47: 24,54 BAD (FFFFHH)
|
||||||
|
Size 48: 24,55 OK (HHHFFF)
|
||||||
|
Size 49: 25,56 BAD (FFFFHH)
|
||||||
|
Size 50: 25,57 OK (HHHFFF)
|
||||||
|
Size 51: 26,59 BAD (FFFFHH)
|
||||||
|
Size 52: 26,60 OK (HHHFFF)
|
||||||
|
Size 53: 27,61 BAD (FFFFHH)
|
||||||
|
Size 54: 27,62 OK (HHHFFF)
|
||||||
|
Size 55: 28,63 BAD (FFFFHH)
|
||||||
|
Size 56: 28,64 OK (HHHFFF)
|
||||||
|
Size 57: 29,65 BAD (FFFFHH)
|
||||||
|
Size 58: 29,67 OK (HHHFFF)
|
||||||
|
Size 59: 30,68 BAD (FFFFHH)
|
||||||
|
Size 60: 30,69 OK (HHHFFF)
|
||||||
|
Size 61: 31,70 BAD (FFFFHH)
|
||||||
|
Size 62: 31,71 OK (HHHFFF)
|
||||||
|
Size 63: 32,72 BAD (FFFFHH)
|
||||||
|
Size 64: 32,74 OK (HHHFFF)
|
||||||
|
Size 65: 33,75 BAD (FFFFHH)
|
||||||
|
Size 66: 33,76 OK (HHHFFF)
|
||||||
|
Size 67: 34,77 BAD (FFFFHH)
|
||||||
|
Size 68: 34,78 OK (HHHFFF)
|
||||||
|
Size 69: 35,79 BAD (FFFFHH)
|
||||||
|
Size 70: 35,80 OK (HHHFFF)
|
||||||
|
Size 71: 36,82 BAD (FFFFHH)
|
||||||
|
Size 72: 36,83 OK (HHHFFF)
|
||||||
|
Size 73: 37,84 BAD (FFFFHH)
|
||||||
|
Size 74: 37,85 OK (HHHFFF)
|
||||||
|
Size 75: 38,86 BAD (FFFFHH)
|
||||||
|
Size 76: 38,87 OK (HHHFFF)
|
||||||
|
Size 77: 39,88 BAD (FFFFHH)
|
||||||
|
Size 78: 39,90 OK (HHHFFF)
|
||||||
|
Size 79: 40,91 BAD (FFFFHH)
|
||||||
|
Size 80: 40,92 OK (HHHFFF)
|
||||||
|
Size 81: 41,93 BAD (FFFFHH)
|
||||||
|
Size 82: 41,94 OK (HHHFFF)
|
||||||
|
Size 83: 42,95 BAD (FFFFHH)
|
||||||
|
Size 84: 42,96 OK (HHHFFF)
|
||||||
|
Size 85: 43,98 BAD (FFFFHH)
|
||||||
|
Size 86: 43,99 OK (HHHFFF)
|
||||||
|
Size 87: 44,100 BAD (FFFFHH)
|
||||||
|
Size 88: 44,101 OK (HHHFFF)
|
||||||
|
Size 89: 45,102 BAD (FFFFHH)
|
||||||
|
Size 90: 45,103 OK (HHHFFF)
|
||||||
|
Size 91: 46,105 BAD (FFFFHH)
|
||||||
|
Size 92: 46,106 OK (HHHFFF)
|
||||||
|
Size 93: 47,107 BAD (FFFFHH)
|
||||||
|
Size 94: 47,108 OK (HHHFFF)
|
||||||
|
Size 95: 48,109 BAD (FFFFHH)
|
||||||
|
Size 96: 48,110 OK (HHHFFF)
|
||||||
|
Size 97: 49,111 BAD (FFFFHH)
|
||||||
|
Size 98: 49,113 OK (HHHFFF)
|
||||||
|
Size 99: 50,114 BAD (FFFFHH)
|
||||||
|
Size 100: 50,115 OK (HHHFFF)
|
||||||
|
|
||||||
|
Windows 8
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,5 OK (HHHFFF)
|
||||||
|
Size 5: 3,6 BAD (FFFFHH)
|
||||||
|
Size 6: 3,7 OK (HHHFFF)
|
||||||
|
Size 7: 4,8 BAD (FFFFHH)
|
||||||
|
Size 8: 4,9 OK (HHHFFF)
|
||||||
|
Size 9: 5,10 BAD (FFFFHH)
|
||||||
|
Size 10: 5,11 OK (HHHFFF)
|
||||||
|
Size 11: 6,13 BAD (FFFFHH)
|
||||||
|
Size 12: 6,14 OK (HHHFFF)
|
||||||
|
Size 13: 7,15 BAD (FFFFHH)
|
||||||
|
Size 14: 7,16 OK (HHHFFF)
|
||||||
|
Size 15: 8,17 BAD (FFFFHH)
|
||||||
|
Size 16: 8,18 OK (HHHFFF)
|
||||||
|
Size 17: 9,20 BAD (FFFFHH)
|
||||||
|
Size 18: 9,21 OK (HHHFFF)
|
||||||
|
Size 19: 10,22 BAD (FFFFHH)
|
||||||
|
Size 20: 10,23 OK (HHHFFF)
|
||||||
|
Size 21: 11,24 BAD (FFFFHH)
|
||||||
|
Size 22: 11,25 OK (HHHFFF)
|
||||||
|
Size 23: 12,26 BAD (FFFFHH)
|
||||||
|
Size 24: 12,28 OK (HHHFFF)
|
||||||
|
Size 25: 13,29 BAD (FFFFHH)
|
||||||
|
Size 26: 13,30 OK (HHHFFF)
|
||||||
|
Size 27: 14,31 BAD (FFFFHH)
|
||||||
|
Size 28: 14,32 OK (HHHFFF)
|
||||||
|
Size 29: 15,33 BAD (FFFFHH)
|
||||||
|
Size 30: 15,34 OK (HHHFFF)
|
||||||
|
Size 31: 16,36 BAD (FFFFHH)
|
||||||
|
Size 32: 16,37 OK (HHHFFF)
|
||||||
|
Size 33: 17,38 BAD (FFFFHH)
|
||||||
|
Size 34: 17,39 OK (HHHFFF)
|
||||||
|
Size 35: 18,40 BAD (FFFFHH)
|
||||||
|
Size 36: 18,41 OK (HHHFFF)
|
||||||
|
Size 37: 19,42 BAD (FFFFHH)
|
||||||
|
Size 38: 19,44 OK (HHHFFF)
|
||||||
|
Size 39: 20,45 BAD (FFFFHH)
|
||||||
|
Size 40: 20,46 OK (HHHFFF)
|
||||||
|
Size 41: 21,47 BAD (FFFFHH)
|
||||||
|
Size 42: 21,48 OK (HHHFFF)
|
||||||
|
Size 43: 22,49 BAD (FFFFHH)
|
||||||
|
Size 44: 22,51 OK (HHHFFF)
|
||||||
|
Size 45: 23,52 BAD (FFFFHH)
|
||||||
|
Size 46: 23,53 OK (HHHFFF)
|
||||||
|
Size 47: 24,54 BAD (FFFFHH)
|
||||||
|
Size 48: 24,55 OK (HHHFFF)
|
||||||
|
Size 49: 25,56 BAD (FFFFHH)
|
||||||
|
Size 50: 25,57 OK (HHHFFF)
|
||||||
|
Size 51: 26,59 BAD (FFFFHH)
|
||||||
|
Size 52: 26,60 OK (HHHFFF)
|
||||||
|
Size 53: 27,61 BAD (FFFFHH)
|
||||||
|
Size 54: 27,62 OK (HHHFFF)
|
||||||
|
Size 55: 28,63 BAD (FFFFHH)
|
||||||
|
Size 56: 28,64 OK (HHHFFF)
|
||||||
|
Size 57: 29,65 BAD (FFFFHH)
|
||||||
|
Size 58: 29,67 OK (HHHFFF)
|
||||||
|
Size 59: 30,68 BAD (FFFFHH)
|
||||||
|
Size 60: 30,69 OK (HHHFFF)
|
||||||
|
Size 61: 31,70 BAD (FFFFHH)
|
||||||
|
Size 62: 31,71 OK (HHHFFF)
|
||||||
|
Size 63: 32,72 BAD (FFFFHH)
|
||||||
|
Size 64: 32,74 OK (HHHFFF)
|
||||||
|
Size 65: 33,75 BAD (FFFFHH)
|
||||||
|
Size 66: 33,76 OK (HHHFFF)
|
||||||
|
Size 67: 34,77 BAD (FFFFHH)
|
||||||
|
Size 68: 34,78 OK (HHHFFF)
|
||||||
|
Size 69: 35,79 BAD (FFFFHH)
|
||||||
|
Size 70: 35,80 OK (HHHFFF)
|
||||||
|
Size 71: 36,82 BAD (FFFFHH)
|
||||||
|
Size 72: 36,83 OK (HHHFFF)
|
||||||
|
Size 73: 37,84 BAD (FFFFHH)
|
||||||
|
Size 74: 37,85 OK (HHHFFF)
|
||||||
|
Size 75: 38,86 BAD (FFFFHH)
|
||||||
|
Size 76: 38,87 OK (HHHFFF)
|
||||||
|
Size 77: 39,88 BAD (FFFFHH)
|
||||||
|
Size 78: 39,90 OK (HHHFFF)
|
||||||
|
Size 79: 40,91 BAD (FFFFHH)
|
||||||
|
Size 80: 40,92 OK (HHHFFF)
|
||||||
|
Size 81: 41,93 BAD (FFFFHH)
|
||||||
|
Size 82: 41,94 OK (HHHFFF)
|
||||||
|
Size 83: 42,95 BAD (FFFFHH)
|
||||||
|
Size 84: 42,96 OK (HHHFFF)
|
||||||
|
Size 85: 43,98 BAD (FFFFHH)
|
||||||
|
Size 86: 43,99 OK (HHHFFF)
|
||||||
|
Size 87: 44,100 BAD (FFFFHH)
|
||||||
|
Size 88: 44,101 OK (HHHFFF)
|
||||||
|
Size 89: 45,102 BAD (FFFFHH)
|
||||||
|
Size 90: 45,103 OK (HHHFFF)
|
||||||
|
Size 91: 46,105 BAD (FFFFHH)
|
||||||
|
Size 92: 46,106 OK (HHHFFF)
|
||||||
|
Size 93: 47,107 BAD (FFFFHH)
|
||||||
|
Size 94: 47,108 OK (HHHFFF)
|
||||||
|
Size 95: 48,109 BAD (FFFFHH)
|
||||||
|
Size 96: 48,110 OK (HHHFFF)
|
||||||
|
Size 97: 49,111 BAD (FFFFHH)
|
||||||
|
Size 98: 49,113 OK (HHHFFF)
|
||||||
|
Size 99: 50,114 BAD (FFFFHH)
|
||||||
|
Size 100: 50,115 OK (HHHFFF)
|
||||||
|
|
||||||
|
Windows 8.1
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,5 OK (HHHFFF)
|
||||||
|
Size 5: 3,6 BAD (FFFFHH)
|
||||||
|
Size 6: 3,7 OK (HHHFFF)
|
||||||
|
Size 7: 4,8 BAD (FFFFHH)
|
||||||
|
Size 8: 4,9 OK (HHHFFF)
|
||||||
|
Size 9: 5,10 BAD (FFFFHH)
|
||||||
|
Size 10: 5,11 OK (HHHFFF)
|
||||||
|
Size 11: 6,13 BAD (FFFFHH)
|
||||||
|
Size 12: 6,14 OK (HHHFFF)
|
||||||
|
Size 13: 7,15 BAD (FFFFHH)
|
||||||
|
Size 14: 7,16 OK (HHHFFF)
|
||||||
|
Size 15: 8,17 BAD (FFFFHH)
|
||||||
|
Size 16: 8,18 OK (HHHFFF)
|
||||||
|
Size 17: 9,20 BAD (FFFFHH)
|
||||||
|
Size 18: 9,21 OK (HHHFFF)
|
||||||
|
Size 19: 10,22 BAD (FFFFHH)
|
||||||
|
Size 20: 10,23 OK (HHHFFF)
|
||||||
|
Size 21: 11,24 BAD (FFFFHH)
|
||||||
|
Size 22: 11,25 OK (HHHFFF)
|
||||||
|
Size 23: 12,26 BAD (FFFFHH)
|
||||||
|
Size 24: 12,28 OK (HHHFFF)
|
||||||
|
Size 25: 13,29 BAD (FFFFHH)
|
||||||
|
Size 26: 13,30 OK (HHHFFF)
|
||||||
|
Size 27: 14,31 BAD (FFFFHH)
|
||||||
|
Size 28: 14,32 OK (HHHFFF)
|
||||||
|
Size 29: 15,33 BAD (FFFFHH)
|
||||||
|
Size 30: 15,34 OK (HHHFFF)
|
||||||
|
Size 31: 16,36 BAD (FFFFHH)
|
||||||
|
Size 32: 16,37 OK (HHHFFF)
|
||||||
|
Size 33: 17,38 BAD (FFFFHH)
|
||||||
|
Size 34: 17,39 OK (HHHFFF)
|
||||||
|
Size 35: 18,40 BAD (FFFFHH)
|
||||||
|
Size 36: 18,41 OK (HHHFFF)
|
||||||
|
Size 37: 19,42 BAD (FFFFHH)
|
||||||
|
Size 38: 19,44 OK (HHHFFF)
|
||||||
|
Size 39: 20,45 BAD (FFFFHH)
|
||||||
|
Size 40: 20,46 OK (HHHFFF)
|
||||||
|
Size 41: 21,47 BAD (FFFFHH)
|
||||||
|
Size 42: 21,48 OK (HHHFFF)
|
||||||
|
Size 43: 22,49 BAD (FFFFHH)
|
||||||
|
Size 44: 22,51 OK (HHHFFF)
|
||||||
|
Size 45: 23,52 BAD (FFFFHH)
|
||||||
|
Size 46: 23,53 OK (HHHFFF)
|
||||||
|
Size 47: 24,54 BAD (FFFFHH)
|
||||||
|
Size 48: 24,55 OK (HHHFFF)
|
||||||
|
Size 49: 25,56 BAD (FFFFHH)
|
||||||
|
Size 50: 25,57 OK (HHHFFF)
|
||||||
|
Size 51: 26,59 BAD (FFFFHH)
|
||||||
|
Size 52: 26,60 OK (HHHFFF)
|
||||||
|
Size 53: 27,61 BAD (FFFFHH)
|
||||||
|
Size 54: 27,62 OK (HHHFFF)
|
||||||
|
Size 55: 28,63 BAD (FFFFHH)
|
||||||
|
Size 56: 28,64 OK (HHHFFF)
|
||||||
|
Size 57: 29,65 BAD (FFFFHH)
|
||||||
|
Size 58: 29,67 OK (HHHFFF)
|
||||||
|
Size 59: 30,68 BAD (FFFFHH)
|
||||||
|
Size 60: 30,69 OK (HHHFFF)
|
||||||
|
Size 61: 31,70 BAD (FFFFHH)
|
||||||
|
Size 62: 31,71 OK (HHHFFF)
|
||||||
|
Size 63: 32,72 BAD (FFFFHH)
|
||||||
|
Size 64: 32,74 OK (HHHFFF)
|
||||||
|
Size 65: 33,75 BAD (FFFFHH)
|
||||||
|
Size 66: 33,76 OK (HHHFFF)
|
||||||
|
Size 67: 34,77 BAD (FFFFHH)
|
||||||
|
Size 68: 34,78 OK (HHHFFF)
|
||||||
|
Size 69: 35,79 BAD (FFFFHH)
|
||||||
|
Size 70: 35,80 OK (HHHFFF)
|
||||||
|
Size 71: 36,82 BAD (FFFFHH)
|
||||||
|
Size 72: 36,83 OK (HHHFFF)
|
||||||
|
Size 73: 37,84 BAD (FFFFHH)
|
||||||
|
Size 74: 37,85 OK (HHHFFF)
|
||||||
|
Size 75: 38,86 BAD (FFFFHH)
|
||||||
|
Size 76: 38,87 OK (HHHFFF)
|
||||||
|
Size 77: 39,88 BAD (FFFFHH)
|
||||||
|
Size 78: 39,90 OK (HHHFFF)
|
||||||
|
Size 79: 40,91 BAD (FFFFHH)
|
||||||
|
Size 80: 40,92 OK (HHHFFF)
|
||||||
|
Size 81: 41,93 BAD (FFFFHH)
|
||||||
|
Size 82: 41,94 OK (HHHFFF)
|
||||||
|
Size 83: 42,95 BAD (FFFFHH)
|
||||||
|
Size 84: 42,96 OK (HHHFFF)
|
||||||
|
Size 85: 43,98 BAD (FFFFHH)
|
||||||
|
Size 86: 43,99 OK (HHHFFF)
|
||||||
|
Size 87: 44,100 BAD (FFFFHH)
|
||||||
|
Size 88: 44,101 OK (HHHFFF)
|
||||||
|
Size 89: 45,102 BAD (FFFFHH)
|
||||||
|
Size 90: 45,103 OK (HHHFFF)
|
||||||
|
Size 91: 46,105 BAD (FFFFHH)
|
||||||
|
Size 92: 46,106 OK (HHHFFF)
|
||||||
|
Size 93: 47,107 BAD (FFFFHH)
|
||||||
|
Size 94: 47,108 OK (HHHFFF)
|
||||||
|
Size 95: 48,109 BAD (FFFFHH)
|
||||||
|
Size 96: 48,110 OK (HHHFFF)
|
||||||
|
Size 97: 49,111 BAD (FFFFHH)
|
||||||
|
Size 98: 49,113 OK (HHHFFF)
|
||||||
|
Size 99: 50,114 BAD (FFFFHH)
|
||||||
|
Size 100: 50,115 OK (HHHFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 Old Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,2 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 BAD (FFFFHH)
|
||||||
|
Size 4: 2,5 OK (HHHFFF)
|
||||||
|
Size 5: 3,6 BAD (FFFFHH)
|
||||||
|
Size 6: 3,7 OK (HHHFFF)
|
||||||
|
Size 7: 4,8 BAD (FFFFHH)
|
||||||
|
Size 8: 4,9 OK (HHHFFF)
|
||||||
|
Size 9: 5,10 BAD (FFFFHH)
|
||||||
|
Size 10: 5,11 OK (HHHFFF)
|
||||||
|
Size 11: 6,13 BAD (FFFFHH)
|
||||||
|
Size 12: 6,14 OK (HHHFFF)
|
||||||
|
Size 13: 7,15 BAD (FFFFHH)
|
||||||
|
Size 14: 7,16 OK (HHHFFF)
|
||||||
|
Size 15: 8,17 BAD (FFFFHH)
|
||||||
|
Size 16: 8,18 OK (HHHFFF)
|
||||||
|
Size 17: 9,20 BAD (FFFFHH)
|
||||||
|
Size 18: 9,21 OK (HHHFFF)
|
||||||
|
Size 19: 10,22 BAD (FFFFHH)
|
||||||
|
Size 20: 10,23 OK (HHHFFF)
|
||||||
|
Size 21: 11,24 BAD (FFFFHH)
|
||||||
|
Size 22: 11,25 OK (HHHFFF)
|
||||||
|
Size 23: 12,26 BAD (FFFFHH)
|
||||||
|
Size 24: 12,28 OK (HHHFFF)
|
||||||
|
Size 25: 13,29 BAD (FFFFHH)
|
||||||
|
Size 26: 13,30 OK (HHHFFF)
|
||||||
|
Size 27: 14,31 BAD (FFFFHH)
|
||||||
|
Size 28: 14,32 OK (HHHFFF)
|
||||||
|
Size 29: 15,33 BAD (FFFFHH)
|
||||||
|
Size 30: 15,34 OK (HHHFFF)
|
||||||
|
Size 31: 16,36 BAD (FFFFHH)
|
||||||
|
Size 32: 16,37 OK (HHHFFF)
|
||||||
|
Size 33: 17,38 BAD (FFFFHH)
|
||||||
|
Size 34: 17,39 OK (HHHFFF)
|
||||||
|
Size 35: 18,40 BAD (FFFFHH)
|
||||||
|
Size 36: 18,41 OK (HHHFFF)
|
||||||
|
Size 37: 19,42 BAD (FFFFHH)
|
||||||
|
Size 38: 19,44 OK (HHHFFF)
|
||||||
|
Size 39: 20,45 BAD (FFFFHH)
|
||||||
|
Size 40: 20,46 OK (HHHFFF)
|
||||||
|
Size 41: 21,47 BAD (FFFFHH)
|
||||||
|
Size 42: 21,48 OK (HHHFFF)
|
||||||
|
Size 43: 22,49 BAD (FFFFHH)
|
||||||
|
Size 44: 22,51 OK (HHHFFF)
|
||||||
|
Size 45: 23,52 BAD (FFFFHH)
|
||||||
|
Size 46: 23,53 OK (HHHFFF)
|
||||||
|
Size 47: 24,54 BAD (FFFFHH)
|
||||||
|
Size 48: 24,55 OK (HHHFFF)
|
||||||
|
Size 49: 25,56 BAD (FFFFHH)
|
||||||
|
Size 50: 25,57 OK (HHHFFF)
|
||||||
|
Size 51: 26,59 BAD (FFFFHH)
|
||||||
|
Size 52: 26,60 OK (HHHFFF)
|
||||||
|
Size 53: 27,61 BAD (FFFFHH)
|
||||||
|
Size 54: 27,62 OK (HHHFFF)
|
||||||
|
Size 55: 28,63 BAD (FFFFHH)
|
||||||
|
Size 56: 28,64 OK (HHHFFF)
|
||||||
|
Size 57: 29,65 BAD (FFFFHH)
|
||||||
|
Size 58: 29,67 OK (HHHFFF)
|
||||||
|
Size 59: 30,68 BAD (FFFFHH)
|
||||||
|
Size 60: 30,69 OK (HHHFFF)
|
||||||
|
Size 61: 31,70 BAD (FFFFHH)
|
||||||
|
Size 62: 31,71 OK (HHHFFF)
|
||||||
|
Size 63: 32,72 BAD (FFFFHH)
|
||||||
|
Size 64: 32,74 OK (HHHFFF)
|
||||||
|
Size 65: 33,75 BAD (FFFFHH)
|
||||||
|
Size 66: 33,76 OK (HHHFFF)
|
||||||
|
Size 67: 34,77 BAD (FFFFHH)
|
||||||
|
Size 68: 34,78 OK (HHHFFF)
|
||||||
|
Size 69: 35,79 BAD (FFFFHH)
|
||||||
|
Size 70: 35,80 OK (HHHFFF)
|
||||||
|
Size 71: 36,82 BAD (FFFFHH)
|
||||||
|
Size 72: 36,83 OK (HHHFFF)
|
||||||
|
Size 73: 37,84 BAD (FFFFHH)
|
||||||
|
Size 74: 37,85 OK (HHHFFF)
|
||||||
|
Size 75: 38,86 BAD (FFFFHH)
|
||||||
|
Size 76: 38,87 OK (HHHFFF)
|
||||||
|
Size 77: 39,88 BAD (FFFFHH)
|
||||||
|
Size 78: 39,90 OK (HHHFFF)
|
||||||
|
Size 79: 40,91 BAD (FFFFHH)
|
||||||
|
Size 80: 40,92 OK (HHHFFF)
|
||||||
|
Size 81: 41,93 BAD (FFFFHH)
|
||||||
|
Size 82: 41,94 OK (HHHFFF)
|
||||||
|
Size 83: 42,95 BAD (FFFFHH)
|
||||||
|
Size 84: 42,96 OK (HHHFFF)
|
||||||
|
Size 85: 43,98 BAD (FFFFHH)
|
||||||
|
Size 86: 43,99 OK (HHHFFF)
|
||||||
|
Size 87: 44,100 BAD (FFFFHH)
|
||||||
|
Size 88: 44,101 OK (HHHFFF)
|
||||||
|
Size 89: 45,102 BAD (FFFFHH)
|
||||||
|
Size 90: 45,103 OK (HHHFFF)
|
||||||
|
Size 91: 46,105 BAD (FFFFHH)
|
||||||
|
Size 92: 46,106 OK (HHHFFF)
|
||||||
|
Size 93: 47,107 BAD (FFFFHH)
|
||||||
|
Size 94: 47,108 OK (HHHFFF)
|
||||||
|
Size 95: 48,109 BAD (FFFFHH)
|
||||||
|
Size 96: 48,110 OK (HHHFFF)
|
||||||
|
Size 97: 49,111 BAD (FFFFHH)
|
||||||
|
Size 98: 49,113 OK (HHHFFF)
|
||||||
|
Size 99: 50,114 BAD (FFFFHH)
|
||||||
|
Size 100: 50,115 OK (HHHFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 New Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,1 OK (HHHFFF)
|
||||||
|
Size 2: 1,2 OK (HHHFFF)
|
||||||
|
Size 3: 2,3 OK (HHHFFF)
|
||||||
|
Size 4: 2,4 OK (HHHFFF)
|
||||||
|
Size 5: 3,5 OK (HHHFFF)
|
||||||
|
Size 6: 3,6 OK (HHHFFF)
|
||||||
|
Size 7: 4,7 OK (HHHFFF)
|
||||||
|
Size 8: 4,8 OK (HHHFFF)
|
||||||
|
Size 9: 5,9 OK (HHHFFF)
|
||||||
|
Size 10: 5,10 OK (HHHFFF)
|
||||||
|
Size 11: 6,11 OK (HHHFFF)
|
||||||
|
Size 12: 6,12 OK (HHHFFF)
|
||||||
|
Size 13: 7,13 OK (HHHFFF)
|
||||||
|
Size 14: 7,14 OK (HHHFFF)
|
||||||
|
Size 15: 8,15 OK (HHHFFF)
|
||||||
|
Size 16: 8,16 OK (HHHFFF)
|
||||||
|
Size 17: 9,17 OK (HHHFFF)
|
||||||
|
Size 18: 9,18 OK (HHHFFF)
|
||||||
|
Size 19: 10,19 OK (HHHFFF)
|
||||||
|
Size 20: 10,20 OK (HHHFFF)
|
||||||
|
Size 21: 11,21 OK (HHHFFF)
|
||||||
|
Size 22: 11,22 OK (HHHFFF)
|
||||||
|
Size 23: 12,23 OK (HHHFFF)
|
||||||
|
Size 24: 12,24 OK (HHHFFF)
|
||||||
|
Size 25: 13,25 OK (HHHFFF)
|
||||||
|
Size 26: 13,26 OK (HHHFFF)
|
||||||
|
Size 27: 14,27 OK (HHHFFF)
|
||||||
|
Size 28: 14,28 OK (HHHFFF)
|
||||||
|
Size 29: 15,29 OK (HHHFFF)
|
||||||
|
Size 30: 15,30 OK (HHHFFF)
|
||||||
|
Size 31: 16,31 OK (HHHFFF)
|
||||||
|
Size 32: 16,32 OK (HHHFFF)
|
||||||
|
Size 33: 17,33 OK (HHHFFF)
|
||||||
|
Size 34: 17,34 OK (HHHFFF)
|
||||||
|
Size 35: 18,35 OK (HHHFFF)
|
||||||
|
Size 36: 18,36 OK (HHHFFF)
|
||||||
|
Size 37: 19,37 OK (HHHFFF)
|
||||||
|
Size 38: 19,38 OK (HHHFFF)
|
||||||
|
Size 39: 20,39 OK (HHHFFF)
|
||||||
|
Size 40: 20,40 OK (HHHFFF)
|
||||||
|
Size 41: 21,41 OK (HHHFFF)
|
||||||
|
Size 42: 21,42 OK (HHHFFF)
|
||||||
|
Size 43: 22,43 OK (HHHFFF)
|
||||||
|
Size 44: 22,44 OK (HHHFFF)
|
||||||
|
Size 45: 23,45 OK (HHHFFF)
|
||||||
|
Size 46: 23,46 OK (HHHFFF)
|
||||||
|
Size 47: 24,47 OK (HHHFFF)
|
||||||
|
Size 48: 24,48 OK (HHHFFF)
|
||||||
|
Size 49: 25,49 OK (HHHFFF)
|
||||||
|
Size 50: 25,50 OK (HHHFFF)
|
||||||
|
Size 51: 26,51 OK (HHHFFF)
|
||||||
|
Size 52: 26,52 OK (HHHFFF)
|
||||||
|
Size 53: 27,53 OK (HHHFFF)
|
||||||
|
Size 54: 27,54 OK (HHHFFF)
|
||||||
|
Size 55: 28,55 OK (HHHFFF)
|
||||||
|
Size 56: 28,56 OK (HHHFFF)
|
||||||
|
Size 57: 29,57 OK (HHHFFF)
|
||||||
|
Size 58: 29,58 OK (HHHFFF)
|
||||||
|
Size 59: 30,59 OK (HHHFFF)
|
||||||
|
Size 60: 30,60 OK (HHHFFF)
|
||||||
|
Size 61: 31,61 OK (HHHFFF)
|
||||||
|
Size 62: 31,62 OK (HHHFFF)
|
||||||
|
Size 63: 32,63 OK (HHHFFF)
|
||||||
|
Size 64: 32,64 OK (HHHFFF)
|
||||||
|
Size 65: 33,65 OK (HHHFFF)
|
||||||
|
Size 66: 33,66 OK (HHHFFF)
|
||||||
|
Size 67: 34,67 OK (HHHFFF)
|
||||||
|
Size 68: 34,68 OK (HHHFFF)
|
||||||
|
Size 69: 35,69 OK (HHHFFF)
|
||||||
|
Size 70: 35,70 OK (HHHFFF)
|
||||||
|
Size 71: 36,71 OK (HHHFFF)
|
||||||
|
Size 72: 36,72 OK (HHHFFF)
|
||||||
|
Size 73: 37,73 OK (HHHFFF)
|
||||||
|
Size 74: 37,74 OK (HHHFFF)
|
||||||
|
Size 75: 38,75 OK (HHHFFF)
|
||||||
|
Size 76: 38,76 OK (HHHFFF)
|
||||||
|
Size 77: 39,77 OK (HHHFFF)
|
||||||
|
Size 78: 39,78 OK (HHHFFF)
|
||||||
|
Size 79: 40,79 OK (HHHFFF)
|
||||||
|
Size 80: 40,80 OK (HHHFFF)
|
||||||
|
Size 81: 41,81 OK (HHHFFF)
|
||||||
|
Size 82: 41,82 OK (HHHFFF)
|
||||||
|
Size 83: 42,83 OK (HHHFFF)
|
||||||
|
Size 84: 42,84 OK (HHHFFF)
|
||||||
|
Size 85: 43,85 OK (HHHFFF)
|
||||||
|
Size 86: 43,86 OK (HHHFFF)
|
||||||
|
Size 87: 44,87 OK (HHHFFF)
|
||||||
|
Size 88: 44,88 OK (HHHFFF)
|
||||||
|
Size 89: 45,89 OK (HHHFFF)
|
||||||
|
Size 90: 45,90 OK (HHHFFF)
|
||||||
|
Size 91: 46,91 OK (HHHFFF)
|
||||||
|
Size 92: 46,92 OK (HHHFFF)
|
||||||
|
Size 93: 47,93 OK (HHHFFF)
|
||||||
|
Size 94: 47,94 OK (HHHFFF)
|
||||||
|
Size 95: 48,95 OK (HHHFFF)
|
||||||
|
Size 96: 48,96 OK (HHHFFF)
|
||||||
|
Size 97: 49,97 OK (HHHFFF)
|
||||||
|
Size 98: 49,98 OK (HHHFFF)
|
||||||
|
Size 99: 50,99 OK (HHHFFF)
|
||||||
|
Size 100: 50,100 OK (HHHFFF)
|
||||||
Generated
Vendored
+630
@@ -0,0 +1,630 @@
|
|||||||
|
===========================================================
|
||||||
|
Code Page 950, Chinese Traditional (Taiwan), MingLight font
|
||||||
|
===========================================================
|
||||||
|
|
||||||
|
Options: -face-minglight -family 0x36
|
||||||
|
Chars: A2 A3 2014 3044 30FC 4000
|
||||||
|
|
||||||
|
Vista
|
||||||
|
-----
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,4 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (HHHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (HHHFHH)
|
||||||
|
Size 8: 4,10 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,11 BAD (HHHFHH)
|
||||||
|
Size 10: 5,12 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (HHHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,16 BAD (HHHFHH)
|
||||||
|
Size 14: 7,17 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,18 BAD (HHHFHH)
|
||||||
|
Size 16: 8,19 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,20 BAD (HHHFHH)
|
||||||
|
Size 18: 9,22 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,23 BAD (HHHFHH)
|
||||||
|
Size 20: 10,24 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,25 BAD (HHHFHH)
|
||||||
|
Size 22: 11,26 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,28 BAD (HHHFHH)
|
||||||
|
Size 24: 12,29 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,30 BAD (HHHFHH)
|
||||||
|
Size 26: 13,31 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,32 BAD (HHHFHH)
|
||||||
|
Size 28: 14,34 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,35 BAD (HHHFHH)
|
||||||
|
Size 30: 15,36 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,37 BAD (HHHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,40 BAD (HHHFHH)
|
||||||
|
Size 34: 17,41 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,42 BAD (HHHFHH)
|
||||||
|
Size 36: 18,43 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,44 BAD (HHHFHH)
|
||||||
|
Size 38: 19,46 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,47 BAD (HHHFHH)
|
||||||
|
Size 40: 20,48 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,49 BAD (HHHFHH)
|
||||||
|
Size 42: 21,50 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,52 BAD (HHHFHH)
|
||||||
|
Size 44: 22,53 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,54 BAD (HHHFHH)
|
||||||
|
Size 46: 23,55 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,56 BAD (HHHFHH)
|
||||||
|
Size 48: 24,58 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,59 BAD (HHHFHH)
|
||||||
|
Size 50: 25,60 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,61 BAD (HHHFHH)
|
||||||
|
Size 52: 26,62 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,64 BAD (HHHFHH)
|
||||||
|
Size 54: 27,65 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,66 BAD (HHHFHH)
|
||||||
|
Size 56: 28,67 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,68 BAD (HHHFHH)
|
||||||
|
Size 58: 29,70 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,71 BAD (HHHFHH)
|
||||||
|
Size 60: 30,72 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,73 BAD (HHHFHH)
|
||||||
|
Size 62: 31,74 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,76 BAD (HHHFHH)
|
||||||
|
Size 64: 32,77 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,78 BAD (HHHFHH)
|
||||||
|
Size 66: 33,79 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,80 BAD (HHHFHH)
|
||||||
|
Size 68: 34,82 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,83 BAD (HHHFHH)
|
||||||
|
Size 70: 35,84 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,85 BAD (HHHFHH)
|
||||||
|
Size 72: 36,86 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,88 BAD (HHHFHH)
|
||||||
|
Size 74: 37,89 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,90 BAD (HHHFHH)
|
||||||
|
Size 76: 38,91 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,92 BAD (HHHFHH)
|
||||||
|
Size 78: 39,94 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,95 BAD (HHHFHH)
|
||||||
|
Size 80: 40,96 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,97 BAD (HHHFHH)
|
||||||
|
Size 82: 41,98 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,100 BAD (HHHFHH)
|
||||||
|
Size 84: 42,101 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,102 BAD (HHHFHH)
|
||||||
|
Size 86: 43,103 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,104 BAD (HHHFHH)
|
||||||
|
Size 88: 44,106 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,107 BAD (HHHFHH)
|
||||||
|
Size 90: 45,108 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,109 BAD (HHHFHH)
|
||||||
|
Size 92: 46,110 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,112 BAD (HHHFHH)
|
||||||
|
Size 94: 47,113 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,114 BAD (HHHFHH)
|
||||||
|
Size 96: 48,115 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,116 BAD (HHHFHH)
|
||||||
|
Size 98: 49,118 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,119 BAD (HHHFHH)
|
||||||
|
Size 100: 50,120 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 7
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,4 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,10 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,11 BAD (FFHFHH)
|
||||||
|
Size 10: 5,12 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,16 BAD (FFHFHH)
|
||||||
|
Size 14: 7,17 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,18 BAD (FFHFHH)
|
||||||
|
Size 16: 8,19 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,20 BAD (FFHFHH)
|
||||||
|
Size 18: 9,22 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,23 BAD (FFHFHH)
|
||||||
|
Size 20: 10,24 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,25 BAD (FFHFHH)
|
||||||
|
Size 22: 11,26 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,28 BAD (FFHFHH)
|
||||||
|
Size 24: 12,29 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,30 BAD (FFHFHH)
|
||||||
|
Size 26: 13,31 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,32 BAD (FFHFHH)
|
||||||
|
Size 28: 14,34 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,35 BAD (FFHFHH)
|
||||||
|
Size 30: 15,36 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,37 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,40 BAD (FFHFHH)
|
||||||
|
Size 34: 17,41 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,42 BAD (FFHFHH)
|
||||||
|
Size 36: 18,43 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,44 BAD (FFHFHH)
|
||||||
|
Size 38: 19,46 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,47 BAD (FFHFHH)
|
||||||
|
Size 40: 20,48 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,49 BAD (FFHFHH)
|
||||||
|
Size 42: 21,50 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,52 BAD (FFHFHH)
|
||||||
|
Size 44: 22,53 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,54 BAD (FFHFHH)
|
||||||
|
Size 46: 23,55 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,56 BAD (FFHFHH)
|
||||||
|
Size 48: 24,58 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,59 BAD (FFHFHH)
|
||||||
|
Size 50: 25,60 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,61 BAD (FFHFHH)
|
||||||
|
Size 52: 26,62 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,64 BAD (FFHFHH)
|
||||||
|
Size 54: 27,65 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,66 BAD (FFHFHH)
|
||||||
|
Size 56: 28,67 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,68 BAD (FFHFHH)
|
||||||
|
Size 58: 29,70 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,71 BAD (FFHFHH)
|
||||||
|
Size 60: 30,72 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,73 BAD (FFHFHH)
|
||||||
|
Size 62: 31,74 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,76 BAD (FFHFHH)
|
||||||
|
Size 64: 32,77 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,78 BAD (FFHFHH)
|
||||||
|
Size 66: 33,79 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,80 BAD (FFHFHH)
|
||||||
|
Size 68: 34,82 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,83 BAD (FFHFHH)
|
||||||
|
Size 70: 35,84 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,85 BAD (FFHFHH)
|
||||||
|
Size 72: 36,86 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,88 BAD (FFHFHH)
|
||||||
|
Size 74: 37,89 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,90 BAD (FFHFHH)
|
||||||
|
Size 76: 38,91 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,92 BAD (FFHFHH)
|
||||||
|
Size 78: 39,94 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,95 BAD (FFHFHH)
|
||||||
|
Size 80: 40,96 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,97 BAD (FFHFHH)
|
||||||
|
Size 82: 41,98 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,100 BAD (FFHFHH)
|
||||||
|
Size 84: 42,101 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,102 BAD (FFHFHH)
|
||||||
|
Size 86: 43,103 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,104 BAD (FFHFHH)
|
||||||
|
Size 88: 44,106 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,107 BAD (FFHFHH)
|
||||||
|
Size 90: 45,108 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,109 BAD (FFHFHH)
|
||||||
|
Size 92: 46,110 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,112 BAD (FFHFHH)
|
||||||
|
Size 94: 47,113 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,114 BAD (FFHFHH)
|
||||||
|
Size 96: 48,115 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,116 BAD (FFHFHH)
|
||||||
|
Size 98: 49,118 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,119 BAD (FFHFHH)
|
||||||
|
Size 100: 50,120 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 8
|
||||||
|
---------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,4 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,10 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,11 BAD (FFHFHH)
|
||||||
|
Size 10: 5,12 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,16 BAD (FFHFHH)
|
||||||
|
Size 14: 7,17 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,18 BAD (FFHFHH)
|
||||||
|
Size 16: 8,19 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,20 BAD (FFHFHH)
|
||||||
|
Size 18: 9,22 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,23 BAD (FFHFHH)
|
||||||
|
Size 20: 10,24 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,25 BAD (FFHFHH)
|
||||||
|
Size 22: 11,26 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,28 BAD (FFHFHH)
|
||||||
|
Size 24: 12,29 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,30 BAD (FFHFHH)
|
||||||
|
Size 26: 13,31 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,32 BAD (FFHFHH)
|
||||||
|
Size 28: 14,34 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,35 BAD (FFHFHH)
|
||||||
|
Size 30: 15,36 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,37 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,40 BAD (FFHFHH)
|
||||||
|
Size 34: 17,41 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,42 BAD (FFHFHH)
|
||||||
|
Size 36: 18,43 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,44 BAD (FFHFHH)
|
||||||
|
Size 38: 19,46 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,47 BAD (FFHFHH)
|
||||||
|
Size 40: 20,48 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,49 BAD (FFHFHH)
|
||||||
|
Size 42: 21,50 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,52 BAD (FFHFHH)
|
||||||
|
Size 44: 22,53 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,54 BAD (FFHFHH)
|
||||||
|
Size 46: 23,55 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,56 BAD (FFHFHH)
|
||||||
|
Size 48: 24,58 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,59 BAD (FFHFHH)
|
||||||
|
Size 50: 25,60 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,61 BAD (FFHFHH)
|
||||||
|
Size 52: 26,62 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,64 BAD (FFHFHH)
|
||||||
|
Size 54: 27,65 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,66 BAD (FFHFHH)
|
||||||
|
Size 56: 28,67 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,68 BAD (FFHFHH)
|
||||||
|
Size 58: 29,70 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,71 BAD (FFHFHH)
|
||||||
|
Size 60: 30,72 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,73 BAD (FFHFHH)
|
||||||
|
Size 62: 31,74 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,76 BAD (FFHFHH)
|
||||||
|
Size 64: 32,77 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,78 BAD (FFHFHH)
|
||||||
|
Size 66: 33,79 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,80 BAD (FFHFHH)
|
||||||
|
Size 68: 34,82 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,83 BAD (FFHFHH)
|
||||||
|
Size 70: 35,84 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,85 BAD (FFHFHH)
|
||||||
|
Size 72: 36,86 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,88 BAD (FFHFHH)
|
||||||
|
Size 74: 37,89 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,90 BAD (FFHFHH)
|
||||||
|
Size 76: 38,91 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,92 BAD (FFHFHH)
|
||||||
|
Size 78: 39,94 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,95 BAD (FFHFHH)
|
||||||
|
Size 80: 40,96 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,97 BAD (FFHFHH)
|
||||||
|
Size 82: 41,98 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,100 BAD (FFHFHH)
|
||||||
|
Size 84: 42,101 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,102 BAD (FFHFHH)
|
||||||
|
Size 86: 43,103 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,104 BAD (FFHFHH)
|
||||||
|
Size 88: 44,106 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,107 BAD (FFHFHH)
|
||||||
|
Size 90: 45,108 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,109 BAD (FFHFHH)
|
||||||
|
Size 92: 46,110 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,112 BAD (FFHFHH)
|
||||||
|
Size 94: 47,113 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,114 BAD (FFHFHH)
|
||||||
|
Size 96: 48,115 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,116 BAD (FFHFHH)
|
||||||
|
Size 98: 49,118 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,119 BAD (FFHFHH)
|
||||||
|
Size 100: 50,120 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 8.1
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,4 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,10 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,11 BAD (FFHFHH)
|
||||||
|
Size 10: 5,12 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,16 BAD (FFHFHH)
|
||||||
|
Size 14: 7,17 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,18 BAD (FFHFHH)
|
||||||
|
Size 16: 8,19 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,20 BAD (FFHFHH)
|
||||||
|
Size 18: 9,22 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,23 BAD (FFHFHH)
|
||||||
|
Size 20: 10,24 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,25 BAD (FFHFHH)
|
||||||
|
Size 22: 11,26 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,28 BAD (FFHFHH)
|
||||||
|
Size 24: 12,29 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,30 BAD (FFHFHH)
|
||||||
|
Size 26: 13,31 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,32 BAD (FFHFHH)
|
||||||
|
Size 28: 14,34 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,35 BAD (FFHFHH)
|
||||||
|
Size 30: 15,36 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,37 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,40 BAD (FFHFHH)
|
||||||
|
Size 34: 17,41 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,42 BAD (FFHFHH)
|
||||||
|
Size 36: 18,43 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,44 BAD (FFHFHH)
|
||||||
|
Size 38: 19,46 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,47 BAD (FFHFHH)
|
||||||
|
Size 40: 20,48 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,49 BAD (FFHFHH)
|
||||||
|
Size 42: 21,50 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,52 BAD (FFHFHH)
|
||||||
|
Size 44: 22,53 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,54 BAD (FFHFHH)
|
||||||
|
Size 46: 23,55 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,56 BAD (FFHFHH)
|
||||||
|
Size 48: 24,58 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,59 BAD (FFHFHH)
|
||||||
|
Size 50: 25,60 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,61 BAD (FFHFHH)
|
||||||
|
Size 52: 26,62 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,64 BAD (FFHFHH)
|
||||||
|
Size 54: 27,65 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,66 BAD (FFHFHH)
|
||||||
|
Size 56: 28,67 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,68 BAD (FFHFHH)
|
||||||
|
Size 58: 29,70 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,71 BAD (FFHFHH)
|
||||||
|
Size 60: 30,72 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,73 BAD (FFHFHH)
|
||||||
|
Size 62: 31,74 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,76 BAD (FFHFHH)
|
||||||
|
Size 64: 32,77 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,78 BAD (FFHFHH)
|
||||||
|
Size 66: 33,79 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,80 BAD (FFHFHH)
|
||||||
|
Size 68: 34,82 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,83 BAD (FFHFHH)
|
||||||
|
Size 70: 35,84 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,85 BAD (FFHFHH)
|
||||||
|
Size 72: 36,86 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,88 BAD (FFHFHH)
|
||||||
|
Size 74: 37,89 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,90 BAD (FFHFHH)
|
||||||
|
Size 76: 38,91 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,92 BAD (FFHFHH)
|
||||||
|
Size 78: 39,94 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,95 BAD (FFHFHH)
|
||||||
|
Size 80: 40,96 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,97 BAD (FFHFHH)
|
||||||
|
Size 82: 41,98 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,100 BAD (FFHFHH)
|
||||||
|
Size 84: 42,101 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,102 BAD (FFHFHH)
|
||||||
|
Size 86: 43,103 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,104 BAD (FFHFHH)
|
||||||
|
Size 88: 44,106 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,107 BAD (FFHFHH)
|
||||||
|
Size 90: 45,108 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,109 BAD (FFHFHH)
|
||||||
|
Size 92: 46,110 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,112 BAD (FFHFHH)
|
||||||
|
Size 94: 47,113 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,114 BAD (FFHFHH)
|
||||||
|
Size 96: 48,115 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,116 BAD (FFHFHH)
|
||||||
|
Size 98: 49,118 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,119 BAD (FFHFHH)
|
||||||
|
Size 100: 50,120 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 Old Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,4 BAD (FFHFHH)
|
||||||
|
Size 4: 2,5 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,6 BAD (FFHFHH)
|
||||||
|
Size 6: 3,7 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,8 BAD (FFHFHH)
|
||||||
|
Size 8: 4,10 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,11 BAD (FFHFHH)
|
||||||
|
Size 10: 5,12 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,13 BAD (FFHFHH)
|
||||||
|
Size 12: 6,14 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,16 BAD (FFHFHH)
|
||||||
|
Size 14: 7,17 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,18 BAD (FFHFHH)
|
||||||
|
Size 16: 8,19 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,20 BAD (FFHFHH)
|
||||||
|
Size 18: 9,22 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,23 BAD (FFHFHH)
|
||||||
|
Size 20: 10,24 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,25 BAD (FFHFHH)
|
||||||
|
Size 22: 11,26 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,28 BAD (FFHFHH)
|
||||||
|
Size 24: 12,29 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,30 BAD (FFHFHH)
|
||||||
|
Size 26: 13,31 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,32 BAD (FFHFHH)
|
||||||
|
Size 28: 14,34 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,35 BAD (FFHFHH)
|
||||||
|
Size 30: 15,36 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,37 BAD (FFHFHH)
|
||||||
|
Size 32: 16,38 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,40 BAD (FFHFHH)
|
||||||
|
Size 34: 17,41 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,42 BAD (FFHFHH)
|
||||||
|
Size 36: 18,43 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,44 BAD (FFHFHH)
|
||||||
|
Size 38: 19,46 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,47 BAD (FFHFHH)
|
||||||
|
Size 40: 20,48 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,49 BAD (FFHFHH)
|
||||||
|
Size 42: 21,50 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,52 BAD (FFHFHH)
|
||||||
|
Size 44: 22,53 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,54 BAD (FFHFHH)
|
||||||
|
Size 46: 23,55 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,56 BAD (FFHFHH)
|
||||||
|
Size 48: 24,58 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,59 BAD (FFHFHH)
|
||||||
|
Size 50: 25,60 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,61 BAD (FFHFHH)
|
||||||
|
Size 52: 26,62 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,64 BAD (FFHFHH)
|
||||||
|
Size 54: 27,65 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,66 BAD (FFHFHH)
|
||||||
|
Size 56: 28,67 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,68 BAD (FFHFHH)
|
||||||
|
Size 58: 29,70 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,71 BAD (FFHFHH)
|
||||||
|
Size 60: 30,72 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,73 BAD (FFHFHH)
|
||||||
|
Size 62: 31,74 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,76 BAD (FFHFHH)
|
||||||
|
Size 64: 32,77 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,78 BAD (FFHFHH)
|
||||||
|
Size 66: 33,79 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,80 BAD (FFHFHH)
|
||||||
|
Size 68: 34,82 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,83 BAD (FFHFHH)
|
||||||
|
Size 70: 35,84 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,85 BAD (FFHFHH)
|
||||||
|
Size 72: 36,86 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,88 BAD (FFHFHH)
|
||||||
|
Size 74: 37,89 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,90 BAD (FFHFHH)
|
||||||
|
Size 76: 38,91 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,92 BAD (FFHFHH)
|
||||||
|
Size 78: 39,94 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,95 BAD (FFHFHH)
|
||||||
|
Size 80: 40,96 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,97 BAD (FFHFHH)
|
||||||
|
Size 82: 41,98 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,100 BAD (FFHFHH)
|
||||||
|
Size 84: 42,101 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,102 BAD (FFHFHH)
|
||||||
|
Size 86: 43,103 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,104 BAD (FFHFHH)
|
||||||
|
Size 88: 44,106 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,107 BAD (FFHFHH)
|
||||||
|
Size 90: 45,108 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,109 BAD (FFHFHH)
|
||||||
|
Size 92: 46,110 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,112 BAD (FFHFHH)
|
||||||
|
Size 94: 47,113 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,114 BAD (FFHFHH)
|
||||||
|
Size 96: 48,115 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,116 BAD (FFHFHH)
|
||||||
|
Size 98: 49,118 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,119 BAD (FFHFHH)
|
||||||
|
Size 100: 50,120 GOOD (HHFFFF)
|
||||||
|
|
||||||
|
Windows 10 14342 New Console
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Size 1: 1,1 GOOD (HHFFFF)
|
||||||
|
Size 2: 1,2 GOOD (HHFFFF)
|
||||||
|
Size 3: 2,3 GOOD (HHFFFF)
|
||||||
|
Size 4: 2,4 GOOD (HHFFFF)
|
||||||
|
Size 5: 3,5 GOOD (HHFFFF)
|
||||||
|
Size 6: 3,6 GOOD (HHFFFF)
|
||||||
|
Size 7: 4,7 GOOD (HHFFFF)
|
||||||
|
Size 8: 4,8 GOOD (HHFFFF)
|
||||||
|
Size 9: 5,9 GOOD (HHFFFF)
|
||||||
|
Size 10: 5,10 GOOD (HHFFFF)
|
||||||
|
Size 11: 6,11 GOOD (HHFFFF)
|
||||||
|
Size 12: 6,12 GOOD (HHFFFF)
|
||||||
|
Size 13: 7,13 GOOD (HHFFFF)
|
||||||
|
Size 14: 7,14 GOOD (HHFFFF)
|
||||||
|
Size 15: 8,15 GOOD (HHFFFF)
|
||||||
|
Size 16: 8,16 GOOD (HHFFFF)
|
||||||
|
Size 17: 9,17 GOOD (HHFFFF)
|
||||||
|
Size 18: 9,18 GOOD (HHFFFF)
|
||||||
|
Size 19: 10,19 GOOD (HHFFFF)
|
||||||
|
Size 20: 10,20 GOOD (HHFFFF)
|
||||||
|
Size 21: 11,21 GOOD (HHFFFF)
|
||||||
|
Size 22: 11,22 GOOD (HHFFFF)
|
||||||
|
Size 23: 12,23 GOOD (HHFFFF)
|
||||||
|
Size 24: 12,24 GOOD (HHFFFF)
|
||||||
|
Size 25: 13,25 GOOD (HHFFFF)
|
||||||
|
Size 26: 13,26 GOOD (HHFFFF)
|
||||||
|
Size 27: 14,27 GOOD (HHFFFF)
|
||||||
|
Size 28: 14,28 GOOD (HHFFFF)
|
||||||
|
Size 29: 15,29 GOOD (HHFFFF)
|
||||||
|
Size 30: 15,30 GOOD (HHFFFF)
|
||||||
|
Size 31: 16,31 GOOD (HHFFFF)
|
||||||
|
Size 32: 16,32 GOOD (HHFFFF)
|
||||||
|
Size 33: 17,33 GOOD (HHFFFF)
|
||||||
|
Size 34: 17,34 GOOD (HHFFFF)
|
||||||
|
Size 35: 18,35 GOOD (HHFFFF)
|
||||||
|
Size 36: 18,36 GOOD (HHFFFF)
|
||||||
|
Size 37: 19,37 GOOD (HHFFFF)
|
||||||
|
Size 38: 19,38 GOOD (HHFFFF)
|
||||||
|
Size 39: 20,39 GOOD (HHFFFF)
|
||||||
|
Size 40: 20,40 GOOD (HHFFFF)
|
||||||
|
Size 41: 21,41 GOOD (HHFFFF)
|
||||||
|
Size 42: 21,42 GOOD (HHFFFF)
|
||||||
|
Size 43: 22,43 GOOD (HHFFFF)
|
||||||
|
Size 44: 22,44 GOOD (HHFFFF)
|
||||||
|
Size 45: 23,45 GOOD (HHFFFF)
|
||||||
|
Size 46: 23,46 GOOD (HHFFFF)
|
||||||
|
Size 47: 24,47 GOOD (HHFFFF)
|
||||||
|
Size 48: 24,48 GOOD (HHFFFF)
|
||||||
|
Size 49: 25,49 GOOD (HHFFFF)
|
||||||
|
Size 50: 25,50 GOOD (HHFFFF)
|
||||||
|
Size 51: 26,51 GOOD (HHFFFF)
|
||||||
|
Size 52: 26,52 GOOD (HHFFFF)
|
||||||
|
Size 53: 27,53 GOOD (HHFFFF)
|
||||||
|
Size 54: 27,54 GOOD (HHFFFF)
|
||||||
|
Size 55: 28,55 GOOD (HHFFFF)
|
||||||
|
Size 56: 28,56 GOOD (HHFFFF)
|
||||||
|
Size 57: 29,57 GOOD (HHFFFF)
|
||||||
|
Size 58: 29,58 GOOD (HHFFFF)
|
||||||
|
Size 59: 30,59 GOOD (HHFFFF)
|
||||||
|
Size 60: 30,60 GOOD (HHFFFF)
|
||||||
|
Size 61: 31,61 GOOD (HHFFFF)
|
||||||
|
Size 62: 31,62 GOOD (HHFFFF)
|
||||||
|
Size 63: 32,63 GOOD (HHFFFF)
|
||||||
|
Size 64: 32,64 GOOD (HHFFFF)
|
||||||
|
Size 65: 33,65 GOOD (HHFFFF)
|
||||||
|
Size 66: 33,66 GOOD (HHFFFF)
|
||||||
|
Size 67: 34,67 GOOD (HHFFFF)
|
||||||
|
Size 68: 34,68 GOOD (HHFFFF)
|
||||||
|
Size 69: 35,69 GOOD (HHFFFF)
|
||||||
|
Size 70: 35,70 GOOD (HHFFFF)
|
||||||
|
Size 71: 36,71 GOOD (HHFFFF)
|
||||||
|
Size 72: 36,72 GOOD (HHFFFF)
|
||||||
|
Size 73: 37,73 GOOD (HHFFFF)
|
||||||
|
Size 74: 37,74 GOOD (HHFFFF)
|
||||||
|
Size 75: 38,75 GOOD (HHFFFF)
|
||||||
|
Size 76: 38,76 GOOD (HHFFFF)
|
||||||
|
Size 77: 39,77 GOOD (HHFFFF)
|
||||||
|
Size 78: 39,78 GOOD (HHFFFF)
|
||||||
|
Size 79: 40,79 GOOD (HHFFFF)
|
||||||
|
Size 80: 40,80 GOOD (HHFFFF)
|
||||||
|
Size 81: 41,81 GOOD (HHFFFF)
|
||||||
|
Size 82: 41,82 GOOD (HHFFFF)
|
||||||
|
Size 83: 42,83 GOOD (HHFFFF)
|
||||||
|
Size 84: 42,84 GOOD (HHFFFF)
|
||||||
|
Size 85: 43,85 GOOD (HHFFFF)
|
||||||
|
Size 86: 43,86 GOOD (HHFFFF)
|
||||||
|
Size 87: 44,87 GOOD (HHFFFF)
|
||||||
|
Size 88: 44,88 GOOD (HHFFFF)
|
||||||
|
Size 89: 45,89 GOOD (HHFFFF)
|
||||||
|
Size 90: 45,90 GOOD (HHFFFF)
|
||||||
|
Size 91: 46,91 GOOD (HHFFFF)
|
||||||
|
Size 92: 46,92 GOOD (HHFFFF)
|
||||||
|
Size 93: 47,93 GOOD (HHFFFF)
|
||||||
|
Size 94: 47,94 GOOD (HHFFFF)
|
||||||
|
Size 95: 48,95 GOOD (HHFFFF)
|
||||||
|
Size 96: 48,96 GOOD (HHFFFF)
|
||||||
|
Size 97: 49,97 GOOD (HHFFFF)
|
||||||
|
Size 98: 49,98 GOOD (HHFFFF)
|
||||||
|
Size 99: 50,99 GOOD (HHFFFF)
|
||||||
|
Size 100: 50,100 GOOD (HHFFFF)
|
||||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
The narrowest allowed console window, in pixels, on a conventional (~96dpi)
|
||||||
|
monitor:
|
||||||
|
|
||||||
|
(mode con: cols=40 lines=40) && SetFont.exe -face "Lucida Console" -h 1 && (ping -n 4 127.0.0.1 > NUL) && cls && GetConsolePos.exe && SetFont.exe -face "Lucida Console" -h 12
|
||||||
|
|
||||||
|
(mode con: cols=40 lines=40) && SetFont.exe -face "Lucida Console" -h 16 && (ping -n 4 127.0.0.1 > NUL) && cls && GetConsolePos.exe && SetFont.exe -face "Lucida Console" -h 12
|
||||||
|
|
||||||
|
sz1:px sz1:col sz16:px sz16:col
|
||||||
|
Vista: 124 104 137 10
|
||||||
|
Windows 7: 132 112 147 11
|
||||||
|
Windows 8: 140 120 147 11
|
||||||
|
Windows 8.1: 140 120 147 11
|
||||||
|
Windows 10 OLD: 136 116 147 11
|
||||||
|
Windows 10 NEW: 136 103 136 10
|
||||||
|
|
||||||
|
I used build 14342 to test Windows 10.
|
||||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
As before, avoid odd sizes in favor of even sizes.
|
||||||
|
|
||||||
|
It's curious that the Japanese font is handled so poorly, especially with
|
||||||
|
Windows 8 and later.
|
||||||
Generated
Vendored
+144
@@ -0,0 +1,144 @@
|
|||||||
|
Issues:
|
||||||
|
|
||||||
|
- Starting with the 14342 build, changing the font using
|
||||||
|
SetCurrentConsoleFontEx does not affect the window size. e.g. The content
|
||||||
|
itself will resize/redraw, but the window neither shrinks nor expands.
|
||||||
|
Presumably this is an oversight? It's almost a convenience; if a program
|
||||||
|
is going to resize the window anyway, then it's nice that the window size
|
||||||
|
contraints don't get in the way. Ordinarily, changing the font doesn't just
|
||||||
|
change the window size in pixels--it can also change the size as measured in
|
||||||
|
rows and columns.
|
||||||
|
|
||||||
|
- (Aside: in the 14342 build, there is also a bug with wmic.exe. Open a console
|
||||||
|
with more than 300 lines of screen buffer, then fill those lines with, e.g.,
|
||||||
|
dir /s. Then run wmic.exe. You won't be able to see the wmic.exe prompt.
|
||||||
|
If you query the screen buffer info somehow, you'll notice that the srWindow
|
||||||
|
is not contained within the dwSize. This breaks winpty's scraping, because
|
||||||
|
it's invalid.)
|
||||||
|
|
||||||
|
- In build 14316, with the Japanese locale, with the 437 code page, attempting
|
||||||
|
to set the Consolas font instead sets the Terminal (raster) font. It seems
|
||||||
|
to pick an appropriate vertical size.
|
||||||
|
|
||||||
|
- It seems necessary to specify "-family 0x36" for maximum reliability.
|
||||||
|
Setting the family to 0 almost always works, and specifying just -tt rarely
|
||||||
|
works.
|
||||||
|
|
||||||
|
Win7
|
||||||
|
English locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 932 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt unreliable
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
|
||||||
|
Win10 Build 10586
|
||||||
|
New console
|
||||||
|
Japanese locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
|
||||||
|
Win10 Build 14316
|
||||||
|
Old console
|
||||||
|
English locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 932 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selected very small Consolas font
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
New console
|
||||||
|
English locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt works
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 932 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 selects gothic instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects gothic instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 selects gothic instead
|
||||||
|
Japanese locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36(*) selects Terminal font instead
|
||||||
|
|
||||||
|
Win10 Build 14342
|
||||||
|
Old Console
|
||||||
|
English locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 932 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
New console
|
||||||
|
English locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 works
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt works
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
Japanese locale / 932 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 selects gothic instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt selects gothic instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 selects gothic instead
|
||||||
|
Japanese locale / 437 code page:
|
||||||
|
SetFont.exe -face Consolas -h 16 selects Terminal font instead
|
||||||
|
SetFont.exe -face Consolas -h 16 -tt works
|
||||||
|
SetFont.exe -face Consolas -h 16 -family 0x36 works
|
||||||
|
|
||||||
|
(*) I was trying to figure out whether the inconsistency was at when I stumbled
|
||||||
|
onto this completely unexpected bug. Here's more detail:
|
||||||
|
|
||||||
|
F:\>SetFont.exe -face Consolas -h 16 -family 0x36 -weight normal -w 8
|
||||||
|
Setting to: nFont=0 dwFontSize=(8,16) FontFamily=0x36 FontWeight=400 FaceName="Consolas"
|
||||||
|
SetCurrentConsoleFontEx returned 1
|
||||||
|
|
||||||
|
F:\>GetFont.exe
|
||||||
|
largestConsoleWindowSize=(96,50)
|
||||||
|
maxWnd=0: nFont=0 dwFontSize=(12,16) FontFamily=0x30 FontWeight=400 FaceName=Terminal (54 65 72 6D 69 6E 61 6C)
|
||||||
|
maxWnd=1: nFont=0 dwFontSize=(96,25) FontFamily=0x30 FontWeight=400 FaceName=Terminal (54 65 72 6D 69 6E 61 6C)
|
||||||
|
00-00: 12x16
|
||||||
|
GetNumberOfConsoleFonts returned 0
|
||||||
|
CP=437 OutputCP=437
|
||||||
|
|
||||||
|
F:\>SetFont.exe -face "Lucida Console" -h 16 -family 0x36 -weight normal
|
||||||
|
Setting to: nFont=0 dwFontSize=(0,16) FontFamily=0x36 FontWeight=400 FaceName="Lucida Console"
|
||||||
|
SetCurrentConsoleFontEx returned 1
|
||||||
|
|
||||||
|
F:\>GetFont.exe
|
||||||
|
largestConsoleWindowSize=(96,50)
|
||||||
|
maxWnd=0: nFont=0 dwFontSize=(12,16) FontFamily=0x30 FontWeight=400 FaceName=Terminal (54 65 72 6D 69 6E 61 6C)
|
||||||
|
maxWnd=1: nFont=0 dwFontSize=(96,25) FontFamily=0x30 FontWeight=400 FaceName=Terminal (54 65 72 6D 69 6E 61 6C)
|
||||||
|
00-00: 12x16
|
||||||
|
GetNumberOfConsoleFonts returned 0
|
||||||
|
CP=437 OutputCP=437
|
||||||
|
|
||||||
|
F:\>SetFont.exe -face "Lucida Console" -h 12 -family 0x36 -weight normal
|
||||||
|
Setting to: nFont=0 dwFontSize=(0,12) FontFamily=0x36 FontWeight=400 FaceName="Lucida Console"
|
||||||
|
SetCurrentConsoleFontEx returned 1
|
||||||
|
|
||||||
|
F:\>GetFont.exe
|
||||||
|
largestConsoleWindowSize=(230,66)
|
||||||
|
maxWnd=0: nFont=0 dwFontSize=(5,12) FontFamily=0x30 FontWeight=400 FaceName=Terminal (54 65 72 6D 69 6E 61 6C)
|
||||||
|
maxWnd=1: nFont=0 dwFontSize=(116,36) FontFamily=0x30 FontWeight=400 FaceName=Terminal (54 65 72 6D 69 6E 61 6C)
|
||||||
|
00-00: 5x12
|
||||||
|
GetNumberOfConsoleFonts returned 0
|
||||||
|
CP=437 OutputCP=437
|
||||||
|
|
||||||
|
Even attempting to set to a Lucida Console / Consolas font from the Console
|
||||||
|
properties dialog fails.
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
#define COUNT_OF(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
|
||||||
|
// See https://en.wikipedia.org/wiki/List_of_CJK_fonts
|
||||||
|
const wchar_t kMSGothic[] = { 0xff2d, 0xff33, 0x0020, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 }; // Japanese
|
||||||
|
const wchar_t kNSimSun[] = { 0x65b0, 0x5b8b, 0x4f53, 0 }; // Simplified Chinese
|
||||||
|
const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
|
||||||
|
const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
|
||||||
|
|
||||||
|
std::vector<bool> condense(const std::vector<CHAR_INFO> &buf) {
|
||||||
|
std::vector<bool> ret;
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < buf.size()) {
|
||||||
|
if (buf[i].Char.UnicodeChar == L' ' &&
|
||||||
|
((buf[i].Attributes & 0x300) == 0)) {
|
||||||
|
// end of line
|
||||||
|
break;
|
||||||
|
} else if (i + 1 < buf.size() &&
|
||||||
|
((buf[i].Attributes & 0x300) == 0x100) &&
|
||||||
|
((buf[i + 1].Attributes & 0x300) == 0x200) &&
|
||||||
|
buf[i].Char.UnicodeChar != L' ' &&
|
||||||
|
buf[i].Char.UnicodeChar == buf[i + 1].Char.UnicodeChar) {
|
||||||
|
// double-width
|
||||||
|
ret.push_back(true);
|
||||||
|
i += 2;
|
||||||
|
} else if ((buf[i].Attributes & 0x300) == 0) {
|
||||||
|
// single-width
|
||||||
|
ret.push_back(false);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
ASSERT(false && "unexpected output");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s \"arguments for SetFont.exe\"\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *setFontArgs = argv[1];
|
||||||
|
|
||||||
|
const wchar_t testLine[] = { 0xA2, 0xA3, 0x2014, 0x3044, 0x30FC, 0x4000, 0 };
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
|
||||||
|
char setFontCmd[1024];
|
||||||
|
for (int h = 1; h <= 100; ++h) {
|
||||||
|
sprintf(setFontCmd, ".\\SetFont.exe %s -h %d && cls", setFontArgs, h);
|
||||||
|
system(setFontCmd);
|
||||||
|
|
||||||
|
CONSOLE_FONT_INFOEX infoex = {};
|
||||||
|
infoex.cbSize = sizeof(infoex);
|
||||||
|
BOOL success = GetCurrentConsoleFontEx(conout, FALSE, &infoex);
|
||||||
|
ASSERT(success && "GetCurrentConsoleFontEx failed");
|
||||||
|
|
||||||
|
DWORD actual = 0;
|
||||||
|
success = WriteConsoleW(conout, testLine, wcslen(testLine), &actual, nullptr);
|
||||||
|
ASSERT(success && actual == wcslen(testLine));
|
||||||
|
|
||||||
|
std::vector<CHAR_INFO> readBuf(14);
|
||||||
|
const SMALL_RECT readRegion = {0, 0, static_cast<short>(readBuf.size() - 1), 0};
|
||||||
|
SMALL_RECT readRegion2 = readRegion;
|
||||||
|
success = ReadConsoleOutputW(
|
||||||
|
conout, readBuf.data(),
|
||||||
|
{static_cast<short>(readBuf.size()), 1},
|
||||||
|
{0, 0},
|
||||||
|
&readRegion2);
|
||||||
|
ASSERT(success && !memcmp(&readRegion, &readRegion2, sizeof(readRegion)));
|
||||||
|
|
||||||
|
const auto widths = condense(readBuf);
|
||||||
|
std::string widthsStr;
|
||||||
|
for (bool width : widths) {
|
||||||
|
widthsStr.append(width ? "F" : "H");
|
||||||
|
}
|
||||||
|
char size[16];
|
||||||
|
sprintf(size, "%d,%d", infoex.dwFontSize.X, infoex.dwFontSize.Y);
|
||||||
|
const char *status = "";
|
||||||
|
if (widthsStr == "HHFFFF") {
|
||||||
|
status = "GOOD";
|
||||||
|
} else if (widthsStr == "HHHFFF") {
|
||||||
|
status = "OK";
|
||||||
|
} else {
|
||||||
|
status = "BAD";
|
||||||
|
}
|
||||||
|
trace("Size %3d: %-7s %-4s (%s)", h, size, status, widthsStr.c_str());
|
||||||
|
}
|
||||||
|
sprintf(setFontCmd, ".\\SetFont.exe %s -h 14", setFontArgs);
|
||||||
|
system(setFontCmd);
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static inline void formatChar(char *str, char ch)
|
||||||
|
{
|
||||||
|
// Print some common control codes.
|
||||||
|
switch (ch) {
|
||||||
|
case '\r': strcpy(str, "CR "); break;
|
||||||
|
case '\n': strcpy(str, "LF "); break;
|
||||||
|
case ' ': strcpy(str, "SP "); break;
|
||||||
|
case 27: strcpy(str, "^[ "); break;
|
||||||
|
case 3: strcpy(str, "^C "); break;
|
||||||
|
default:
|
||||||
|
if (isgraph(ch))
|
||||||
|
sprintf(str, "%c ", ch);
|
||||||
|
else
|
||||||
|
sprintf(str, "%02x ", ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
const int SC_CONSOLE_SELECT_ALL = 0xFFF5;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[0]) {
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s (mark|selectall|read)\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Test { Mark, SelectAll, Read } test;
|
||||||
|
if (!strcmp(argv[1], "mark")) {
|
||||||
|
test = Test::Mark;
|
||||||
|
} else if (!strcmp(argv[1], "selectall")) {
|
||||||
|
test = Test::SelectAll;
|
||||||
|
} else if (!strcmp(argv[1], "read")) {
|
||||||
|
test = Test::Read;
|
||||||
|
} else {
|
||||||
|
printf("Invalid test: %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
TimeMeasurement tm;
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(100, 3000);
|
||||||
|
system("cls");
|
||||||
|
setWindowPos(0, 2975, 100, 25);
|
||||||
|
setCursorPos(0, 2999);
|
||||||
|
|
||||||
|
ShowWindow(hwnd, SW_HIDE);
|
||||||
|
|
||||||
|
for (int i = 0; i < 1000; ++i) {
|
||||||
|
// CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||||||
|
// GetConsoleScreenBufferInfo(conout, &info);
|
||||||
|
|
||||||
|
if (test == Test::Mark) {
|
||||||
|
SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0);
|
||||||
|
SendMessage(hwnd, WM_CHAR, 27, 0x00010001);
|
||||||
|
} else if (test == Test::SelectAll) {
|
||||||
|
SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_SELECT_ALL, 0);
|
||||||
|
SendMessage(hwnd, WM_CHAR, 27, 0x00010001);
|
||||||
|
} else if (test == Test::Read) {
|
||||||
|
static CHAR_INFO buffer[100 * 3000];
|
||||||
|
const SMALL_RECT readRegion = {0, 0, 99, 2999};
|
||||||
|
SMALL_RECT tmp = readRegion;
|
||||||
|
BOOL ret = ReadConsoleOutput(conout, buffer, {100, 3000}, {0, 0}, &tmp);
|
||||||
|
ASSERT(ret && !memcmp(&tmp, &readRegion, sizeof(tmp)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowWindow(hwnd, SW_SHOW);
|
||||||
|
|
||||||
|
printf("elapsed: %f\n", tm.elapsed());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#include <conio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("\nPress any keys -- Ctrl-D exits\n\n");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const int ch = getch();
|
||||||
|
printf("0x%x", ch);
|
||||||
|
if (isgraph(ch)) {
|
||||||
|
printf(" '%c'", ch);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
if (ch == 0x4) { // Ctrl-D
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||||||
|
BOOL ret = GetConsoleScreenBufferInfo(conout, &info);
|
||||||
|
ASSERT(ret && "GetConsoleScreenBufferInfo failed");
|
||||||
|
|
||||||
|
trace("cursor=%d,%d", info.dwCursorPosition.X, info.dwCursorPosition.Y);
|
||||||
|
printf("cursor=%d,%d\n", info.dwCursorPosition.X, info.dwCursorPosition.Y);
|
||||||
|
|
||||||
|
trace("srWindow={L=%d,T=%d,R=%d,B=%d}", info.srWindow.Left, info.srWindow.Top, info.srWindow.Right, info.srWindow.Bottom);
|
||||||
|
printf("srWindow={L=%d,T=%d,R=%d,B=%d}\n", info.srWindow.Left, info.srWindow.Top, info.srWindow.Right, info.srWindow.Bottom);
|
||||||
|
|
||||||
|
trace("dwSize=%d,%d", info.dwSize.X, info.dwSize.Y);
|
||||||
|
printf("dwSize=%d,%d\n", info.dwSize.X, info.dwSize.Y);
|
||||||
|
|
||||||
|
const HWND hwnd = GetConsoleWindow();
|
||||||
|
if (hwnd != NULL) {
|
||||||
|
RECT r = {};
|
||||||
|
if (GetWindowRect(hwnd, &r)) {
|
||||||
|
const int w = r.right - r.left;
|
||||||
|
const int h = r.bottom - r.top;
|
||||||
|
trace("hwnd: pos=(%d,%d) size=(%d,%d)", r.left, r.top, w, h);
|
||||||
|
printf("hwnd: pos=(%d,%d) size=(%d,%d)\n", r.left, r.top, w, h);
|
||||||
|
} else {
|
||||||
|
trace("GetWindowRect failed");
|
||||||
|
printf("GetWindowRect failed\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
trace("GetConsoleWindow returned NULL");
|
||||||
|
printf("GetConsoleWindow returned NULL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+261
@@ -0,0 +1,261 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include "../src/shared/OsModule.h"
|
||||||
|
#include "../src/shared/StringUtil.h"
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
#include "../src/shared/StringUtil.cc"
|
||||||
|
|
||||||
|
#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
// Some of these types and functions are missing from the MinGW headers.
|
||||||
|
// Others are undocumented.
|
||||||
|
|
||||||
|
struct AGENT_CONSOLE_FONT_INFO {
|
||||||
|
DWORD nFont;
|
||||||
|
COORD dwFontSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AGENT_CONSOLE_FONT_INFOEX {
|
||||||
|
ULONG cbSize;
|
||||||
|
DWORD nFont;
|
||||||
|
COORD dwFontSize;
|
||||||
|
UINT FontFamily;
|
||||||
|
UINT FontWeight;
|
||||||
|
WCHAR FaceName[LF_FACESIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
// undocumented XP API
|
||||||
|
typedef BOOL WINAPI SetConsoleFont_t(
|
||||||
|
HANDLE hOutput,
|
||||||
|
DWORD dwFontIndex);
|
||||||
|
|
||||||
|
// undocumented XP API
|
||||||
|
typedef DWORD WINAPI GetNumberOfConsoleFonts_t();
|
||||||
|
|
||||||
|
// XP and up
|
||||||
|
typedef BOOL WINAPI GetCurrentConsoleFont_t(
|
||||||
|
HANDLE hOutput,
|
||||||
|
BOOL bMaximumWindow,
|
||||||
|
AGENT_CONSOLE_FONT_INFO *lpConsoleCurrentFont);
|
||||||
|
|
||||||
|
// XP and up
|
||||||
|
typedef COORD WINAPI GetConsoleFontSize_t(
|
||||||
|
HANDLE hConsoleOutput,
|
||||||
|
DWORD nFont);
|
||||||
|
|
||||||
|
// Vista and up
|
||||||
|
typedef BOOL WINAPI GetCurrentConsoleFontEx_t(
|
||||||
|
HANDLE hConsoleOutput,
|
||||||
|
BOOL bMaximumWindow,
|
||||||
|
AGENT_CONSOLE_FONT_INFOEX *lpConsoleCurrentFontEx);
|
||||||
|
|
||||||
|
// Vista and up
|
||||||
|
typedef BOOL WINAPI SetCurrentConsoleFontEx_t(
|
||||||
|
HANDLE hConsoleOutput,
|
||||||
|
BOOL bMaximumWindow,
|
||||||
|
AGENT_CONSOLE_FONT_INFOEX *lpConsoleCurrentFontEx);
|
||||||
|
|
||||||
|
#define GET_MODULE_PROC(mod, funcName) \
|
||||||
|
m_##funcName = reinterpret_cast<funcName##_t*>((mod).proc(#funcName)); \
|
||||||
|
|
||||||
|
#define DEFINE_ACCESSOR(funcName) \
|
||||||
|
funcName##_t &funcName() const { \
|
||||||
|
ASSERT(valid()); \
|
||||||
|
return *m_##funcName; \
|
||||||
|
}
|
||||||
|
|
||||||
|
class XPFontAPI {
|
||||||
|
public:
|
||||||
|
XPFontAPI() : m_kernel32(L"kernel32.dll") {
|
||||||
|
GET_MODULE_PROC(m_kernel32, GetCurrentConsoleFont);
|
||||||
|
GET_MODULE_PROC(m_kernel32, GetConsoleFontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() const {
|
||||||
|
return m_GetCurrentConsoleFont != NULL &&
|
||||||
|
m_GetConsoleFontSize != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACCESSOR(GetCurrentConsoleFont)
|
||||||
|
DEFINE_ACCESSOR(GetConsoleFontSize)
|
||||||
|
|
||||||
|
private:
|
||||||
|
OsModule m_kernel32;
|
||||||
|
GetCurrentConsoleFont_t *m_GetCurrentConsoleFont;
|
||||||
|
GetConsoleFontSize_t *m_GetConsoleFontSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UndocumentedXPFontAPI : public XPFontAPI {
|
||||||
|
public:
|
||||||
|
UndocumentedXPFontAPI() : m_kernel32(L"kernel32.dll") {
|
||||||
|
GET_MODULE_PROC(m_kernel32, SetConsoleFont);
|
||||||
|
GET_MODULE_PROC(m_kernel32, GetNumberOfConsoleFonts);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() const {
|
||||||
|
return this->XPFontAPI::valid() &&
|
||||||
|
m_SetConsoleFont != NULL &&
|
||||||
|
m_GetNumberOfConsoleFonts != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACCESSOR(SetConsoleFont)
|
||||||
|
DEFINE_ACCESSOR(GetNumberOfConsoleFonts)
|
||||||
|
|
||||||
|
private:
|
||||||
|
OsModule m_kernel32;
|
||||||
|
SetConsoleFont_t *m_SetConsoleFont;
|
||||||
|
GetNumberOfConsoleFonts_t *m_GetNumberOfConsoleFonts;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VistaFontAPI : public XPFontAPI {
|
||||||
|
public:
|
||||||
|
VistaFontAPI() : m_kernel32(L"kernel32.dll") {
|
||||||
|
GET_MODULE_PROC(m_kernel32, GetCurrentConsoleFontEx);
|
||||||
|
GET_MODULE_PROC(m_kernel32, SetCurrentConsoleFontEx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() const {
|
||||||
|
return this->XPFontAPI::valid() &&
|
||||||
|
m_GetCurrentConsoleFontEx != NULL &&
|
||||||
|
m_SetCurrentConsoleFontEx != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACCESSOR(GetCurrentConsoleFontEx)
|
||||||
|
DEFINE_ACCESSOR(SetCurrentConsoleFontEx)
|
||||||
|
|
||||||
|
private:
|
||||||
|
OsModule m_kernel32;
|
||||||
|
GetCurrentConsoleFontEx_t *m_GetCurrentConsoleFontEx;
|
||||||
|
SetCurrentConsoleFontEx_t *m_SetCurrentConsoleFontEx;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<std::pair<DWORD, COORD> > readFontTable(
|
||||||
|
XPFontAPI &api, HANDLE conout, DWORD maxCount) {
|
||||||
|
std::vector<std::pair<DWORD, COORD> > ret;
|
||||||
|
for (DWORD i = 0; i < maxCount; ++i) {
|
||||||
|
COORD size = api.GetConsoleFontSize()(conout, i);
|
||||||
|
if (size.X == 0 && size.Y == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret.push_back(std::make_pair(i, size));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpFontTable(HANDLE conout) {
|
||||||
|
const int kMaxCount = 1000;
|
||||||
|
XPFontAPI api;
|
||||||
|
if (!api.valid()) {
|
||||||
|
printf("dumpFontTable: cannot dump font table -- missing APIs\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<std::pair<DWORD, COORD> > table =
|
||||||
|
readFontTable(api, conout, kMaxCount);
|
||||||
|
std::string line;
|
||||||
|
char tmp[128];
|
||||||
|
size_t first = 0;
|
||||||
|
while (first < table.size()) {
|
||||||
|
size_t last = std::min(table.size() - 1, first + 10 - 1);
|
||||||
|
winpty_snprintf(tmp, "%02u-%02u:",
|
||||||
|
static_cast<unsigned>(first), static_cast<unsigned>(last));
|
||||||
|
line = tmp;
|
||||||
|
for (size_t i = first; i <= last; ++i) {
|
||||||
|
if (i % 10 == 5) {
|
||||||
|
line += " - ";
|
||||||
|
}
|
||||||
|
winpty_snprintf(tmp, " %2dx%-2d",
|
||||||
|
table[i].second.X, table[i].second.Y);
|
||||||
|
line += tmp;
|
||||||
|
}
|
||||||
|
printf("%s\n", line.c_str());
|
||||||
|
first = last + 1;
|
||||||
|
}
|
||||||
|
if (table.size() == kMaxCount) {
|
||||||
|
printf("... stopped reading at %d fonts ...\n", kMaxCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string stringToCodePoints(const std::wstring &str) {
|
||||||
|
std::string ret = "(";
|
||||||
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
|
char tmp[32];
|
||||||
|
winpty_snprintf(tmp, "%X", str[i]);
|
||||||
|
if (ret.size() > 1) {
|
||||||
|
ret.push_back(' ');
|
||||||
|
}
|
||||||
|
ret += tmp;
|
||||||
|
}
|
||||||
|
ret.push_back(')');
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpFontInfoEx(
|
||||||
|
const AGENT_CONSOLE_FONT_INFOEX &infoex) {
|
||||||
|
std::wstring faceName(infoex.FaceName,
|
||||||
|
winpty_wcsnlen(infoex.FaceName, COUNT_OF(infoex.FaceName)));
|
||||||
|
cprintf(L"nFont=%u dwFontSize=(%d,%d) "
|
||||||
|
"FontFamily=0x%x FontWeight=%u FaceName=%ls %hs\n",
|
||||||
|
static_cast<unsigned>(infoex.nFont),
|
||||||
|
infoex.dwFontSize.X, infoex.dwFontSize.Y,
|
||||||
|
infoex.FontFamily, infoex.FontWeight, faceName.c_str(),
|
||||||
|
stringToCodePoints(faceName).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpVistaFont(VistaFontAPI &api, HANDLE conout, BOOL maxWindow) {
|
||||||
|
AGENT_CONSOLE_FONT_INFOEX infoex = {0};
|
||||||
|
infoex.cbSize = sizeof(infoex);
|
||||||
|
if (!api.GetCurrentConsoleFontEx()(conout, maxWindow, &infoex)) {
|
||||||
|
printf("GetCurrentConsoleFontEx call failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dumpFontInfoEx(infoex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpXPFont(XPFontAPI &api, HANDLE conout, BOOL maxWindow) {
|
||||||
|
AGENT_CONSOLE_FONT_INFO info = {0};
|
||||||
|
if (!api.GetCurrentConsoleFont()(conout, maxWindow, &info)) {
|
||||||
|
printf("GetCurrentConsoleFont call failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("nFont=%u dwFontSize=(%d,%d)\n",
|
||||||
|
static_cast<unsigned>(info.nFont),
|
||||||
|
info.dwFontSize.X, info.dwFontSize.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpFontAndTable(HANDLE conout) {
|
||||||
|
VistaFontAPI vista;
|
||||||
|
if (vista.valid()) {
|
||||||
|
printf("maxWnd=0: "); dumpVistaFont(vista, conout, FALSE);
|
||||||
|
printf("maxWnd=1: "); dumpVistaFont(vista, conout, TRUE);
|
||||||
|
dumpFontTable(conout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UndocumentedXPFontAPI xp;
|
||||||
|
if (xp.valid()) {
|
||||||
|
printf("maxWnd=0: "); dumpXPFont(xp, conout, FALSE);
|
||||||
|
printf("maxWnd=1: "); dumpXPFont(xp, conout, TRUE);
|
||||||
|
dumpFontTable(conout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("setSmallFont: neither Vista nor XP APIs detected -- giving up\n");
|
||||||
|
dumpFontTable(conout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
const COORD largest = GetLargestConsoleWindowSize(conout);
|
||||||
|
printf("largestConsoleWindowSize=(%d,%d)\n", largest.X, largest.Y);
|
||||||
|
dumpFontAndTable(conout);
|
||||||
|
UndocumentedXPFontAPI xp;
|
||||||
|
if (xp.valid()) {
|
||||||
|
printf("GetNumberOfConsoleFonts returned %u\n", xp.GetNumberOfConsoleFonts()());
|
||||||
|
} else {
|
||||||
|
printf("The GetNumberOfConsoleFonts API was missing\n");
|
||||||
|
}
|
||||||
|
printf("CP=%u OutputCP=%u\n", GetConsoleCP(), GetConsoleOutputCP());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Generated
Vendored
+51
@@ -0,0 +1,51 @@
|
|||||||
|
#
|
||||||
|
# Usage: powershell <path>\IdentifyConsoleWindow.ps1
|
||||||
|
#
|
||||||
|
# This script determines whether the process has a console attached, whether
|
||||||
|
# that console has a non-NULL window (e.g. HWND), and whether the window is on
|
||||||
|
# the current window station.
|
||||||
|
#
|
||||||
|
|
||||||
|
$signature = @'
|
||||||
|
[DllImport("kernel32.dll", SetLastError=true)]
|
||||||
|
public static extern IntPtr GetConsoleWindow();
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
|
||||||
|
public static extern bool SetConsoleTitle(String title);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
|
||||||
|
public static extern int GetWindowText(IntPtr hWnd,
|
||||||
|
System.Text.StringBuilder lpString,
|
||||||
|
int nMaxCount);
|
||||||
|
'@
|
||||||
|
|
||||||
|
$WinAPI = Add-Type -MemberDefinition $signature `
|
||||||
|
-Name WinAPI -Namespace IdentifyConsoleWindow -PassThru
|
||||||
|
|
||||||
|
if (!$WinAPI::SetConsoleTitle("ConsoleWindowScript")) {
|
||||||
|
echo "error: could not change console title -- is a console attached?"
|
||||||
|
exit 1
|
||||||
|
} else {
|
||||||
|
echo "note: successfully set console title to ""ConsoleWindowScript""."
|
||||||
|
}
|
||||||
|
|
||||||
|
$hwnd = $WinAPI::GetConsoleWindow()
|
||||||
|
if ($hwnd -eq 0) {
|
||||||
|
echo "note: GetConsoleWindow returned NULL."
|
||||||
|
} else {
|
||||||
|
echo "note: GetConsoleWindow returned 0x$($hwnd.ToString("X"))."
|
||||||
|
$sb = New-Object System.Text.StringBuilder -ArgumentList 4096
|
||||||
|
if ($WinAPI::GetWindowText($hwnd, $sb, $sb.Capacity)) {
|
||||||
|
$title = $sb.ToString()
|
||||||
|
echo "note: GetWindowText returned ""${title}""."
|
||||||
|
if ($title -eq "ConsoleWindowScript") {
|
||||||
|
echo "success!"
|
||||||
|
} else {
|
||||||
|
echo "error: expected to see ""ConsoleWindowScript""."
|
||||||
|
echo " (Perhaps the console window is on a different window station?)"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "error: GetWindowText could not read the window title."
|
||||||
|
echo " (Perhaps the console window is on a different window station?)"
|
||||||
|
}
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
// Determines whether this is a new console by testing whether MARK moves the
|
||||||
|
// cursor.
|
||||||
|
//
|
||||||
|
// WARNING: This test program may behave erratically if run under winpty.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
const int SC_CONSOLE_SELECT_ALL = 0xFFF5;
|
||||||
|
|
||||||
|
static COORD getWindowPos(HANDLE conout) {
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||||||
|
BOOL ret = GetConsoleScreenBufferInfo(conout, &info);
|
||||||
|
ASSERT(ret && "GetConsoleScreenBufferInfo failed");
|
||||||
|
return { info.srWindow.Left, info.srWindow.Top };
|
||||||
|
}
|
||||||
|
|
||||||
|
static COORD getWindowSize(HANDLE conout) {
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||||||
|
BOOL ret = GetConsoleScreenBufferInfo(conout, &info);
|
||||||
|
ASSERT(ret && "GetConsoleScreenBufferInfo failed");
|
||||||
|
return {
|
||||||
|
static_cast<short>(info.srWindow.Right - info.srWindow.Left + 1),
|
||||||
|
static_cast<short>(info.srWindow.Bottom - info.srWindow.Top + 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static COORD getCursorPos(HANDLE conout) {
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||||||
|
BOOL ret = GetConsoleScreenBufferInfo(conout, &info);
|
||||||
|
ASSERT(ret && "GetConsoleScreenBufferInfo failed");
|
||||||
|
return info.dwCursorPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setCursorPos(HANDLE conout, COORD pos) {
|
||||||
|
BOOL ret = SetConsoleCursorPosition(conout, pos);
|
||||||
|
ASSERT(ret && "SetConsoleCursorPosition failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
const HWND hwnd = GetConsoleWindow();
|
||||||
|
ASSERT(hwnd != NULL && "GetConsoleWindow() returned NULL");
|
||||||
|
|
||||||
|
// With the legacy console, the Mark command moves the the cursor to the
|
||||||
|
// top-left cell of the visible console window. Determine whether this
|
||||||
|
// is the new console by seeing if the cursor moves.
|
||||||
|
|
||||||
|
const auto windowSize = getWindowSize(conout);
|
||||||
|
if (windowSize.X <= 1) {
|
||||||
|
printf("Error: console window must be at least 2 columns wide\n");
|
||||||
|
trace("Error: console window must be at least 2 columns wide");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cursorMoved = false;
|
||||||
|
const auto initialPos = getCursorPos(conout);
|
||||||
|
|
||||||
|
const auto windowPos = getWindowPos(conout);
|
||||||
|
setCursorPos(conout, { static_cast<short>(windowPos.X + 1), windowPos.Y });
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto posA = getCursorPos(conout);
|
||||||
|
SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0);
|
||||||
|
const auto posB = getCursorPos(conout);
|
||||||
|
cursorMoved = memcmp(&posA, &posB, sizeof(posA)) != 0;
|
||||||
|
SendMessage(hwnd, WM_CHAR, 27, 0x00010001); // Send ESCAPE
|
||||||
|
}
|
||||||
|
|
||||||
|
setCursorPos(conout, initialPos);
|
||||||
|
|
||||||
|
if (cursorMoved) {
|
||||||
|
printf("Legacy console (i.e. MARK moved cursor)\n");
|
||||||
|
trace("Legacy console (i.e. MARK moved cursor)");
|
||||||
|
} else {
|
||||||
|
printf("Windows 10 new console (i.e MARK did not move cursor)\n");
|
||||||
|
trace("Windows 10 new console (i.e MARK did not move cursor)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
The only specification I could find describing mouse input escape sequences
|
||||||
|
was the /usr/share/doc/xterm/ctlseqs.txt.gz file installed on my Ubuntu
|
||||||
|
machine.
|
||||||
|
|
||||||
|
Here are the relevant escape sequences:
|
||||||
|
|
||||||
|
* [ON] CSI '?' M 'h' Enable mouse input mode M
|
||||||
|
* [OFF] CSI '?' M 'l' Disable mouse input mode M
|
||||||
|
* [EVT] CSI 'M' F X Y Mouse event (default or mode 1005)
|
||||||
|
* [EVT6] CSI '<' F ';' X ';' Y 'M' Mouse event with mode 1006
|
||||||
|
* [EVT6] CSI '<' F ';' X ';' Y 'm' Mouse event with mode 1006 (up)
|
||||||
|
* [EVT15] CSI F ';' X ';' Y 'M' Mouse event with mode 1015
|
||||||
|
|
||||||
|
The first batch of modes affect what events are reported:
|
||||||
|
|
||||||
|
* 9: Presses only (not as well-supported as the other modes)
|
||||||
|
* 1000: Presses and releases
|
||||||
|
* 1002: Presses, releases, and moves-while-pressed
|
||||||
|
* 1003: Presses, releases, and all moves
|
||||||
|
|
||||||
|
The next batch of modes affect the encoding of the mouse events:
|
||||||
|
|
||||||
|
* 1005: The X and Y coordinates are UTF-8 codepoints rather than bytes.
|
||||||
|
* 1006: Use the EVT6 sequences instead of EVT
|
||||||
|
* 1015: Use the EVT15 sequence instead of EVT (aka URVXT-mode)
|
||||||
|
|
||||||
|
Support for modes in existing terminals
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
| 9 1000 1002 1003 | 1004 | overflow | defhi | 1005 1006 1015
|
||||||
|
---------------------------------+---------------------+------+--------------+-------+----------------
|
||||||
|
Eclipse TM Terminal (Neon) | _ _ _ _ | _ | n/a | n/a | _ _ _
|
||||||
|
gnome-terminal 3.6.2 | X X X X | _ | suppressed*b | 0x07 | _ X X
|
||||||
|
iTerm2 2.1.4 | _ X X X | OI | wrap*z | n/a | X X X
|
||||||
|
jediterm/IntelliJ | _ X X X | _ | ch='?' | 0xff | X X X
|
||||||
|
Konsole 2.13.2 | _ X X *a | _ | suppressed | 0xff | X X X
|
||||||
|
mintty 2.2.2 | X X X X | OI | ch='\0' | 0xff | X X X
|
||||||
|
putty 0.66 | _ X X _ | _ | suppressed | 0xff | _ X X
|
||||||
|
rxvt 2.7.10 | X X _ _ | _ | wrap*z | n/a | _ _ _
|
||||||
|
screen(under xterm) | X X X X | _ | suppressed | 0xff | _ _ _
|
||||||
|
urxvt 9.21 | X X X X | _ | wrap*z | n/a | X _ X
|
||||||
|
xfce4-terminal 0.6.3 (GTK2 VTE) | X X X X | _ | wrap | n/a | _ _ _
|
||||||
|
xterm | X X X X | OI | ch='\0' | 0xff | X X X
|
||||||
|
|
||||||
|
*a: Mode 1003 is handled the same way as 1002.
|
||||||
|
*b: The coordinate wraps from 0xff to 0x00, then maxs out at 0x07. I'm
|
||||||
|
guessing this behavior is a bug? I'm using the Xubuntu 14.04
|
||||||
|
gnome-terminal.
|
||||||
|
*z: These terminals have a bug where column 224 (and row 224, presumably)
|
||||||
|
yields a truncated escape sequence. 224 + 32 is 0, so it would normally
|
||||||
|
yield `CSI 'M' F '\0' Y`, but the '\0' is interpreted as a NUL-terminator.
|
||||||
|
|
||||||
|
Problem 1: How do these flags work?
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Terminals accept the OFF sequence with any of the input modes. This makes
|
||||||
|
little sense--there are two multi-value settings, not seven independent flags!
|
||||||
|
|
||||||
|
All the terminals handle Granularity the same way. ON-Granularity sets
|
||||||
|
Granularity to the specified value, and OFF-Granularity sets Granularity to
|
||||||
|
OFF.
|
||||||
|
|
||||||
|
Terminals vary in how they handle the Encoding modes. For example:
|
||||||
|
|
||||||
|
* xterm. ON-Encoding sets Encoding. OFF-Encoding with a non-active Encoding
|
||||||
|
has no effect. OFF-Encoding otherwise resets Encoding to Default.
|
||||||
|
|
||||||
|
* mintty (tested 2.2.2), iTerm2 2.1.4, and jediterm. ON-Encoding sets
|
||||||
|
Encoding. OFF-Encoding resets Encoding to Default.
|
||||||
|
|
||||||
|
* Konsole (tested 2.13.2) seems to configure each encoding method
|
||||||
|
independently. The effective Encoding is the first enabled encoding in this
|
||||||
|
list:
|
||||||
|
- Mode 1006
|
||||||
|
- Mode 1015
|
||||||
|
- Mode 1005
|
||||||
|
- Default
|
||||||
|
|
||||||
|
* gnome-terminal (tested 3.6.2) also configures each encoding method
|
||||||
|
independently. The effective Encoding is the first enabled encoding in
|
||||||
|
this list:
|
||||||
|
- Mode 1006
|
||||||
|
- Mode 1015
|
||||||
|
- Default
|
||||||
|
Mode 1005 is not supported.
|
||||||
|
|
||||||
|
* xfce4 terminal 0.6.3 (GTK2 VTE) always outputs the default encoding method.
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 3 && argc != 5) {
|
||||||
|
printf("Usage: %s x y\n", argv[0]);
|
||||||
|
printf("Usage: %s x y width height\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
|
||||||
|
const int x = atoi(argv[1]);
|
||||||
|
const int y = atoi(argv[2]);
|
||||||
|
|
||||||
|
int w = 0, h = 0;
|
||||||
|
if (argc == 3) {
|
||||||
|
RECT r = {};
|
||||||
|
BOOL ret = GetWindowRect(hwnd, &r);
|
||||||
|
ASSERT(ret && "GetWindowRect failed on console window");
|
||||||
|
w = r.right - r.left;
|
||||||
|
h = r.bottom - r.top;
|
||||||
|
} else {
|
||||||
|
w = atoi(argv[3]);
|
||||||
|
h = atoi(argv[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ret = MoveWindow(hwnd, x, y, w, h, TRUE);
|
||||||
|
trace("MoveWindow: ret=%d", ret);
|
||||||
|
printf("MoveWindow: ret=%d\n", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+219
@@ -0,0 +1,219 @@
|
|||||||
|
Test programs
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Cygwin
|
||||||
|
emacs
|
||||||
|
vim
|
||||||
|
mc (Midnight Commander)
|
||||||
|
lynx
|
||||||
|
links
|
||||||
|
less
|
||||||
|
more
|
||||||
|
wget
|
||||||
|
|
||||||
|
Capturing the console output
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Initial idea:
|
||||||
|
|
||||||
|
In the agent, keep track of the remote terminal state for N lines of
|
||||||
|
(window+history). Also keep track of the terminal size. Regularly poll for
|
||||||
|
changes to the console screen buffer, then use some number of edits to bring
|
||||||
|
the remote terminal into sync with the console.
|
||||||
|
|
||||||
|
This idea seems to have trouble when a Unix terminal is resized. When the
|
||||||
|
server receives a resize notification, it can have a hard time figuring out
|
||||||
|
what the terminal did. Race conditions might also be a problem.
|
||||||
|
|
||||||
|
The behavior of the terminal can be tricky:
|
||||||
|
|
||||||
|
- When the window is expanded by one line, does the terminal add a blank line
|
||||||
|
to the bottom or move a line from the history into the top?
|
||||||
|
|
||||||
|
- When the window is shrunk by one line, does the terminal delete the topmost
|
||||||
|
or the bottommost line? Can it delete the line with the cursor?
|
||||||
|
|
||||||
|
Some popular behaviors for expanding:
|
||||||
|
- [all] If there are no history lines, then add a line at the bottom.
|
||||||
|
- [konsole] Always add a line at the bottom.
|
||||||
|
- [putty,xterm,rxvt] Pull in a history line from the top.
|
||||||
|
- [g-t] I can't tell. It seems to add a blank line, until the program writes
|
||||||
|
to stdout or until I click the scroll bar, then the output "snaps" back down,
|
||||||
|
pulling lines out of the history. I thought I saw different behavior
|
||||||
|
between Ubuntu 10.10 and 11.10, so maybe GNOME 3 changed something. Avoid
|
||||||
|
using "bash" to test this behavior because "bash" apparently always writes
|
||||||
|
the prompt after terminal resize.
|
||||||
|
|
||||||
|
Some popular behaviors for shrinking:
|
||||||
|
- [konsole,putty,xterm,rxvt] If the line at the bottom is blank, then delete
|
||||||
|
it. Otherwise, move the topmost line into history.
|
||||||
|
- [g-t] If the line at the bottom has not been touched, then delete it.
|
||||||
|
Otherwise, move the topmost line into history.
|
||||||
|
|
||||||
|
(TODO: I need to test my theories about the terminal behavior better still.
|
||||||
|
It's interesting to see how g-t handles clear differently than every other
|
||||||
|
terminal.)
|
||||||
|
|
||||||
|
There is an ANSI escape sequence (DSR) that sends the current cursor location
|
||||||
|
to the terminal's input. One idea I had was to use this code to figure out how
|
||||||
|
the terminal had handled a resize. I currently think this idea won't work due
|
||||||
|
to race conditions.
|
||||||
|
|
||||||
|
Newer idea:
|
||||||
|
|
||||||
|
Keep track of the last N lines that have been sent to the remote terminal.
|
||||||
|
Poll for changes to console output. When the output changes, send just the
|
||||||
|
changed content to the terminal. In particular:
|
||||||
|
- Don't send a cursor position (CUP) code. Instead, if the line that's 3
|
||||||
|
steps up from the latest line changes, send a relative cursor up (CUU)
|
||||||
|
code. It's OK to send an absolute column number code (CHA).
|
||||||
|
- At least in general, don't try to send complete screenshots of the current
|
||||||
|
console window.
|
||||||
|
|
||||||
|
The idea is that sending just the changes should have good behavior for streams
|
||||||
|
of output, even when those streams modify the output (e.g. an archiver, or
|
||||||
|
maybe a downloader/packager/wget). I need to think about whether this works
|
||||||
|
for full-screen programs (e.g. emacs, less, lynx, the above list of programs).
|
||||||
|
|
||||||
|
I noticed that console programs don't typically modify the window or buffer
|
||||||
|
coordinates. edit.com is an exception.
|
||||||
|
|
||||||
|
I tested the pager in native Python (more?), and I verified that ENTER and SPACE
|
||||||
|
both paid no attention to the location of the console window within the screen
|
||||||
|
buffer. This makes sense -- why would they care? The Cygwin less, on the other
|
||||||
|
hand, does care. If I scroll the window up, then Cygwin less will write to a
|
||||||
|
position within the window. I didn't really expect this behavior, but it
|
||||||
|
doesn't seem to be a problem.
|
||||||
|
|
||||||
|
Setting up a TestNetServer service
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
First run the deploy.sh script to copy files into deploy. Make sure
|
||||||
|
TestNetServer.exe will run in a bare environment (no MinGW or Qt in the path).
|
||||||
|
|
||||||
|
Install the Windows Server 2003 Resource Kit. It will have two programs in it,
|
||||||
|
instsrv and srvany.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
InstSrv TestNetServer <path-to-srvany>\srvany.exe
|
||||||
|
|
||||||
|
This creates a service named "TestNetServer" that uses the Microsoft service
|
||||||
|
wrapper. To configure the new service to run TestNetServer, set a registry
|
||||||
|
value:
|
||||||
|
|
||||||
|
[HKLM\SYSTEM\CurrentControlSet\Services\TestNetServer\Parameters]
|
||||||
|
Application=<full-path>\TestNetServer.exe
|
||||||
|
|
||||||
|
Also see http://www.iopus.com/guides/srvany.htm.
|
||||||
|
|
||||||
|
To remove the service, run:
|
||||||
|
|
||||||
|
InstSrv TestNetServer REMOVE
|
||||||
|
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
|
||||||
|
Agent: When resizing the console, consider whether to add lines to the top
|
||||||
|
or bottom. I remember thinking the current behavior was wrong for some
|
||||||
|
application, but I forgot which one.
|
||||||
|
|
||||||
|
Make the font as small as possible. The console window dimensions are limited by
|
||||||
|
the screen size, so making the font small reduces an unnecessary limitation on the
|
||||||
|
PseudoConsole size. There's a documented Vista/Win7 API for this
|
||||||
|
(SetCurrentConsoleFontEx), and apparently WinXP has an undocumented API
|
||||||
|
(SetConsoleFont):
|
||||||
|
http://blogs.microsoft.co.il/blogs/pavely/archive/2009/07/23/changing-console-fonts.aspx
|
||||||
|
|
||||||
|
Make the agent work with DOS programs like edit and qbasic.
|
||||||
|
- Detect that the terminal program has resized the window/buffer and enter a
|
||||||
|
simple just-scrape-and-dont-resize mode. Track the client window size and
|
||||||
|
send the intersection of the console and the agent's client.
|
||||||
|
- I also need to generate keyboard scan codes.
|
||||||
|
- Solve the NTVDM.EXE console shutdown problem, probably by ignoring NTVDM.EXE
|
||||||
|
when it appears on the GetConsoleProcessList list.
|
||||||
|
|
||||||
|
Rename the agent? Is the term "proxy" more accurate?
|
||||||
|
|
||||||
|
Optimize the polling. e.g. Use a longer poll interval when the console is idle.
|
||||||
|
Do a minimal poll that checks whether the sync marker or window has moved.
|
||||||
|
|
||||||
|
Increase the console buffer size to ~9000 lines. Beware making it so big that
|
||||||
|
reading the sync column exhausts the 32KB conhost<->agent heap.
|
||||||
|
|
||||||
|
Reduce the memory overhead of the agent. The agent's m_bufferData array can
|
||||||
|
be small (a few hundred lines?) relative to the console buffer size.
|
||||||
|
|
||||||
|
Try to handle console background color better.
|
||||||
|
Unix terminal emulators have a user-configurable foreground and background
|
||||||
|
color, and for best results, the agent really needs to avoid changing the colors,
|
||||||
|
especially the background color. It's undesirable/ugly to SSH into a machine
|
||||||
|
and see the command prompt change the colors. It's especially ugly that the
|
||||||
|
terminal retains its original colors and only drawn cells get the new colors.
|
||||||
|
(e.g. Resizing the window to the right uses the local terminal colors rather
|
||||||
|
than the remote colors.) It's especially ugly in gnome-terminal, which draws
|
||||||
|
user-configurable black as black, but VT100 black as dark-gray.
|
||||||
|
If there were a way to query the terminal emulator's colors, then I could
|
||||||
|
match the console's colors to the terminal and everything would just work. As
|
||||||
|
far as I know, that's not possible.
|
||||||
|
I thought of a kludge that might work. Instead of translating console white
|
||||||
|
and black to VT/100 white and black, I would translate them to "reset" and
|
||||||
|
"invert". I'd translate other colors normally. This approach should produce
|
||||||
|
ideal results for command-line work and tolerable results for full-screen
|
||||||
|
programs without configuration. Configuring the agent for black-on-white or
|
||||||
|
white-on-black would produce ideal results in all situations.
|
||||||
|
This kludge only really applies to the SSH application. For a Win32 Konsole
|
||||||
|
application, it should be easy to get the colors right all the time.
|
||||||
|
|
||||||
|
Try using the screen reader API:
|
||||||
|
- To eliminate polling.
|
||||||
|
- To detect when a line wraps. When a line wraps, it'd be nice not to send a
|
||||||
|
CRLF to the terminal emulator so copy-and-paste works better.
|
||||||
|
- To detect hard tabs with Cygwin.
|
||||||
|
|
||||||
|
Implement VT100/ANSI escape sequence recognition for input. Decide where this
|
||||||
|
functionality belongs. PseudoConsole.dll? Disambiguating ESC from an escape
|
||||||
|
sequence might be tricky. For the SSH server, I was thinking that when a small
|
||||||
|
SSH payload ended with an ESC character, I could assume the character was really
|
||||||
|
an ESC keypress, on the assumption that if it were an escape sequence, the
|
||||||
|
payload would probably contain the whole sequence. I'm not sure this works,
|
||||||
|
especially if there's a lot of other traffic multiplexed on the SSH socket.
|
||||||
|
|
||||||
|
Support Unicode.
|
||||||
|
- Some DOS programs draw using line/box characters. Can these characters be
|
||||||
|
translated to the Unicode equivalents?
|
||||||
|
|
||||||
|
Create automated tests.
|
||||||
|
|
||||||
|
Experiment with the Terminator emulator, an emulator that doesn't wrap lines.
|
||||||
|
How many columns does it report having? What column does it report the cursor
|
||||||
|
in as it's writing past the right end of the window? Will Terminator be a
|
||||||
|
problem if I implement line wrapping detection in the agent?
|
||||||
|
|
||||||
|
BUG: After the unix-adapter/pconsole.exe program exits, the blinking cursor is
|
||||||
|
replaced with a hidden cursor.
|
||||||
|
|
||||||
|
Fix assert() in the agent. If it fails, the failure message needs to be
|
||||||
|
reported somewhere. Pop up a dialog box? Maybe switch the active desktop,
|
||||||
|
then show a dialog box?
|
||||||
|
|
||||||
|
TODO: There's already a pconsole project on GitHub. Maybe rename this project
|
||||||
|
to something else? winpty?
|
||||||
|
|
||||||
|
TODO: Can the DebugServer system be replaced with OutputDebugString? How
|
||||||
|
do we decide whose processes' output to collect?
|
||||||
|
|
||||||
|
TODO: Three executables:
|
||||||
|
build/winpty-agent.exe
|
||||||
|
build/winpty.dll
|
||||||
|
build/console.exe
|
||||||
|
|
||||||
|
BUG: Run the pconsole.exe inside another console. As I type dir, I see this:
|
||||||
|
D:\rprichard\pconsole>
|
||||||
|
D:\rprichard\pconsole>d
|
||||||
|
D:\rprichard\pconsole>di
|
||||||
|
D:\rprichard\pconsole>dir
|
||||||
|
In the output of "dir", every other line is blank.
|
||||||
|
There was a bug in Terminal::sendLine that was causing this to happen
|
||||||
|
frequently. Now that I fixed it, this bug should only manifest on lines
|
||||||
|
whose last column is not a space (i.e. a full line).
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
|
OSVERSIONINFOEXW info = {0};
|
||||||
|
info.dwOSVersionInfoSize = sizeof(info);
|
||||||
|
assert(GetVersionExW((OSVERSIONINFOW*)&info));
|
||||||
|
|
||||||
|
printf("dwMajorVersion = %d\n", (int)info.dwMajorVersion);
|
||||||
|
printf("dwMinorVersion = %d\n", (int)info.dwMinorVersion);
|
||||||
|
printf("dwBuildNumber = %d\n", (int)info.dwBuildNumber);
|
||||||
|
printf("dwPlatformId = %d\n", (int)info.dwPlatformId);
|
||||||
|
printf("szCSDVersion = %ls\n", info.szCSDVersion);
|
||||||
|
printf("wServicePackMajor = %d\n", info.wServicePackMajor);
|
||||||
|
printf("wServicePackMinor = %d\n", info.wServicePackMinor);
|
||||||
|
printf("wSuiteMask = 0x%x\n", (unsigned int)info.wSuiteMask);
|
||||||
|
printf("wProductType = 0x%x\n", (unsigned int)info.wProductType);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
|||||||
|
//
|
||||||
|
// Verify that console selection blocks writes to an inactive console screen
|
||||||
|
// buffer. Writes TEST PASSED or TEST FAILED to the popup console window.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
const int SC_CONSOLE_SELECT_ALL = 0xFFF5;
|
||||||
|
|
||||||
|
bool g_useMark = false;
|
||||||
|
|
||||||
|
CALLBACK DWORD pausingThread(LPVOID dummy)
|
||||||
|
{
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
trace("Sending selection to freeze");
|
||||||
|
SendMessage(hwnd, WM_SYSCOMMAND,
|
||||||
|
g_useMark ? SC_CONSOLE_MARK :
|
||||||
|
SC_CONSOLE_SELECT_ALL,
|
||||||
|
0);
|
||||||
|
Sleep(1000);
|
||||||
|
trace("Sending escape WM_CHAR to unfreeze");
|
||||||
|
SendMessage(hwnd, WM_CHAR, 27, 0x00010001);
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE createBuffer() {
|
||||||
|
HANDLE buf = CreateConsoleScreenBuffer(
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL,
|
||||||
|
CONSOLE_TEXTMODE_BUFFER,
|
||||||
|
NULL);
|
||||||
|
ASSERT(buf != INVALID_HANDLE_VALUE);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void runTest(bool useMark, bool createEarly) {
|
||||||
|
trace("=======================================");
|
||||||
|
trace("useMark=%d createEarly=%d", useMark, createEarly);
|
||||||
|
g_useMark = useMark;
|
||||||
|
HANDLE buf = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
if (createEarly) {
|
||||||
|
buf = createBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateThread(NULL, 0,
|
||||||
|
pausingThread, NULL,
|
||||||
|
0, NULL);
|
||||||
|
Sleep(500);
|
||||||
|
|
||||||
|
if (!createEarly) {
|
||||||
|
trace("Creating buffer");
|
||||||
|
TimeMeasurement tm1;
|
||||||
|
buf = createBuffer();
|
||||||
|
const double elapsed1 = tm1.elapsed();
|
||||||
|
if (elapsed1 >= 0.250) {
|
||||||
|
printf("!!! TEST FAILED !!!\n");
|
||||||
|
Sleep(2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("Writing to aux buffer");
|
||||||
|
TimeMeasurement tm2;
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleW(buf, L"HI", 2, &actual, NULL);
|
||||||
|
const double elapsed2 = tm2.elapsed();
|
||||||
|
trace("Writing to aux buffer: finished: ret=%d actual=%d (elapsed=%1.3f)", ret, actual, elapsed2);
|
||||||
|
if (elapsed2 < 0.250) {
|
||||||
|
printf("!!! TEST FAILED !!!\n");
|
||||||
|
} else {
|
||||||
|
printf("TEST PASSED\n");
|
||||||
|
}
|
||||||
|
Sleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"child");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string arg = argv[1];
|
||||||
|
if (arg == "child") {
|
||||||
|
for (int useMark = 0; useMark <= 1; useMark++) {
|
||||||
|
for (int createEarly = 0; createEarly <= 1; createEarly++) {
|
||||||
|
runTest(useMark, createEarly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("done...\n");
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+671
@@ -0,0 +1,671 @@
|
|||||||
|
//
|
||||||
|
// Windows versions tested
|
||||||
|
//
|
||||||
|
// Vista Enterprise SP2 32-bit
|
||||||
|
// - ver reports [Version 6.0.6002]
|
||||||
|
// - kernel32.dll product/file versions are 6.0.6002.19381
|
||||||
|
//
|
||||||
|
// Windows 7 Ultimate SP1 32-bit
|
||||||
|
// - ver reports [Version 6.1.7601]
|
||||||
|
// - conhost.exe product/file versions are 6.1.7601.18847
|
||||||
|
// - kernel32.dll product/file versions are 6.1.7601.18847
|
||||||
|
//
|
||||||
|
// Windows Server 2008 R2 Datacenter SP1 64-bit
|
||||||
|
// - ver reports [Version 6.1.7601]
|
||||||
|
// - conhost.exe product/file versions are 6.1.7601.23153
|
||||||
|
// - kernel32.dll product/file versions are 6.1.7601.23153
|
||||||
|
//
|
||||||
|
// Windows 8 Enterprise 32-bit
|
||||||
|
// - ver reports [Version 6.2.9200]
|
||||||
|
// - conhost.exe product/file versions are 6.2.9200.16578
|
||||||
|
// - kernel32.dll product/file versions are 6.2.9200.16859
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Specific version details on working Server 2008 R2:
|
||||||
|
//
|
||||||
|
// dwMajorVersion = 6
|
||||||
|
// dwMinorVersion = 1
|
||||||
|
// dwBuildNumber = 7601
|
||||||
|
// dwPlatformId = 2
|
||||||
|
// szCSDVersion = Service Pack 1
|
||||||
|
// wServicePackMajor = 1
|
||||||
|
// wServicePackMinor = 0
|
||||||
|
// wSuiteMask = 0x190
|
||||||
|
// wProductType = 0x3
|
||||||
|
//
|
||||||
|
// Specific version details on broken Win7:
|
||||||
|
//
|
||||||
|
// dwMajorVersion = 6
|
||||||
|
// dwMinorVersion = 1
|
||||||
|
// dwBuildNumber = 7601
|
||||||
|
// dwPlatformId = 2
|
||||||
|
// szCSDVersion = Service Pack 1
|
||||||
|
// wServicePackMajor = 1
|
||||||
|
// wServicePackMinor = 0
|
||||||
|
// wSuiteMask = 0x100
|
||||||
|
// wProductType = 0x1
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
const char *g_prefix = "";
|
||||||
|
|
||||||
|
static void dumpHandles() {
|
||||||
|
trace("%sSTDIN=0x%I64x STDOUT=0x%I64x STDERR=0x%I64x",
|
||||||
|
g_prefix,
|
||||||
|
(long long)GetStdHandle(STD_INPUT_HANDLE),
|
||||||
|
(long long)GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
(long long)GetStdHandle(STD_ERROR_HANDLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *successOrFail(BOOL ret) {
|
||||||
|
return ret ? "ok" : "FAILED";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void startChildInSameConsole(const wchar_t *args, BOOL
|
||||||
|
bInheritHandles=FALSE) {
|
||||||
|
wchar_t program[1024];
|
||||||
|
wchar_t cmdline[1024];
|
||||||
|
GetModuleFileNameW(NULL, program, 1024);
|
||||||
|
swprintf(cmdline, L"\"%ls\" %ls", program, args);
|
||||||
|
|
||||||
|
STARTUPINFOW sui;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
memset(&sui, 0, sizeof(sui));
|
||||||
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
sui.cb = sizeof(sui);
|
||||||
|
|
||||||
|
CreateProcessW(program, cmdline,
|
||||||
|
NULL, NULL,
|
||||||
|
/*bInheritHandles=*/bInheritHandles,
|
||||||
|
/*dwCreationFlags=*/0,
|
||||||
|
NULL, NULL,
|
||||||
|
&sui, &pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void closeHandle(HANDLE h) {
|
||||||
|
trace("%sClosing handle 0x%I64x...", g_prefix, (long long)h);
|
||||||
|
trace("%sClosing handle 0x%I64x... %s", g_prefix, (long long)h, successOrFail(CloseHandle(h)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE createBuffer() {
|
||||||
|
|
||||||
|
// If sa isn't provided, the handle defaults to not-inheritable.
|
||||||
|
SECURITY_ATTRIBUTES sa = {0};
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
|
||||||
|
trace("%sCreating a new buffer...", g_prefix);
|
||||||
|
HANDLE conout = CreateConsoleScreenBuffer(
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
&sa,
|
||||||
|
CONSOLE_TEXTMODE_BUFFER, NULL);
|
||||||
|
|
||||||
|
trace("%sCreating a new buffer... 0x%I64x", g_prefix, (long long)conout);
|
||||||
|
return conout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE openConout() {
|
||||||
|
|
||||||
|
// If sa isn't provided, the handle defaults to not-inheritable.
|
||||||
|
SECURITY_ATTRIBUTES sa = {0};
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
|
||||||
|
trace("%sOpening CONOUT...", g_prefix);
|
||||||
|
HANDLE conout = CreateFileW(L"CONOUT$",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
&sa,
|
||||||
|
OPEN_EXISTING, 0, NULL);
|
||||||
|
trace("%sOpening CONOUT... 0x%I64x", g_prefix, (long long)conout);
|
||||||
|
return conout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setConsoleActiveScreenBuffer(HANDLE conout) {
|
||||||
|
trace("%sSetConsoleActiveScreenBuffer(0x%I64x) called...",
|
||||||
|
g_prefix, (long long)conout);
|
||||||
|
trace("%sSetConsoleActiveScreenBuffer(0x%I64x) called... %s",
|
||||||
|
g_prefix, (long long)conout,
|
||||||
|
successOrFail(SetConsoleActiveScreenBuffer(conout)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeTest(HANDLE conout, const char *msg) {
|
||||||
|
char writeData[256];
|
||||||
|
sprintf(writeData, "%s%s\n", g_prefix, msg);
|
||||||
|
|
||||||
|
trace("%sWriting to 0x%I64x: '%s'...",
|
||||||
|
g_prefix, (long long)conout, msg);
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleA(conout, writeData, strlen(writeData), &actual, NULL);
|
||||||
|
trace("%sWriting to 0x%I64x: '%s'... %s",
|
||||||
|
g_prefix, (long long)conout, msg,
|
||||||
|
successOrFail(ret && actual == strlen(writeData)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeTest(const char *msg) {
|
||||||
|
writeTest(GetStdHandle(STD_OUTPUT_HANDLE), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TEST 1 -- create new buffer, activate it, and close the handle. The console
|
||||||
|
// automatically switches the screen buffer back to the original.
|
||||||
|
//
|
||||||
|
// This test passes everywhere.
|
||||||
|
//
|
||||||
|
|
||||||
|
static void test1(int argc, char *argv[]) {
|
||||||
|
if (!strcmp(argv[1], "1")) {
|
||||||
|
startChildProcess(L"1:child");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
writeTest(origBuffer, "<-- origBuffer -->");
|
||||||
|
|
||||||
|
HANDLE newBuffer = createBuffer();
|
||||||
|
writeTest(newBuffer, "<-- newBuffer -->");
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer);
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
writeTest(origBuffer, "TEST PASSED!");
|
||||||
|
|
||||||
|
// Closing the handle w/o switching the active screen buffer automatically
|
||||||
|
// switches the console back to the original buffer.
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TEST 2 -- Test program that creates and activates newBuffer, starts a child
|
||||||
|
// process, then closes its newBuffer handle. newBuffer remains activated,
|
||||||
|
// because the child keeps it active. (Also see TEST D.)
|
||||||
|
//
|
||||||
|
|
||||||
|
static void test2(int argc, char *argv[]) {
|
||||||
|
if (!strcmp(argv[1], "2")) {
|
||||||
|
startChildProcess(L"2:parent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "2:parent")) {
|
||||||
|
g_prefix = "parent: ";
|
||||||
|
dumpHandles();
|
||||||
|
HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
writeTest(origBuffer, "<-- origBuffer -->");
|
||||||
|
|
||||||
|
HANDLE newBuffer = createBuffer();
|
||||||
|
writeTest(newBuffer, "<-- newBuffer -->");
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer);
|
||||||
|
|
||||||
|
Sleep(1000);
|
||||||
|
writeTest(newBuffer, "bInheritHandles=FALSE:");
|
||||||
|
startChildInSameConsole(L"2:child", FALSE);
|
||||||
|
Sleep(1000);
|
||||||
|
writeTest(newBuffer, "bInheritHandles=TRUE:");
|
||||||
|
startChildInSameConsole(L"2:child", TRUE);
|
||||||
|
|
||||||
|
Sleep(1000);
|
||||||
|
trace("parent:----");
|
||||||
|
|
||||||
|
// Close the new buffer. The active screen buffer doesn't automatically
|
||||||
|
// switch back to origBuffer, because the child process has a handle open
|
||||||
|
// to the original buffer.
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
|
||||||
|
Sleep(600 * 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "2:child")) {
|
||||||
|
g_prefix = "child: ";
|
||||||
|
dumpHandles();
|
||||||
|
// The child's output isn't visible, because it's still writing to
|
||||||
|
// origBuffer.
|
||||||
|
trace("child:----");
|
||||||
|
writeTest("writing to STDOUT");
|
||||||
|
|
||||||
|
// Handle inheritability is curious. The console handles this program
|
||||||
|
// creates are inheritable, but CreateProcess is called with both
|
||||||
|
// bInheritHandles=TRUE and bInheritHandles=FALSE.
|
||||||
|
//
|
||||||
|
// Vista and Windows 7: bInheritHandles has no effect. The child and
|
||||||
|
// parent processes have the same STDIN/STDOUT/STDERR handles:
|
||||||
|
// 0x3, 0x7, and 0xB. The parent has a 0xF handle for newBuffer.
|
||||||
|
// The child can only write to 0x7, 0xB, and 0xF. Only the writes to
|
||||||
|
// 0xF are visible (i.e. they touch newBuffer).
|
||||||
|
//
|
||||||
|
// Windows 8 or Windows 10 (legacy or non-legacy): the lowest 2 bits of
|
||||||
|
// the HANDLE to WriteConsole seem to be ignored. The new process'
|
||||||
|
// console handles always refer to the buffer that was active when they
|
||||||
|
// started, but the values of the handles depend upon bInheritHandles.
|
||||||
|
// With bInheritHandles=TRUE, the child has the same
|
||||||
|
// STDIN/STDOUT/STDERR/newBuffer handles as the parent, and the three
|
||||||
|
// output handles all work, though their output is all visible. With
|
||||||
|
// bInheritHandles=FALSE, the child has different STDIN/STDOUT/STDERR
|
||||||
|
// handles, and only the new STDOUT/STDERR handles work.
|
||||||
|
//
|
||||||
|
for (unsigned int i = 0x1; i <= 0xB0; ++i) {
|
||||||
|
char msg[256];
|
||||||
|
sprintf(msg, "Write to handle 0x%x", i);
|
||||||
|
HANDLE h = reinterpret_cast<HANDLE>(i);
|
||||||
|
writeTest(h, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sleep(600 * 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TEST A -- demonstrate an apparent Windows bug with screen buffers
|
||||||
|
//
|
||||||
|
// Steps:
|
||||||
|
// - The parent starts a child process.
|
||||||
|
// - The child process creates and activates newBuffer
|
||||||
|
// - The parent opens CONOUT$ and writes to it.
|
||||||
|
// - The parent closes CONOUT$.
|
||||||
|
// - At this point, broken Windows reactivates origBuffer.
|
||||||
|
// - The child writes to newBuffer again.
|
||||||
|
// - The child activates origBuffer again, then closes newBuffer.
|
||||||
|
//
|
||||||
|
// Test passes if the message "TEST PASSED!" is visible.
|
||||||
|
// Test commonly fails if conhost.exe crashes.
|
||||||
|
//
|
||||||
|
// Results:
|
||||||
|
// - Windows 7 Ultimate SP1 32-bit: conhost.exe crashes
|
||||||
|
// - Windows Server 2008 R2 Datacenter SP1 64-bit: PASS
|
||||||
|
// - Windows 8 Enterprise 32-bit: PASS
|
||||||
|
// - Windows 10 64-bit (legacy and non-legacy): PASS
|
||||||
|
//
|
||||||
|
|
||||||
|
static void testA_parentWork() {
|
||||||
|
// Open an extra CONOUT$ handle so that the HANDLE values in parent and
|
||||||
|
// child don't collide. I think it's OK if they collide, but since we're
|
||||||
|
// trying to track down a Windows bug, it's best to avoid unnecessary
|
||||||
|
// complication.
|
||||||
|
HANDLE dummy = openConout();
|
||||||
|
|
||||||
|
Sleep(3000);
|
||||||
|
|
||||||
|
// Step 2: Open CONOUT$ in the parent. This opens the active buffer, which
|
||||||
|
// was just created in the child. It's handle 0x13. Write to it.
|
||||||
|
|
||||||
|
HANDLE newBuffer = openConout();
|
||||||
|
writeTest(newBuffer, "step2: writing to newBuffer");
|
||||||
|
|
||||||
|
Sleep(3000);
|
||||||
|
|
||||||
|
// Step 3: Close handle 0x13. With Windows 7, the console switches back to
|
||||||
|
// origBuffer, and (unless I'm missing something) it shouldn't.
|
||||||
|
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testA_childWork() {
|
||||||
|
HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 1: Create the new screen buffer in the child process and make it
|
||||||
|
// active. (Typically, it's handle 0x0F.)
|
||||||
|
//
|
||||||
|
|
||||||
|
HANDLE newBuffer = createBuffer();
|
||||||
|
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer);
|
||||||
|
writeTest(newBuffer, "<-- newBuffer -->");
|
||||||
|
|
||||||
|
Sleep(9000);
|
||||||
|
trace("child:----");
|
||||||
|
|
||||||
|
// Step 4: write to the newBuffer again.
|
||||||
|
writeTest(newBuffer, "TEST PASSED!");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 5: Switch back to the original screen buffer and close the new
|
||||||
|
// buffer. The switch call succeeds, but the CloseHandle call freezes for
|
||||||
|
// several seconds, because conhost.exe crashes.
|
||||||
|
//
|
||||||
|
Sleep(3000);
|
||||||
|
|
||||||
|
setConsoleActiveScreenBuffer(origBuffer);
|
||||||
|
writeTest(origBuffer, "writing to origBuffer");
|
||||||
|
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
|
||||||
|
// The console HWND is NULL.
|
||||||
|
trace("child: console HWND=0x%I64x", (long long)GetConsoleWindow());
|
||||||
|
|
||||||
|
// At this point, the console window has closed, but the parent/child
|
||||||
|
// processes are still running. Calling AllocConsole would fail, but
|
||||||
|
// calling FreeConsole followed by AllocConsole would both succeed, and a
|
||||||
|
// new console would appear.
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testA(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "A")) {
|
||||||
|
startChildProcess(L"A:parent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "A:parent")) {
|
||||||
|
g_prefix = "parent: ";
|
||||||
|
trace("parent:----");
|
||||||
|
dumpHandles();
|
||||||
|
writeTest("<-- origBuffer -->");
|
||||||
|
startChildInSameConsole(L"A:child");
|
||||||
|
testA_parentWork();
|
||||||
|
Sleep(120000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "A:child")) {
|
||||||
|
g_prefix = "child: ";
|
||||||
|
dumpHandles();
|
||||||
|
testA_childWork();
|
||||||
|
Sleep(120000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TEST B -- invert TEST A -- also crashes conhost on Windows 7
|
||||||
|
//
|
||||||
|
// Test passes if the message "TEST PASSED!" is visible.
|
||||||
|
// Test commonly fails if conhost.exe crashes.
|
||||||
|
//
|
||||||
|
// Results:
|
||||||
|
// - Windows 7 Ultimate SP1 32-bit: conhost.exe crashes
|
||||||
|
// - Windows Server 2008 R2 Datacenter SP1 64-bit: PASS
|
||||||
|
// - Windows 8 Enterprise 32-bit: PASS
|
||||||
|
// - Windows 10 64-bit (legacy and non-legacy): PASS
|
||||||
|
//
|
||||||
|
|
||||||
|
static void testB(int argc, char *argv[]) {
|
||||||
|
if (!strcmp(argv[1], "B")) {
|
||||||
|
startChildProcess(L"B:parent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "B:parent")) {
|
||||||
|
g_prefix = "parent: ";
|
||||||
|
startChildInSameConsole(L"B:child");
|
||||||
|
writeTest("<-- origBuffer -->");
|
||||||
|
HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 1: Create the new buffer and make it active.
|
||||||
|
//
|
||||||
|
trace("%s----", g_prefix);
|
||||||
|
HANDLE newBuffer = createBuffer();
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer);
|
||||||
|
writeTest(newBuffer, "<-- newBuffer -->");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 4: Attempt to write again to the new buffer.
|
||||||
|
//
|
||||||
|
Sleep(9000);
|
||||||
|
trace("%s----", g_prefix);
|
||||||
|
writeTest(newBuffer, "TEST PASSED!");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 5: Switch back to the original buffer.
|
||||||
|
//
|
||||||
|
Sleep(3000);
|
||||||
|
trace("%s----", g_prefix);
|
||||||
|
setConsoleActiveScreenBuffer(origBuffer);
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
writeTest(origBuffer, "writing to the initial buffer");
|
||||||
|
|
||||||
|
Sleep(60000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "B:child")) {
|
||||||
|
g_prefix = "child: ";
|
||||||
|
Sleep(3000);
|
||||||
|
trace("%s----", g_prefix);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 2: Open the newly active buffer and write to it.
|
||||||
|
//
|
||||||
|
HANDLE newBuffer = openConout();
|
||||||
|
writeTest(newBuffer, "writing to newBuffer");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 3: Close the newly active buffer.
|
||||||
|
//
|
||||||
|
Sleep(3000);
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
|
||||||
|
Sleep(60000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TEST C -- Interleaving open/close of console handles also seems to break on
|
||||||
|
// Windows 7.
|
||||||
|
//
|
||||||
|
// Test:
|
||||||
|
// - child creates and activates newBuf1
|
||||||
|
// - parent opens newBuf1
|
||||||
|
// - child creates and activates newBuf2
|
||||||
|
// - parent opens newBuf2, then closes newBuf1
|
||||||
|
// - child switches back to newBuf1
|
||||||
|
// * At this point, the console starts malfunctioning.
|
||||||
|
// - parent and child close newBuf2
|
||||||
|
// - child closes newBuf1
|
||||||
|
//
|
||||||
|
// Test passes if the message "TEST PASSED!" is visible.
|
||||||
|
// Test commonly fails if conhost.exe crashes.
|
||||||
|
//
|
||||||
|
// Results:
|
||||||
|
// - Windows 7 Ultimate SP1 32-bit: conhost.exe crashes
|
||||||
|
// - Windows Server 2008 R2 Datacenter SP1 64-bit: PASS
|
||||||
|
// - Windows 8 Enterprise 32-bit: PASS
|
||||||
|
// - Windows 10 64-bit (legacy and non-legacy): PASS
|
||||||
|
//
|
||||||
|
|
||||||
|
static void testC(int argc, char *argv[]) {
|
||||||
|
if (!strcmp(argv[1], "C")) {
|
||||||
|
startChildProcess(L"C:parent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "C:parent")) {
|
||||||
|
startChildInSameConsole(L"C:child");
|
||||||
|
writeTest("<-- origBuffer -->");
|
||||||
|
g_prefix = "parent: ";
|
||||||
|
|
||||||
|
// At time=4, open newBuffer1.
|
||||||
|
Sleep(4000);
|
||||||
|
trace("%s---- t=4", g_prefix);
|
||||||
|
const HANDLE newBuffer1 = openConout();
|
||||||
|
|
||||||
|
// At time=8, open newBuffer2, and close newBuffer1.
|
||||||
|
Sleep(4000);
|
||||||
|
trace("%s---- t=8", g_prefix);
|
||||||
|
const HANDLE newBuffer2 = openConout();
|
||||||
|
closeHandle(newBuffer1);
|
||||||
|
|
||||||
|
// At time=25, cleanup of newBuffer2.
|
||||||
|
Sleep(17000);
|
||||||
|
trace("%s---- t=25", g_prefix);
|
||||||
|
closeHandle(newBuffer2);
|
||||||
|
|
||||||
|
Sleep(240000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "C:child")) {
|
||||||
|
g_prefix = "child: ";
|
||||||
|
|
||||||
|
// At time=2, create newBuffer1 and activate it.
|
||||||
|
Sleep(2000);
|
||||||
|
trace("%s---- t=2", g_prefix);
|
||||||
|
const HANDLE newBuffer1 = createBuffer();
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer1);
|
||||||
|
writeTest(newBuffer1, "<-- newBuffer1 -->");
|
||||||
|
|
||||||
|
// At time=6, create newBuffer2 and activate it.
|
||||||
|
Sleep(4000);
|
||||||
|
trace("%s---- t=6", g_prefix);
|
||||||
|
const HANDLE newBuffer2 = createBuffer();
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer2);
|
||||||
|
writeTest(newBuffer2, "<-- newBuffer2 -->");
|
||||||
|
|
||||||
|
// At time=10, attempt to switch back to newBuffer1. The parent process
|
||||||
|
// has opened and closed its handle to newBuffer1, so does it still exist?
|
||||||
|
Sleep(4000);
|
||||||
|
trace("%s---- t=10", g_prefix);
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer1);
|
||||||
|
writeTest(newBuffer1, "write to newBuffer1: TEST PASSED!");
|
||||||
|
|
||||||
|
// At time=25, cleanup of newBuffer2.
|
||||||
|
Sleep(15000);
|
||||||
|
trace("%s---- t=25", g_prefix);
|
||||||
|
closeHandle(newBuffer2);
|
||||||
|
|
||||||
|
// At time=35, cleanup of newBuffer1. The console should switch to the
|
||||||
|
// initial buffer again.
|
||||||
|
Sleep(10000);
|
||||||
|
trace("%s---- t=35", g_prefix);
|
||||||
|
closeHandle(newBuffer1);
|
||||||
|
|
||||||
|
Sleep(240000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TEST D -- parent creates a new buffer, child launches, writes,
|
||||||
|
// closes it output handle, then parent writes again. (Also see TEST 2.)
|
||||||
|
//
|
||||||
|
// On success, this will appear:
|
||||||
|
//
|
||||||
|
// parent: <-- newBuffer -->
|
||||||
|
// child: writing to newBuffer
|
||||||
|
// parent: TEST PASSED!
|
||||||
|
//
|
||||||
|
// If this appears, it indicates that the child's closing its output handle did
|
||||||
|
// not destroy newBuffer.
|
||||||
|
//
|
||||||
|
// Results:
|
||||||
|
// - Windows 7 Ultimate SP1 32-bit: PASS
|
||||||
|
// - Windows 8 Enterprise 32-bit: PASS
|
||||||
|
// - Windows 10 64-bit (legacy and non-legacy): PASS
|
||||||
|
//
|
||||||
|
|
||||||
|
static void testD(int argc, char *argv[]) {
|
||||||
|
if (!strcmp(argv[1], "D")) {
|
||||||
|
startChildProcess(L"D:parent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "D:parent")) {
|
||||||
|
g_prefix = "parent: ";
|
||||||
|
HANDLE origBuffer = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
writeTest(origBuffer, "<-- origBuffer -->");
|
||||||
|
|
||||||
|
HANDLE newBuffer = createBuffer();
|
||||||
|
writeTest(newBuffer, "<-- newBuffer -->");
|
||||||
|
setConsoleActiveScreenBuffer(newBuffer);
|
||||||
|
|
||||||
|
// At t=2, start a child process, explicitly forcing it to use
|
||||||
|
// newBuffer for its standard handles. These calls are apparently
|
||||||
|
// redundant on Windows 8 and up.
|
||||||
|
Sleep(2000);
|
||||||
|
trace("parent:----");
|
||||||
|
trace("parent: starting child process");
|
||||||
|
SetStdHandle(STD_OUTPUT_HANDLE, newBuffer);
|
||||||
|
SetStdHandle(STD_ERROR_HANDLE, newBuffer);
|
||||||
|
startChildInSameConsole(L"D:child");
|
||||||
|
SetStdHandle(STD_OUTPUT_HANDLE, origBuffer);
|
||||||
|
SetStdHandle(STD_ERROR_HANDLE, origBuffer);
|
||||||
|
|
||||||
|
// At t=6, write again to newBuffer.
|
||||||
|
Sleep(4000);
|
||||||
|
trace("parent:----");
|
||||||
|
writeTest(newBuffer, "TEST PASSED!");
|
||||||
|
|
||||||
|
// At t=8, close the newBuffer. In earlier versions of windows
|
||||||
|
// (including Server 2008 R2), the console then switches back to
|
||||||
|
// origBuffer. As of Windows 8, it doesn't, because somehow the child
|
||||||
|
// process is keeping the console on newBuffer, even though the child
|
||||||
|
// process closed its STDIN/STDOUT/STDERR handles. Killing the child
|
||||||
|
// process by hand after the test finishes *does* force the console
|
||||||
|
// back to origBuffer.
|
||||||
|
Sleep(2000);
|
||||||
|
closeHandle(newBuffer);
|
||||||
|
|
||||||
|
Sleep(120000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "D:child")) {
|
||||||
|
g_prefix = "child: ";
|
||||||
|
// At t=2, the child starts.
|
||||||
|
trace("child:----");
|
||||||
|
dumpHandles();
|
||||||
|
writeTest("writing to newBuffer");
|
||||||
|
|
||||||
|
// At t=4, the child explicitly closes its handle.
|
||||||
|
Sleep(2000);
|
||||||
|
trace("child:----");
|
||||||
|
if (GetStdHandle(STD_ERROR_HANDLE) != GetStdHandle(STD_OUTPUT_HANDLE)) {
|
||||||
|
closeHandle(GetStdHandle(STD_ERROR_HANDLE));
|
||||||
|
}
|
||||||
|
closeHandle(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||||
|
closeHandle(GetStdHandle(STD_INPUT_HANDLE));
|
||||||
|
|
||||||
|
Sleep(120000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
printf("USAGE: %s testnum\n", argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv[1][0] == '1') {
|
||||||
|
test1(argc, argv);
|
||||||
|
} else if (argv[1][0] == '2') {
|
||||||
|
test2(argc, argv);
|
||||||
|
} else if (argv[1][0] == 'A') {
|
||||||
|
testA(argc, argv);
|
||||||
|
} else if (argv[1][0] == 'B') {
|
||||||
|
testB(argc, argv);
|
||||||
|
} else if (argv[1][0] == 'C') {
|
||||||
|
testC(argc, argv);
|
||||||
|
} else if (argv[1][0] == 'D') {
|
||||||
|
testD(argc, argv);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
const char *g_prefix = "";
|
||||||
|
|
||||||
|
static void dumpHandles() {
|
||||||
|
trace("%sSTDIN=0x%I64x STDOUT=0x%I64x STDERR=0x%I64x",
|
||||||
|
g_prefix,
|
||||||
|
(long long)GetStdHandle(STD_INPUT_HANDLE),
|
||||||
|
(long long)GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
(long long)GetStdHandle(STD_ERROR_HANDLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE createBuffer() {
|
||||||
|
|
||||||
|
// If sa isn't provided, the handle defaults to not-inheritable.
|
||||||
|
SECURITY_ATTRIBUTES sa = {0};
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
|
||||||
|
trace("%sCreating a new buffer...", g_prefix);
|
||||||
|
HANDLE conout = CreateConsoleScreenBuffer(
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
&sa,
|
||||||
|
CONSOLE_TEXTMODE_BUFFER, NULL);
|
||||||
|
|
||||||
|
trace("%sCreating a new buffer... 0x%I64x", g_prefix, (long long)conout);
|
||||||
|
return conout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *successOrFail(BOOL ret) {
|
||||||
|
return ret ? "ok" : "FAILED";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setConsoleActiveScreenBuffer(HANDLE conout) {
|
||||||
|
trace("%sSetConsoleActiveScreenBuffer(0x%I64x) called...",
|
||||||
|
g_prefix, (long long)conout);
|
||||||
|
trace("%sSetConsoleActiveScreenBuffer(0x%I64x) called... %s",
|
||||||
|
g_prefix, (long long)conout,
|
||||||
|
successOrFail(SetConsoleActiveScreenBuffer(conout)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeTest(HANDLE conout, const char *msg) {
|
||||||
|
char writeData[256];
|
||||||
|
sprintf(writeData, "%s%s\n", g_prefix, msg);
|
||||||
|
|
||||||
|
trace("%sWriting to 0x%I64x: '%s'...",
|
||||||
|
g_prefix, (long long)conout, msg);
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleA(conout, writeData, strlen(writeData), &actual, NULL);
|
||||||
|
trace("%sWriting to 0x%I64x: '%s'... %s",
|
||||||
|
g_prefix, (long long)conout, msg,
|
||||||
|
successOrFail(ret && actual == strlen(writeData)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE startChildInSameConsole(const wchar_t *args, BOOL
|
||||||
|
bInheritHandles=FALSE) {
|
||||||
|
wchar_t program[1024];
|
||||||
|
wchar_t cmdline[1024];
|
||||||
|
GetModuleFileNameW(NULL, program, 1024);
|
||||||
|
swprintf(cmdline, L"\"%ls\" %ls", program, args);
|
||||||
|
|
||||||
|
STARTUPINFOW sui;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
memset(&sui, 0, sizeof(sui));
|
||||||
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
sui.cb = sizeof(sui);
|
||||||
|
|
||||||
|
CreateProcessW(program, cmdline,
|
||||||
|
NULL, NULL,
|
||||||
|
/*bInheritHandles=*/bInheritHandles,
|
||||||
|
/*dwCreationFlags=*/0,
|
||||||
|
NULL, NULL,
|
||||||
|
&sui, &pi);
|
||||||
|
|
||||||
|
return pi.hProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE dup(HANDLE h, HANDLE targetProcess) {
|
||||||
|
HANDLE h2 = INVALID_HANDLE_VALUE;
|
||||||
|
BOOL ret = DuplicateHandle(
|
||||||
|
GetCurrentProcess(), h,
|
||||||
|
targetProcess, &h2,
|
||||||
|
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||||
|
trace("dup(0x%I64x) to process 0x%I64x... %s, 0x%I64x",
|
||||||
|
(long long)h,
|
||||||
|
(long long)targetProcess,
|
||||||
|
successOrFail(ret),
|
||||||
|
(long long)h2);
|
||||||
|
return h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"parent");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "parent")) {
|
||||||
|
g_prefix = "parent: ";
|
||||||
|
dumpHandles();
|
||||||
|
HANDLE hChild = startChildInSameConsole(L"child");
|
||||||
|
|
||||||
|
// Windows 10.
|
||||||
|
HANDLE orig1 = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
HANDLE new1 = createBuffer();
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
setConsoleActiveScreenBuffer(new1);
|
||||||
|
|
||||||
|
// Handle duplication results to child process in same console:
|
||||||
|
// - Windows XP: fails
|
||||||
|
// - Windows 7 Ultimate SP1 32-bit: fails
|
||||||
|
// - Windows Server 2008 R2 Datacenter SP1 64-bit: fails
|
||||||
|
// - Windows 8 Enterprise 32-bit: succeeds
|
||||||
|
// - Windows 10: succeeds
|
||||||
|
HANDLE orig2 = dup(orig1, GetCurrentProcess());
|
||||||
|
HANDLE new2 = dup(new1, GetCurrentProcess());
|
||||||
|
|
||||||
|
dup(orig1, hChild);
|
||||||
|
dup(new1, hChild);
|
||||||
|
|
||||||
|
// The writes to orig1/orig2 are invisible. The writes to new1/new2
|
||||||
|
// are visible.
|
||||||
|
writeTest(orig1, "write to orig1");
|
||||||
|
writeTest(orig2, "write to orig2");
|
||||||
|
writeTest(new1, "write to new1");
|
||||||
|
writeTest(new2, "write to new2");
|
||||||
|
|
||||||
|
Sleep(120000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "child")) {
|
||||||
|
g_prefix = "child: ";
|
||||||
|
dumpHandles();
|
||||||
|
Sleep(4000);
|
||||||
|
for (unsigned int i = 0x1; i <= 0xB0; ++i) {
|
||||||
|
char msg[256];
|
||||||
|
sprintf(msg, "Write to handle 0x%x", i);
|
||||||
|
HANDLE h = reinterpret_cast<HANDLE>(i);
|
||||||
|
writeTest(h, msg);
|
||||||
|
}
|
||||||
|
Sleep(120000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "../src/shared/DebugClient.cc"
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
const int SC_CONSOLE_SELECT_ALL = 0xFFF5;
|
||||||
|
|
||||||
|
CALLBACK DWORD pausingThread(LPVOID dummy)
|
||||||
|
{
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
while (true) {
|
||||||
|
SendMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_SELECT_ALL, 0);
|
||||||
|
Sleep(1000);
|
||||||
|
SendMessage(hwnd, WM_CHAR, 27, 0x00010001);
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
|
||||||
|
GetConsoleScreenBufferInfo(out, &info);
|
||||||
|
COORD initial = info.dwCursorPosition;
|
||||||
|
|
||||||
|
CreateThread(NULL, 0,
|
||||||
|
pausingThread, NULL,
|
||||||
|
0, NULL);
|
||||||
|
|
||||||
|
for (int i = 0; i < 30; ++i) {
|
||||||
|
Sleep(100);
|
||||||
|
GetConsoleScreenBufferInfo(out, &info);
|
||||||
|
if (memcmp(&info.dwCursorPosition, &initial, sizeof(COORD)) != 0) {
|
||||||
|
trace("cursor moved to [%d,%d]",
|
||||||
|
info.dwCursorPosition.X,
|
||||||
|
info.dwCursorPosition.Y);
|
||||||
|
} else {
|
||||||
|
trace("cursor in expected position");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("Usage: %s x y width height\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE conout = CreateFileW(L"CONOUT$",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ASSERT(conout != INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
COORD size = {
|
||||||
|
(short)atoi(argv[1]),
|
||||||
|
(short)atoi(argv[2]),
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOL ret = SetConsoleScreenBufferSize(conout, size);
|
||||||
|
const unsigned lastError = GetLastError();
|
||||||
|
const char *const retStr = ret ? "OK" : "failed";
|
||||||
|
trace("SetConsoleScreenBufferSize ret: %s (LastError=0x%x)", retStr, lastError);
|
||||||
|
printf("SetConsoleScreenBufferSize ret: %s (LastError=0x%x)\n", retStr, lastError);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int col = atoi(argv[1]);
|
||||||
|
int row = atoi(argv[2]);
|
||||||
|
setCursorPos(col, row);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+145
@@ -0,0 +1,145 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
#define COUNT_OF(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
|
||||||
|
// See https://en.wikipedia.org/wiki/List_of_CJK_fonts
|
||||||
|
const wchar_t kMSGothic[] = { 0xff2d, 0xff33, 0x0020, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 }; // Japanese
|
||||||
|
const wchar_t kNSimSun[] = { 0x65b0, 0x5b8b, 0x4f53, 0 }; // Simplified Chinese
|
||||||
|
const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
|
||||||
|
const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
wchar_t *cmdline = GetCommandLineW();
|
||||||
|
int argc = 0;
|
||||||
|
wchar_t **argv = CommandLineToArgvW(cmdline, &argc);
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
cprintf(L"Usage:\n");
|
||||||
|
cprintf(L" SetFont <index>\n");
|
||||||
|
cprintf(L" SetFont options\n");
|
||||||
|
cprintf(L"\n");
|
||||||
|
cprintf(L"Options for SetCurrentConsoleFontEx:\n");
|
||||||
|
cprintf(L" -idx INDEX\n");
|
||||||
|
cprintf(L" -w WIDTH\n");
|
||||||
|
cprintf(L" -h HEIGHT\n");
|
||||||
|
cprintf(L" -family (0xNN|NN)\n");
|
||||||
|
cprintf(L" -weight (normal|bold|NNN)\n");
|
||||||
|
cprintf(L" -face FACENAME\n");
|
||||||
|
cprintf(L" -face-{gothic|simsun|minglight|gulimche) [JP,CN-sim,CN-tra,KR]\n");
|
||||||
|
cprintf(L" -tt\n");
|
||||||
|
cprintf(L" -vec\n");
|
||||||
|
cprintf(L" -vp\n");
|
||||||
|
cprintf(L" -dev\n");
|
||||||
|
cprintf(L" -roman\n");
|
||||||
|
cprintf(L" -swiss\n");
|
||||||
|
cprintf(L" -modern\n");
|
||||||
|
cprintf(L" -script\n");
|
||||||
|
cprintf(L" -decorative\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdigit(argv[1][0])) {
|
||||||
|
int index = _wtoi(argv[1]);
|
||||||
|
HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
|
||||||
|
FARPROC proc = GetProcAddress(kernel32, "SetConsoleFont");
|
||||||
|
if (proc == NULL) {
|
||||||
|
cprintf(L"Couldn't get address of SetConsoleFont\n");
|
||||||
|
} else {
|
||||||
|
BOOL ret = reinterpret_cast<BOOL WINAPI(*)(HANDLE, DWORD)>(proc)(
|
||||||
|
conout, index);
|
||||||
|
cprintf(L"SetFont returned %d\n", ret);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSOLE_FONT_INFOEX fontex = {0};
|
||||||
|
fontex.cbSize = sizeof(fontex);
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
std::wstring arg = argv[i];
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
std::wstring next = argv[i + 1];
|
||||||
|
if (arg == L"-idx") {
|
||||||
|
fontex.nFont = _wtoi(next.c_str());
|
||||||
|
++i; continue;
|
||||||
|
} else if (arg == L"-w") {
|
||||||
|
fontex.dwFontSize.X = _wtoi(next.c_str());
|
||||||
|
++i; continue;
|
||||||
|
} else if (arg == L"-h") {
|
||||||
|
fontex.dwFontSize.Y = _wtoi(next.c_str());
|
||||||
|
++i; continue;
|
||||||
|
} else if (arg == L"-weight") {
|
||||||
|
if (next == L"normal") {
|
||||||
|
fontex.FontWeight = 400;
|
||||||
|
} else if (next == L"bold") {
|
||||||
|
fontex.FontWeight = 700;
|
||||||
|
} else {
|
||||||
|
fontex.FontWeight = _wtoi(next.c_str());
|
||||||
|
}
|
||||||
|
++i; continue;
|
||||||
|
} else if (arg == L"-face") {
|
||||||
|
wcsncpy(fontex.FaceName, next.c_str(), COUNT_OF(fontex.FaceName));
|
||||||
|
++i; continue;
|
||||||
|
} else if (arg == L"-family") {
|
||||||
|
fontex.FontFamily = strtol(narrowString(next).c_str(), nullptr, 0);
|
||||||
|
++i; continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arg == L"-tt") {
|
||||||
|
fontex.FontFamily |= TMPF_TRUETYPE;
|
||||||
|
} else if (arg == L"-vec") {
|
||||||
|
fontex.FontFamily |= TMPF_VECTOR;
|
||||||
|
} else if (arg == L"-vp") {
|
||||||
|
// Setting the TMPF_FIXED_PITCH bit actually indicates variable
|
||||||
|
// pitch.
|
||||||
|
fontex.FontFamily |= TMPF_FIXED_PITCH;
|
||||||
|
} else if (arg == L"-dev") {
|
||||||
|
fontex.FontFamily |= TMPF_DEVICE;
|
||||||
|
} else if (arg == L"-roman") {
|
||||||
|
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_ROMAN;
|
||||||
|
} else if (arg == L"-swiss") {
|
||||||
|
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_SWISS;
|
||||||
|
} else if (arg == L"-modern") {
|
||||||
|
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_MODERN;
|
||||||
|
} else if (arg == L"-script") {
|
||||||
|
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_SCRIPT;
|
||||||
|
} else if (arg == L"-decorative") {
|
||||||
|
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_DECORATIVE;
|
||||||
|
} else if (arg == L"-face-gothic") {
|
||||||
|
wcsncpy(fontex.FaceName, kMSGothic, COUNT_OF(fontex.FaceName));
|
||||||
|
} else if (arg == L"-face-simsun") {
|
||||||
|
wcsncpy(fontex.FaceName, kNSimSun, COUNT_OF(fontex.FaceName));
|
||||||
|
} else if (arg == L"-face-minglight") {
|
||||||
|
wcsncpy(fontex.FaceName, kMingLight, COUNT_OF(fontex.FaceName));
|
||||||
|
} else if (arg == L"-face-gulimche") {
|
||||||
|
wcsncpy(fontex.FaceName, kGulimChe, COUNT_OF(fontex.FaceName));
|
||||||
|
} else {
|
||||||
|
cprintf(L"Unrecognized argument: %ls\n", arg.c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cprintf(L"Setting to: nFont=%u dwFontSize=(%d,%d) "
|
||||||
|
L"FontFamily=0x%x FontWeight=%u "
|
||||||
|
L"FaceName=\"%ls\"\n",
|
||||||
|
static_cast<unsigned>(fontex.nFont),
|
||||||
|
fontex.dwFontSize.X, fontex.dwFontSize.Y,
|
||||||
|
fontex.FontFamily, fontex.FontWeight,
|
||||||
|
fontex.FaceName);
|
||||||
|
|
||||||
|
BOOL ret = SetCurrentConsoleFontEx(
|
||||||
|
conout,
|
||||||
|
FALSE,
|
||||||
|
&fontex);
|
||||||
|
cprintf(L"SetCurrentConsoleFontEx returned %d\n", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 5) {
|
||||||
|
printf("Usage: %s x y width height\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE conout = CreateFileW(L"CONOUT$",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ASSERT(conout != INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
SMALL_RECT sr = {
|
||||||
|
(short)atoi(argv[1]),
|
||||||
|
(short)atoi(argv[2]),
|
||||||
|
(short)(atoi(argv[1]) + atoi(argv[3]) - 1),
|
||||||
|
(short)(atoi(argv[2]) + atoi(argv[4]) - 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
trace("Calling SetConsoleWindowInfo with {L=%d,T=%d,R=%d,B=%d}",
|
||||||
|
sr.Left, sr.Top, sr.Right, sr.Bottom);
|
||||||
|
BOOL ret = SetConsoleWindowInfo(conout, TRUE, &sr);
|
||||||
|
const unsigned lastError = GetLastError();
|
||||||
|
const char *const retStr = ret ? "OK" : "failed";
|
||||||
|
trace("SetConsoleWindowInfo ret: %s (LastError=0x%x)", retStr, lastError);
|
||||||
|
printf("SetConsoleWindowInfo ret: %s (LastError=0x%x)\n", retStr, lastError);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// This test program is useful for studying commandline<->argv conversion.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
printf("cmdline = [%s]\n", GetCommandLine());
|
||||||
|
for (int i = 0; i < argc; ++i)
|
||||||
|
printf("[%s]\n", argv[i]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
static int escCount = 0;
|
||||||
|
|
||||||
|
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
while (true) {
|
||||||
|
DWORD count;
|
||||||
|
INPUT_RECORD ir;
|
||||||
|
if (!ReadConsoleInput(hStdin, &ir, 1, &count)) {
|
||||||
|
printf("ReadConsoleInput failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
DWORD mode;
|
||||||
|
GetConsoleMode(hStdin, &mode);
|
||||||
|
SetConsoleMode(hStdin, mode & ~ENABLE_PROCESSED_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ir.EventType == KEY_EVENT) {
|
||||||
|
const KEY_EVENT_RECORD &ker = ir.Event.KeyEvent;
|
||||||
|
printf("%s", ker.bKeyDown ? "dn" : "up");
|
||||||
|
printf(" ch=");
|
||||||
|
if (isprint(ker.uChar.AsciiChar))
|
||||||
|
printf("'%c'", ker.uChar.AsciiChar);
|
||||||
|
printf("%d", ker.uChar.AsciiChar);
|
||||||
|
printf(" vk=%#x", ker.wVirtualKeyCode);
|
||||||
|
printf(" scan=%#x", ker.wVirtualScanCode);
|
||||||
|
printf(" state=%#x", (int)ker.dwControlKeyState);
|
||||||
|
printf(" repeat=%d", ker.wRepeatCount);
|
||||||
|
printf("\n");
|
||||||
|
if (ker.uChar.AsciiChar == 27 && ++escCount == 6)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
i = 0;
|
||||||
|
while True:
|
||||||
|
i += 1
|
||||||
|
print(i)
|
||||||
+172
@@ -0,0 +1,172 @@
|
|||||||
|
// This file is included into test programs using #include
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../src/shared/DebugClient.h"
|
||||||
|
#include "../src/shared/TimeMeasurement.h"
|
||||||
|
|
||||||
|
#include "../src/shared/DebugClient.cc"
|
||||||
|
#include "../src/shared/WinptyAssert.cc"
|
||||||
|
#include "../src/shared/WinptyException.cc"
|
||||||
|
|
||||||
|
// Launch this test program again, in a new console that we will destroy.
|
||||||
|
static void startChildProcess(const wchar_t *args) {
|
||||||
|
wchar_t program[1024];
|
||||||
|
wchar_t cmdline[1024];
|
||||||
|
GetModuleFileNameW(NULL, program, 1024);
|
||||||
|
swprintf(cmdline, L"\"%ls\" %ls", program, args);
|
||||||
|
|
||||||
|
STARTUPINFOW sui;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
memset(&sui, 0, sizeof(sui));
|
||||||
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
sui.cb = sizeof(sui);
|
||||||
|
|
||||||
|
CreateProcessW(program, cmdline,
|
||||||
|
NULL, NULL,
|
||||||
|
/*bInheritHandles=*/FALSE,
|
||||||
|
/*dwCreationFlags=*/CREATE_NEW_CONSOLE,
|
||||||
|
NULL, NULL,
|
||||||
|
&sui, &pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setBufferSize(HANDLE conout, int x, int y) {
|
||||||
|
COORD size = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
|
||||||
|
BOOL success = SetConsoleScreenBufferSize(conout, size);
|
||||||
|
trace("setBufferSize: (%d,%d), result=%d", x, y, success);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setWindowPos(HANDLE conout, int x, int y, int w, int h) {
|
||||||
|
SMALL_RECT r = {
|
||||||
|
static_cast<SHORT>(x), static_cast<SHORT>(y),
|
||||||
|
static_cast<SHORT>(x + w - 1),
|
||||||
|
static_cast<SHORT>(y + h - 1)
|
||||||
|
};
|
||||||
|
BOOL success = SetConsoleWindowInfo(conout, /*bAbsolute=*/TRUE, &r);
|
||||||
|
trace("setWindowPos: (%d,%d,%d,%d), result=%d", x, y, w, h, success);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setCursorPos(HANDLE conout, int x, int y) {
|
||||||
|
COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
|
||||||
|
SetConsoleCursorPosition(conout, coord);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setBufferSize(int x, int y) {
|
||||||
|
setBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setWindowPos(int x, int y, int w, int h) {
|
||||||
|
setWindowPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setCursorPos(int x, int y) {
|
||||||
|
setCursorPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void countDown(int sec) {
|
||||||
|
for (int i = sec; i > 0; --i) {
|
||||||
|
printf("%d.. ", i);
|
||||||
|
fflush(stdout);
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeBox(int x, int y, int w, int h, char ch, int attributes=7) {
|
||||||
|
CHAR_INFO info = { 0 };
|
||||||
|
info.Char.AsciiChar = ch;
|
||||||
|
info.Attributes = attributes;
|
||||||
|
std::vector<CHAR_INFO> buf(w * h, info);
|
||||||
|
HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
COORD bufSize = { static_cast<SHORT>(w), static_cast<SHORT>(h) };
|
||||||
|
COORD bufCoord = { 0, 0 };
|
||||||
|
SMALL_RECT writeRegion = {
|
||||||
|
static_cast<SHORT>(x),
|
||||||
|
static_cast<SHORT>(y),
|
||||||
|
static_cast<SHORT>(x + w - 1),
|
||||||
|
static_cast<SHORT>(y + h - 1)
|
||||||
|
};
|
||||||
|
WriteConsoleOutputA(conout, buf.data(), bufSize, bufCoord, &writeRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setChar(int x, int y, char ch, int attributes=7) {
|
||||||
|
writeBox(x, y, 1, 1, ch, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fillChar(int x, int y, int repeat, char ch) {
|
||||||
|
COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
|
||||||
|
DWORD actual = 0;
|
||||||
|
FillConsoleOutputCharacterA(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
ch, repeat, coord, &actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void repeatChar(int count, char ch) {
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
putchar(ch);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// I don't know why, but wprintf fails to print this face name,
|
||||||
|
// "MS ゴシック" (aka MS Gothic). It helps to use wprintf instead of printf, and
|
||||||
|
// it helps to call `setlocale(LC_ALL, "")`, but the Japanese symbols are
|
||||||
|
// ultimately converted to `?` symbols, even though MS Gothic is able to
|
||||||
|
// display its own name, and the current code page is 932 (Shift-JIS).
|
||||||
|
static void cvfprintf(HANDLE conout, const wchar_t *fmt, va_list ap) {
|
||||||
|
wchar_t buffer[256];
|
||||||
|
vswprintf(buffer, 256 - 1, fmt, ap);
|
||||||
|
buffer[255] = L'\0';
|
||||||
|
DWORD actual = 0;
|
||||||
|
if (!WriteConsoleW(conout, buffer, wcslen(buffer), &actual, NULL)) {
|
||||||
|
wprintf(L"WriteConsoleW call failed!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cfprintf(HANDLE conout, const wchar_t *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
cvfprintf(conout, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cprintf(const wchar_t *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
cvfprintf(GetStdHandle(STD_OUTPUT_HANDLE), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string narrowString(const std::wstring &input)
|
||||||
|
{
|
||||||
|
int mblen = WideCharToMultiByte(
|
||||||
|
CP_UTF8, 0,
|
||||||
|
input.data(), input.size(),
|
||||||
|
NULL, 0, NULL, NULL);
|
||||||
|
if (mblen <= 0) {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
std::vector<char> tmp(mblen);
|
||||||
|
int mblen2 = WideCharToMultiByte(
|
||||||
|
CP_UTF8, 0,
|
||||||
|
input.data(), input.size(),
|
||||||
|
tmp.data(), tmp.size(),
|
||||||
|
NULL, NULL);
|
||||||
|
assert(mblen2 == mblen);
|
||||||
|
return std::string(tmp.data(), tmp.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE openConout() {
|
||||||
|
const HANDLE conout = CreateFileW(L"CONOUT$",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ASSERT(conout != INVALID_HANDLE_VALUE);
|
||||||
|
return conout;
|
||||||
|
}
|
||||||
Generated
Vendored
+102
@@ -0,0 +1,102 @@
|
|||||||
|
// Demonstrates how U+30FC is sometimes handled as a single-width character
|
||||||
|
// when it should be handled as a double-width character.
|
||||||
|
//
|
||||||
|
// It only runs on computers where 932 is a valid code page. Set the system
|
||||||
|
// local to "Japanese (Japan)" to ensure this.
|
||||||
|
//
|
||||||
|
// The problem seems to happen when U+30FC is printed in a console using the
|
||||||
|
// Lucida Console font, and only when that font is at certain sizes.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
static void setFont(const wchar_t *faceName, int pxSize) {
|
||||||
|
CONSOLE_FONT_INFOEX infoex = {0};
|
||||||
|
infoex.cbSize = sizeof(infoex);
|
||||||
|
infoex.dwFontSize.Y = pxSize;
|
||||||
|
wcsncpy(infoex.FaceName, faceName, COUNT_OF(infoex.FaceName));
|
||||||
|
BOOL ret = SetCurrentConsoleFontEx(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &infoex);
|
||||||
|
assert(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool performTest(const wchar_t testChar) {
|
||||||
|
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(conout, 7);
|
||||||
|
|
||||||
|
system("cls");
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleW(conout, &testChar, 1, &actual, NULL);
|
||||||
|
assert(ret && actual == 1);
|
||||||
|
|
||||||
|
CHAR_INFO verify[2];
|
||||||
|
COORD bufSize = {2, 1};
|
||||||
|
COORD bufCoord = {0, 0};
|
||||||
|
const SMALL_RECT readRegion = {0, 0, 1, 0};
|
||||||
|
SMALL_RECT actualRegion = readRegion;
|
||||||
|
ret = ReadConsoleOutputW(conout, verify, bufSize, bufCoord, &actualRegion);
|
||||||
|
assert(ret && !memcmp(&readRegion, &actualRegion, sizeof(readRegion)));
|
||||||
|
assert(verify[0].Char.UnicodeChar == testChar);
|
||||||
|
|
||||||
|
if (verify[1].Char.UnicodeChar == testChar) {
|
||||||
|
// Typical double-width behavior with a TrueType font. Pass.
|
||||||
|
assert(verify[0].Attributes == 0x107);
|
||||||
|
assert(verify[1].Attributes == 0x207);
|
||||||
|
return true;
|
||||||
|
} else if (verify[1].Char.UnicodeChar == 0) {
|
||||||
|
// Typical double-width behavior with a Raster Font. Pass.
|
||||||
|
assert(verify[0].Attributes == 7);
|
||||||
|
assert(verify[1].Attributes == 0);
|
||||||
|
return true;
|
||||||
|
} else if (verify[1].Char.UnicodeChar == L' ') {
|
||||||
|
// Single-width behavior. Fail.
|
||||||
|
assert(verify[0].Attributes == 7);
|
||||||
|
assert(verify[1].Attributes == 7);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// Unexpected output.
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(SetConsoleCP(932));
|
||||||
|
assert(SetConsoleOutputCP(932));
|
||||||
|
|
||||||
|
const wchar_t testChar = 0x30FC;
|
||||||
|
const wchar_t *const faceNames[] = {
|
||||||
|
L"Lucida Console",
|
||||||
|
L"Consolas",
|
||||||
|
L"MS ゴシック",
|
||||||
|
};
|
||||||
|
|
||||||
|
trace("Test started");
|
||||||
|
|
||||||
|
for (auto faceName : faceNames) {
|
||||||
|
for (int px = 1; px <= 50; ++px) {
|
||||||
|
setFont(faceName, px);
|
||||||
|
if (!performTest(testChar)) {
|
||||||
|
trace("FAILURE: %s %dpx", narrowString(faceName).c_str(), px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("Test complete");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+246
@@ -0,0 +1,246 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
|
||||||
|
CHAR_INFO ci(wchar_t ch, WORD attributes) {
|
||||||
|
CHAR_INFO ret;
|
||||||
|
ret.Char.UnicodeChar = ch;
|
||||||
|
ret.Attributes = attributes;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHAR_INFO ci(wchar_t ch) {
|
||||||
|
return ci(ch, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHAR_INFO ci() {
|
||||||
|
return ci(L' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(SMALL_RECT x, SMALL_RECT y) {
|
||||||
|
return !memcmp(&x, &y, sizeof(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
SMALL_RECT sr(COORD pt, COORD size) {
|
||||||
|
return {
|
||||||
|
pt.X, pt.Y,
|
||||||
|
static_cast<SHORT>(pt.X + size.X - 1),
|
||||||
|
static_cast<SHORT>(pt.Y + size.Y - 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set(
|
||||||
|
const COORD pt,
|
||||||
|
const COORD size,
|
||||||
|
const std::vector<CHAR_INFO> &data) {
|
||||||
|
assert(data.size() == size.X * size.Y);
|
||||||
|
SMALL_RECT writeRegion = sr(pt, size);
|
||||||
|
BOOL ret = WriteConsoleOutputW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
data.data(), size, {0, 0}, &writeRegion);
|
||||||
|
assert(ret && writeRegion == sr(pt, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set(
|
||||||
|
const COORD pt,
|
||||||
|
const std::vector<CHAR_INFO> &data) {
|
||||||
|
set(pt, {static_cast<SHORT>(data.size()), 1}, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeAttrsAt(
|
||||||
|
const COORD pt,
|
||||||
|
const std::vector<WORD> &data) {
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleOutputAttribute(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
data.data(), data.size(), pt, &actual);
|
||||||
|
assert(ret && actual == data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeCharsAt(
|
||||||
|
const COORD pt,
|
||||||
|
const std::vector<wchar_t> &data) {
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleOutputCharacterW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
data.data(), data.size(), pt, &actual);
|
||||||
|
assert(ret && actual == data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeChars(
|
||||||
|
const std::vector<wchar_t> &data) {
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
data.data(), data.size(), &actual, NULL);
|
||||||
|
assert(ret && actual == data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CHAR_INFO> get(
|
||||||
|
const COORD pt,
|
||||||
|
const COORD size) {
|
||||||
|
std::vector<CHAR_INFO> data(size.X * size.Y);
|
||||||
|
SMALL_RECT readRegion = sr(pt, size);
|
||||||
|
BOOL ret = ReadConsoleOutputW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
data.data(), size, {0, 0}, &readRegion);
|
||||||
|
assert(ret && readRegion == sr(pt, size));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<wchar_t> readCharsAt(
|
||||||
|
const COORD pt,
|
||||||
|
int size) {
|
||||||
|
std::vector<wchar_t> data(size);
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = ReadConsoleOutputCharacterW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
data.data(), data.size(), pt, &actual);
|
||||||
|
assert(ret);
|
||||||
|
data.resize(actual); // With double-width chars, we can read fewer than `size`.
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump(const COORD pt, const COORD size) {
|
||||||
|
for (CHAR_INFO ci : get(pt, size)) {
|
||||||
|
printf("%04X %04X\n", ci.Char.UnicodeChar, ci.Attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpCharsAt(const COORD pt, int size) {
|
||||||
|
for (wchar_t ch : readCharsAt(pt, size)) {
|
||||||
|
printf("%04X\n", ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static COORD getCursorPos() {
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info = { sizeof(info) };
|
||||||
|
assert(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info));
|
||||||
|
return info.dwCursorPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test1() {
|
||||||
|
// We write "䀀䀀", then write "䀁" in the middle of the two. The second
|
||||||
|
// write turns the first and last cells into spaces. The LEADING/TRAILING
|
||||||
|
// flags retain consistency.
|
||||||
|
printf("test1 - overlap full-width char with full-width char\n");
|
||||||
|
writeCharsAt({1,0}, {0x4000, 0x4000});
|
||||||
|
dump({0,0}, {6,1});
|
||||||
|
printf("\n");
|
||||||
|
writeCharsAt({2,0}, {0x4001});
|
||||||
|
dump({0,0}, {6,1});
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test2() {
|
||||||
|
// Like `test1`, but use a lower-level API to do the write. Consistency is
|
||||||
|
// preserved here too -- the first and last cells are replaced with spaces.
|
||||||
|
printf("test2 - overlap full-width char with full-width char (lowlevel)\n");
|
||||||
|
writeCharsAt({1,0}, {0x4000, 0x4000});
|
||||||
|
dump({0,0}, {6,1});
|
||||||
|
printf("\n");
|
||||||
|
set({2,0}, {ci(0x4001,0x107), ci(0x4001,0x207)});
|
||||||
|
dump({0,0}, {6,1});
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test3() {
|
||||||
|
// However, the lower-level API can break the LEADING/TRAILING invariant
|
||||||
|
// explicitly:
|
||||||
|
printf("test3 - explicitly violate LEADING/TRAILING using lowlevel API\n");
|
||||||
|
set({1,0}, {
|
||||||
|
ci(0x4000, 0x207),
|
||||||
|
ci(0x4001, 0x107),
|
||||||
|
ci(0x3044, 7),
|
||||||
|
ci(L'X', 0x107),
|
||||||
|
ci(L'X', 0x207),
|
||||||
|
});
|
||||||
|
dump({0,0}, {7,1});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test4() {
|
||||||
|
// It is possible for the two cells of a double-width character to have two
|
||||||
|
// colors.
|
||||||
|
printf("test4 - use lowlevel to assign two colors to one full-width char\n");
|
||||||
|
set({0,0}, {
|
||||||
|
ci(0x4000, 0x142),
|
||||||
|
ci(0x4000, 0x224),
|
||||||
|
});
|
||||||
|
dump({0,0}, {2,1});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test5() {
|
||||||
|
// WriteConsoleOutputAttribute doesn't seem to affect the LEADING/TRAILING
|
||||||
|
// flags.
|
||||||
|
printf("test5 - WriteConsoleOutputAttribute cannot affect LEADING/TRAILING\n");
|
||||||
|
|
||||||
|
// Trying to clear the flags doesn't work...
|
||||||
|
writeCharsAt({0,0}, {0x4000});
|
||||||
|
dump({0,0}, {2,1});
|
||||||
|
writeAttrsAt({0,0}, {0x42, 0x24});
|
||||||
|
printf("\n");
|
||||||
|
dump({0,0}, {2,1});
|
||||||
|
|
||||||
|
// ... and trying to add them also doesn't work.
|
||||||
|
writeCharsAt({0,1}, {'A', ' '});
|
||||||
|
writeAttrsAt({0,1}, {0x107, 0x207});
|
||||||
|
printf("\n");
|
||||||
|
dump({0,1}, {2,1});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test6() {
|
||||||
|
// The cursor position may be on either cell of a double-width character.
|
||||||
|
// Visually, the cursor appears under both cells, regardless of which
|
||||||
|
// specific one has the cursor.
|
||||||
|
printf("test6 - cursor can be either left or right cell of full-width char\n");
|
||||||
|
|
||||||
|
writeCharsAt({2,1}, {0x4000});
|
||||||
|
|
||||||
|
setCursorPos(2, 1);
|
||||||
|
auto pos1 = getCursorPos();
|
||||||
|
Sleep(1000);
|
||||||
|
|
||||||
|
setCursorPos(3, 1);
|
||||||
|
auto pos2 = getCursorPos();
|
||||||
|
Sleep(1000);
|
||||||
|
|
||||||
|
setCursorPos(0, 15);
|
||||||
|
printf("%d,%d\n", pos1.X, pos1.Y);
|
||||||
|
printf("%d,%d\n", pos2.X, pos2.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void runTest(void (&test)()) {
|
||||||
|
system("cls");
|
||||||
|
setCursorPos(0, 14);
|
||||||
|
test();
|
||||||
|
system("pause");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(80, 40);
|
||||||
|
setWindowPos(0, 0, 80, 40);
|
||||||
|
|
||||||
|
auto cp = GetConsoleOutputCP();
|
||||||
|
assert(cp == 932 || cp == 936 || cp == 949 || cp == 950);
|
||||||
|
|
||||||
|
runTest(test1);
|
||||||
|
runTest(test2);
|
||||||
|
runTest(test3);
|
||||||
|
runTest(test4);
|
||||||
|
runTest(test5);
|
||||||
|
runTest(test6);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
//
|
||||||
|
// Test half-width vs full-width characters.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
static void writeChars(const wchar_t *text) {
|
||||||
|
wcslen(text);
|
||||||
|
const int len = wcslen(text);
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
text, len, &actual, NULL);
|
||||||
|
trace("writeChars: ret=%d, actual=%lld", ret, (long long)actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpChars(int x, int y, int w, int h) {
|
||||||
|
BOOL ret;
|
||||||
|
const COORD bufSize = {w, h};
|
||||||
|
const COORD bufCoord = {0, 0};
|
||||||
|
const SMALL_RECT topLeft = {x, y, x + w - 1, y + h - 1};
|
||||||
|
CHAR_INFO mbcsData[w * h];
|
||||||
|
CHAR_INFO unicodeData[w * h];
|
||||||
|
SMALL_RECT readRegion;
|
||||||
|
readRegion = topLeft;
|
||||||
|
ret = ReadConsoleOutputW(GetStdHandle(STD_OUTPUT_HANDLE), unicodeData,
|
||||||
|
bufSize, bufCoord, &readRegion);
|
||||||
|
assert(ret);
|
||||||
|
readRegion = topLeft;
|
||||||
|
ret = ReadConsoleOutputA(GetStdHandle(STD_OUTPUT_HANDLE), mbcsData,
|
||||||
|
bufSize, bufCoord, &readRegion);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
for (int i = 0; i < w * h; ++i) {
|
||||||
|
printf("(%02d,%02d) CHAR: %04x %4x -- %02x %4x\n",
|
||||||
|
x + i % w, y + i / w,
|
||||||
|
(unsigned short)unicodeData[i].Char.UnicodeChar,
|
||||||
|
(unsigned short)unicodeData[i].Attributes,
|
||||||
|
(unsigned char)mbcsData[i].Char.AsciiChar,
|
||||||
|
(unsigned short)mbcsData[i].Attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
system("cls");
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(80, 38);
|
||||||
|
setWindowPos(0, 0, 80, 38);
|
||||||
|
|
||||||
|
// Write text.
|
||||||
|
const wchar_t text1[] = {
|
||||||
|
0x3044, // U+3044 (HIRAGANA LETTER I)
|
||||||
|
0x2014, // U+2014 (EM DASH)
|
||||||
|
0x3044, // U+3044 (HIRAGANA LETTER I)
|
||||||
|
0xFF2D, // U+FF2D (FULLWIDTH LATIN CAPITAL LETTER M)
|
||||||
|
0x30FC, // U+30FC (KATAKANA-HIRAGANA PROLONGED SOUND MARK)
|
||||||
|
0x0031, // U+3031 (DIGIT ONE)
|
||||||
|
0x2014, // U+2014 (EM DASH)
|
||||||
|
0x0032, // U+0032 (DIGIT TWO)
|
||||||
|
0x005C, // U+005C (REVERSE SOLIDUS)
|
||||||
|
0x3044, // U+3044 (HIRAGANA LETTER I)
|
||||||
|
0
|
||||||
|
};
|
||||||
|
setCursorPos(0, 0);
|
||||||
|
writeChars(text1);
|
||||||
|
|
||||||
|
setCursorPos(78, 1);
|
||||||
|
writeChars(L"<>");
|
||||||
|
|
||||||
|
const wchar_t text2[] = {
|
||||||
|
0x0032, // U+3032 (DIGIT TWO)
|
||||||
|
0x3044, // U+3044 (HIRAGANA LETTER I)
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
setCursorPos(78, 1);
|
||||||
|
writeChars(text2);
|
||||||
|
|
||||||
|
system("pause");
|
||||||
|
|
||||||
|
dumpChars(0, 0, 17, 1);
|
||||||
|
dumpChars(2, 0, 2, 1);
|
||||||
|
dumpChars(2, 0, 1, 1);
|
||||||
|
dumpChars(3, 0, 1, 1);
|
||||||
|
dumpChars(78, 1, 2, 1);
|
||||||
|
dumpChars(0, 2, 2, 1);
|
||||||
|
|
||||||
|
system("pause");
|
||||||
|
system("cls");
|
||||||
|
|
||||||
|
const wchar_t text3[] = {
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 1
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 2
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 3
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 4
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 5
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 6
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 7
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 8
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 9
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 10
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 11
|
||||||
|
0x30FC, 0x30FC, 0x30FC, 0xFF2D, // 12
|
||||||
|
L'\r', '\n',
|
||||||
|
L'\r', '\n',
|
||||||
|
0
|
||||||
|
};
|
||||||
|
writeChars(text3);
|
||||||
|
system("pause");
|
||||||
|
{
|
||||||
|
const COORD bufSize = {80, 2};
|
||||||
|
const COORD bufCoord = {0, 0};
|
||||||
|
SMALL_RECT readRegion = {0, 0, 79, 1};
|
||||||
|
CHAR_INFO unicodeData[160];
|
||||||
|
BOOL ret = ReadConsoleOutputW(GetStdHandle(STD_OUTPUT_HANDLE), unicodeData,
|
||||||
|
bufSize, bufCoord, &readRegion);
|
||||||
|
assert(ret);
|
||||||
|
for (int i = 0; i < 96; ++i) {
|
||||||
|
printf("%04x ", unicodeData[i].Char.UnicodeChar);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Unix test code that puts the terminal into raw mode, then echos typed
|
||||||
|
* characters to stdout. Derived from sample code in the Stevens book, posted
|
||||||
|
* online at http://www.lafn.org/~dave/linux/terminalIO.html.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "FormatChar.h"
|
||||||
|
|
||||||
|
static struct termios save_termios;
|
||||||
|
static int term_saved;
|
||||||
|
|
||||||
|
/* RAW! mode */
|
||||||
|
int tty_raw(int fd)
|
||||||
|
{
|
||||||
|
struct termios buf;
|
||||||
|
|
||||||
|
if (tcgetattr(fd, &save_termios) < 0) /* get the original state */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buf = save_termios;
|
||||||
|
|
||||||
|
/* echo off, canonical mode off, extended input
|
||||||
|
processing off, signal chars off */
|
||||||
|
buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||||
|
|
||||||
|
/* no SIGINT on BREAK, CR-to-NL off, input parity
|
||||||
|
check off, don't strip the 8th bit on input,
|
||||||
|
ouput flow control off */
|
||||||
|
buf.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON);
|
||||||
|
|
||||||
|
/* clear size bits, parity checking off */
|
||||||
|
buf.c_cflag &= ~(CSIZE | PARENB);
|
||||||
|
|
||||||
|
/* set 8 bits/char */
|
||||||
|
buf.c_cflag |= CS8;
|
||||||
|
|
||||||
|
/* output processing off */
|
||||||
|
buf.c_oflag &= ~(OPOST);
|
||||||
|
|
||||||
|
buf.c_cc[VMIN] = 1; /* 1 byte at a time */
|
||||||
|
buf.c_cc[VTIME] = 0; /* no timer on input */
|
||||||
|
|
||||||
|
if (tcsetattr(fd, TCSAFLUSH, &buf) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
term_saved = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* set it to normal! */
|
||||||
|
int tty_reset(int fd)
|
||||||
|
{
|
||||||
|
if (term_saved)
|
||||||
|
if (tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
tty_raw(0);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
while (true) {
|
||||||
|
char ch;
|
||||||
|
char buf[16];
|
||||||
|
int actual = read(0, &ch, 1);
|
||||||
|
if (actual != 1) {
|
||||||
|
perror("read error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
formatChar(buf, ch);
|
||||||
|
fputs(buf, stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
if (ch == 3) // Ctrl-C
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_reset(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
system("cls");
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
printf("Usage: %s hhhh\n", argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring dataToWrite;
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
wchar_t ch = strtol(argv[i], NULL, 16);
|
||||||
|
dataToWrite.push_back(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD actual = 0;
|
||||||
|
BOOL ret = WriteConsoleW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
dataToWrite.data(), dataToWrite.size(), &actual, NULL);
|
||||||
|
assert(ret && actual == dataToWrite.size());
|
||||||
|
|
||||||
|
// Read it back.
|
||||||
|
std::vector<CHAR_INFO> readBuffer(dataToWrite.size() * 2);
|
||||||
|
COORD bufSize = {static_cast<short>(readBuffer.size()), 1};
|
||||||
|
COORD bufCoord = {0, 0};
|
||||||
|
SMALL_RECT topLeft = {0, 0, static_cast<short>(readBuffer.size() - 1), 0};
|
||||||
|
ret = ReadConsoleOutputW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE), readBuffer.data(),
|
||||||
|
bufSize, bufCoord, &topLeft);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
for (int i = 0; i < readBuffer.size(); ++i) {
|
||||||
|
printf("CHAR: %04x %04x\n",
|
||||||
|
readBuffer[i].Char.UnicodeChar,
|
||||||
|
readBuffer[i].Attributes);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
//
|
||||||
|
// 2015-09-25
|
||||||
|
// I measured these limits on the size of a single ReadConsoleOutputW call.
|
||||||
|
// The limit seems to more-or-less disppear with Windows 8, which is the first
|
||||||
|
// OS to stop using ALPCs for console I/O. My guess is that the new I/O
|
||||||
|
// method does not use the 64KiB shared memory buffer that the ALPC method
|
||||||
|
// uses.
|
||||||
|
//
|
||||||
|
// I'm guessing the remaining difference between Windows 8/8.1 and Windows 10
|
||||||
|
// might be related to the 32-vs-64-bitness.
|
||||||
|
//
|
||||||
|
// Client OSs
|
||||||
|
//
|
||||||
|
// Windows XP 32-bit VM ==> up to 13304 characters
|
||||||
|
// - 13304x1 works, but 13305x1 fails instantly
|
||||||
|
// Windows 7 32-bit VM ==> between 16-17 thousand characters
|
||||||
|
// - 16000x1 works, 17000x1 fails instantly
|
||||||
|
// - 163x100 *crashes* conhost.exe but leaves VeryLargeRead.exe running
|
||||||
|
// Windows 8 32-bit VM ==> between 240-250 million characters
|
||||||
|
// - 10000x24000 works, but 10000x25000 does not
|
||||||
|
// Windows 8.1 32-bit VM ==> between 240-250 million characters
|
||||||
|
// - 10000x24000 works, but 10000x25000 does not
|
||||||
|
// Windows 10 64-bit VM ==> no limit (tested to 576 million characters)
|
||||||
|
// - 24000x24000 works
|
||||||
|
// - `ver` reports [Version 10.0.10240], conhost.exe and ConhostV1.dll are
|
||||||
|
// 10.0.10240.16384 for file and product version. ConhostV2.dll is
|
||||||
|
// 10.0.10240.16391 for file and product version.
|
||||||
|
//
|
||||||
|
// Server OSs
|
||||||
|
//
|
||||||
|
// Windows Server 2008 64-bit VM ==> 14300-14400 characters
|
||||||
|
// - 14300x1 works, 14400x1 fails instantly
|
||||||
|
// - This OS does not have conhost.exe.
|
||||||
|
// - `ver` reports [Version 6.0.6002]
|
||||||
|
// Windows Server 2008 R2 64-bit VM ==> 15600-15700 characters
|
||||||
|
// - 15600x1 works, 15700x1 fails instantly
|
||||||
|
// - This OS has conhost.exe, and procexp.exe reveals console ALPC ports in
|
||||||
|
// use in conhost.exe.
|
||||||
|
// - `ver` reports [Version 6.1.7601], conhost.exe is 6.1.7601.23153 for file
|
||||||
|
// and product version.
|
||||||
|
// Windows Server 2012 64-bit VM ==> at least 100 million characters
|
||||||
|
// - 10000x10000 works (VM had only 1GiB of RAM, so I skipped larger tests)
|
||||||
|
// - This OS has Windows 8's task manager and procexp.exe reveals the same
|
||||||
|
// lack of ALPC ports and the same \Device\ConDrv\* files as Windows 8.
|
||||||
|
// - `ver` reports [Version 6.2.9200], conhost.exe is 6.2.9200.16579 for file
|
||||||
|
// and product version.
|
||||||
|
//
|
||||||
|
// To summarize:
|
||||||
|
//
|
||||||
|
// client-OS server-OS notes
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// XP Server 2008 CSRSS, small reads
|
||||||
|
// 7 Server 2008 R2 ALPC-to-conhost, small reads
|
||||||
|
// 8, 8.1 Server 2012 new I/O interface, large reads allowed
|
||||||
|
// 10 <no server OS yet> enhanced console w/rewrapping
|
||||||
|
//
|
||||||
|
// (Presumably, Win2K, Vista, and Win2K3 behave the same as XP. conhost.exe
|
||||||
|
// was announced as a Win7 feature.)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
long long width = 9000;
|
||||||
|
long long height = 9000;
|
||||||
|
|
||||||
|
assert(argc >= 1);
|
||||||
|
if (argc == 4) {
|
||||||
|
width = atoi(argv[2]);
|
||||||
|
height = atoi(argv[3]);
|
||||||
|
} else {
|
||||||
|
if (argc == 3) {
|
||||||
|
width = atoi(argv[1]);
|
||||||
|
height = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
wchar_t args[1024];
|
||||||
|
swprintf(args, 1024, L"CHILD %lld %lld", width, height);
|
||||||
|
startChildProcess(args);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(width, height);
|
||||||
|
setWindowPos(0, 0, std::min(80LL, width), std::min(50LL, height));
|
||||||
|
|
||||||
|
setCursorPos(0, 0);
|
||||||
|
printf("A");
|
||||||
|
fflush(stdout);
|
||||||
|
setCursorPos(width - 2, height - 1);
|
||||||
|
printf("B");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
trace("sizeof(CHAR_INFO) = %d", (int)sizeof(CHAR_INFO));
|
||||||
|
|
||||||
|
trace("Allocating buffer...");
|
||||||
|
CHAR_INFO *buffer = new CHAR_INFO[width * height];
|
||||||
|
assert(buffer != NULL);
|
||||||
|
memset(&buffer[0], 0, sizeof(CHAR_INFO));
|
||||||
|
memset(&buffer[width * height - 2], 0, sizeof(CHAR_INFO));
|
||||||
|
|
||||||
|
COORD bufSize = { width, height };
|
||||||
|
COORD bufCoord = { 0, 0 };
|
||||||
|
SMALL_RECT readRegion = { 0, 0, width - 1, height - 1 };
|
||||||
|
trace("ReadConsoleOutputW: calling...");
|
||||||
|
BOOL success = ReadConsoleOutputW(conout, buffer, bufSize, bufCoord, &readRegion);
|
||||||
|
trace("ReadConsoleOutputW: success=%d", success);
|
||||||
|
|
||||||
|
assert(buffer[0].Char.UnicodeChar == L'A');
|
||||||
|
assert(buffer[width * height - 2].Char.UnicodeChar == L'B');
|
||||||
|
trace("Top-left and bottom-right characters read successfully!");
|
||||||
|
|
||||||
|
Sleep(30000);
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Sending VK_PAUSE to the console window almost works as a mechanism for
|
||||||
|
* pausing it, but it doesn't because the console could turn off the
|
||||||
|
* ENABLE_LINE_INPUT console mode flag.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
CALLBACK DWORD pausingThread(LPVOID dummy)
|
||||||
|
{
|
||||||
|
if (1) {
|
||||||
|
Sleep(1000);
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
SendMessage(hwnd, WM_KEYDOWN, VK_PAUSE, 1);
|
||||||
|
Sleep(1000);
|
||||||
|
SendMessage(hwnd, WM_KEYDOWN, VK_ESCAPE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
INPUT_RECORD ir;
|
||||||
|
memset(&ir, 0, sizeof(ir));
|
||||||
|
ir.EventType = KEY_EVENT;
|
||||||
|
ir.Event.KeyEvent.bKeyDown = TRUE;
|
||||||
|
ir.Event.KeyEvent.wVirtualKeyCode = VK_PAUSE;
|
||||||
|
ir.Event.KeyEvent.wRepeatCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
COORD c = { 0, 0 };
|
||||||
|
|
||||||
|
DWORD mode;
|
||||||
|
GetConsoleMode(hin, &mode);
|
||||||
|
SetConsoleMode(hin, mode &
|
||||||
|
~(ENABLE_LINE_INPUT));
|
||||||
|
|
||||||
|
CreateThread(NULL, 0,
|
||||||
|
pausingThread, NULL,
|
||||||
|
0, NULL);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (true) {
|
||||||
|
Sleep(100);
|
||||||
|
printf("%d\n", ++i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Generated
Vendored
+52
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Demonstrates a conhost hang that occurs when widening the console buffer
|
||||||
|
* while selection is in progress. The problem affects the new Windows 10
|
||||||
|
* console, not the "legacy" console mode that Windows 10 also includes.
|
||||||
|
*
|
||||||
|
* First tested with:
|
||||||
|
* - Windows 10.0.10240
|
||||||
|
* - conhost.exe version 10.0.10240.16384
|
||||||
|
* - ConhostV1.dll version 10.0.10240.16384
|
||||||
|
* - ConhostV2.dll version 10.0.10240.16391
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
const int SC_CONSOLE_SELECT_ALL = 0xFFF5;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(80, 25);
|
||||||
|
setWindowPos(0, 0, 80, 25);
|
||||||
|
|
||||||
|
countDown(5);
|
||||||
|
|
||||||
|
SendMessage(GetConsoleWindow(), WM_SYSCOMMAND, SC_CONSOLE_SELECT_ALL, 0);
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
// This API call does not return. In the console window, the "Select All"
|
||||||
|
// operation appears to end. The console window becomes non-responsive,
|
||||||
|
// and the conhost.exe process must be killed from the Task Manager.
|
||||||
|
// (Killing this test program or closing the console window is not
|
||||||
|
// sufficient.)
|
||||||
|
//
|
||||||
|
// The same hang occurs whether line resizing is off or on. It happens
|
||||||
|
// with both "Mark" and "Select All". Calling setBufferSize with the
|
||||||
|
// existing buffer size does not hang, but calling it with only a changed
|
||||||
|
// buffer height *does* hang. Calling setWindowPos does not hang.
|
||||||
|
setBufferSize(120, 25);
|
||||||
|
|
||||||
|
printf("Done...\n");
|
||||||
|
Sleep(2000);
|
||||||
|
}
|
||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Demonstrates some wrapping behaviors of the new Windows 10 console.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(40, 20);
|
||||||
|
setWindowPos(0, 0, 40, 20);
|
||||||
|
|
||||||
|
system("cls");
|
||||||
|
|
||||||
|
repeatChar(39, 'A'); repeatChar(1, ' ');
|
||||||
|
repeatChar(39, 'B'); repeatChar(1, ' ');
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
repeatChar(39, 'C'); repeatChar(1, ' ');
|
||||||
|
repeatChar(39, 'D'); repeatChar(1, ' ');
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
repeatChar(40, 'E');
|
||||||
|
repeatChar(40, 'F');
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
repeatChar(39, 'G'); repeatChar(1, ' ');
|
||||||
|
repeatChar(39, 'H'); repeatChar(1, ' ');
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
setChar(39, 0, '*', 0x24);
|
||||||
|
setChar(39, 1, '*', 0x24);
|
||||||
|
|
||||||
|
setChar(39, 3, ' ', 0x24);
|
||||||
|
setChar(39, 4, ' ', 0x24);
|
||||||
|
|
||||||
|
setChar(38, 6, ' ', 0x24);
|
||||||
|
setChar(38, 7, ' ', 0x24);
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
setWindowPos(0, 0, 35, 20);
|
||||||
|
setBufferSize(35, 20);
|
||||||
|
trace("DONE");
|
||||||
|
|
||||||
|
printf("Sleeping forever...\n");
|
||||||
|
while(true) { Sleep(1000); }
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc == 1) {
|
||||||
|
startChildProcess(L"CHILD");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int WIDTH = 25;
|
||||||
|
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(WIDTH, 40);
|
||||||
|
setWindowPos(0, 0, WIDTH, 20);
|
||||||
|
|
||||||
|
system("cls");
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; ++i) {
|
||||||
|
printf("FOO(%d)\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
repeatChar(5, '\n');
|
||||||
|
repeatChar(WIDTH * 5, '.');
|
||||||
|
repeatChar(10, '\n');
|
||||||
|
setWindowPos(0, 20, WIDTH, 20);
|
||||||
|
writeBox(0, 5, 1, 10, '|');
|
||||||
|
|
||||||
|
Sleep(120000);
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* A Win32 program that reads raw console input with ReadFile and echos
|
||||||
|
* it to stdout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
SetConsoleMode(hStdIn, 0);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
DWORD actual;
|
||||||
|
char ch;
|
||||||
|
ReadFile(hStdIn, &ch, 1, &actual, NULL);
|
||||||
|
printf("%02x ", ch);
|
||||||
|
if (++count == 50)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* A Win32 program that reads raw console input with getch and echos
|
||||||
|
* it to stdout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
while (true) {
|
||||||
|
int ch = getch();
|
||||||
|
printf("%02x ", ch);
|
||||||
|
if (++count == 50)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#include "../src/shared/DebugClient.cc"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
|
||||||
|
CALLBACK DWORD writerThread(void*)
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
Sleep(1000);
|
||||||
|
trace("writing");
|
||||||
|
printf("X\n");
|
||||||
|
trace("written");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CreateThread(NULL, 0, writerThread, NULL, 0, NULL);
|
||||||
|
trace("marking console");
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
PostMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0);
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
trace("reading output");
|
||||||
|
CHAR_INFO buf[1];
|
||||||
|
COORD bufSize = { 1, 1 };
|
||||||
|
COORD zeroCoord = { 0, 0 };
|
||||||
|
SMALL_RECT readRect = { 0, 0, 0, 0 };
|
||||||
|
ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
buf,
|
||||||
|
bufSize,
|
||||||
|
zeroCoord,
|
||||||
|
&readRect);
|
||||||
|
trace("done reading output");
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
PostMessage(hwnd, WM_CHAR, 27, 0x00010001);
|
||||||
|
|
||||||
|
Sleep(1100);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* This test demonstrates that putting a console into selection mode does not
|
||||||
|
* block the low-level console APIs, even though it blocks WriteFile.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#include "../src/shared/DebugClient.cc"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const int SC_CONSOLE_MARK = 0xFFF2;
|
||||||
|
|
||||||
|
CALLBACK DWORD writerThread(void*)
|
||||||
|
{
|
||||||
|
CHAR_INFO xChar, fillChar;
|
||||||
|
memset(&xChar, 0, sizeof(xChar));
|
||||||
|
xChar.Char.AsciiChar = 'X';
|
||||||
|
xChar.Attributes = 7;
|
||||||
|
memset(&fillChar, 0, sizeof(fillChar));
|
||||||
|
fillChar.Char.AsciiChar = ' ';
|
||||||
|
fillChar.Attributes = 7;
|
||||||
|
COORD oneCoord = { 1, 1 };
|
||||||
|
COORD zeroCoord = { 0, 0 };
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
SMALL_RECT writeRegion = { 5, 5, 5, 5 };
|
||||||
|
WriteConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
&xChar, oneCoord,
|
||||||
|
zeroCoord,
|
||||||
|
&writeRegion);
|
||||||
|
Sleep(500);
|
||||||
|
SMALL_RECT scrollRect = { 1, 1, 20, 20 };
|
||||||
|
COORD destCoord = { 0, 0 };
|
||||||
|
ScrollConsoleScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
&scrollRect,
|
||||||
|
NULL,
|
||||||
|
destCoord,
|
||||||
|
&fillChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CreateThread(NULL, 0, writerThread, NULL, 0, NULL);
|
||||||
|
trace("marking console");
|
||||||
|
HWND hwnd = GetConsoleWindow();
|
||||||
|
PostMessage(hwnd, WM_SYSCOMMAND, SC_CONSOLE_MARK, 0);
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
trace("reading output");
|
||||||
|
CHAR_INFO buf[1];
|
||||||
|
COORD bufSize = { 1, 1 };
|
||||||
|
COORD zeroCoord = { 0, 0 };
|
||||||
|
SMALL_RECT readRect = { 0, 0, 0, 0 };
|
||||||
|
ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
buf,
|
||||||
|
bufSize,
|
||||||
|
zeroCoord,
|
||||||
|
&readRect);
|
||||||
|
trace("done reading output");
|
||||||
|
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
|
PostMessage(hwnd, WM_CHAR, 27, 0x00010001);
|
||||||
|
|
||||||
|
Sleep(1100);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Creates a window station and starts a process under it. The new process
|
||||||
|
* also gets a new console.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOL success;
|
||||||
|
|
||||||
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
|
||||||
|
HWINSTA originalStation = GetProcessWindowStation();
|
||||||
|
printf("originalStation == 0x%x\n", originalStation);
|
||||||
|
HWINSTA station = CreateWindowStation(NULL,
|
||||||
|
0,
|
||||||
|
WINSTA_ALL_ACCESS,
|
||||||
|
&sa);
|
||||||
|
printf("station == 0x%x\n", station);
|
||||||
|
if (!SetProcessWindowStation(station))
|
||||||
|
printf("SetWindowStation failed!\n");
|
||||||
|
HDESK desktop = CreateDesktop("Default", NULL, NULL,
|
||||||
|
/*dwFlags=*/0, GENERIC_ALL,
|
||||||
|
&sa);
|
||||||
|
printf("desktop = 0x%x\n", desktop);
|
||||||
|
|
||||||
|
char stationName[256];
|
||||||
|
stationName[0] = '\0';
|
||||||
|
success = GetUserObjectInformation(station, UOI_NAME,
|
||||||
|
stationName, sizeof(stationName),
|
||||||
|
NULL);
|
||||||
|
printf("stationName = [%s]\n", stationName);
|
||||||
|
|
||||||
|
char startupDesktop[256];
|
||||||
|
sprintf(startupDesktop, "%s\\Default", stationName);
|
||||||
|
|
||||||
|
STARTUPINFO sui;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
memset(&sui, 0, sizeof(sui));
|
||||||
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
sui.cb = sizeof(STARTUPINFO);
|
||||||
|
sui.lpDesktop = startupDesktop;
|
||||||
|
|
||||||
|
// Start a cmd subprocess, and have it start its own cmd subprocess.
|
||||||
|
// Both subprocesses will connect to the same non-interactive window
|
||||||
|
// station.
|
||||||
|
|
||||||
|
const char program[] = "c:\\windows\\system32\\cmd.exe";
|
||||||
|
char cmdline[256];
|
||||||
|
sprintf(cmdline, "%s /c cmd", program);
|
||||||
|
success = CreateProcess(program,
|
||||||
|
cmdline,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
/*bInheritHandles=*/FALSE,
|
||||||
|
/*dwCreationFlags=*/CREATE_NEW_CONSOLE,
|
||||||
|
NULL, NULL,
|
||||||
|
&sui,
|
||||||
|
&pi);
|
||||||
|
|
||||||
|
printf("pid == %d\n", pi.dwProcessId);
|
||||||
|
|
||||||
|
// This sleep is necessary. We must give the child enough time to
|
||||||
|
// connect to the specified window station.
|
||||||
|
Sleep(5000);
|
||||||
|
|
||||||
|
SetProcessWindowStation(originalStation);
|
||||||
|
CloseWindowStation(station);
|
||||||
|
CloseDesktop(desktop);
|
||||||
|
Sleep(5000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* A Win32 program that scrolls and writes to the console using the ioctl-like
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
for (int i = 0; i < 80; ++i) {
|
||||||
|
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
GetConsoleScreenBufferInfo(conout, &info);
|
||||||
|
|
||||||
|
SMALL_RECT src = { 0, 1, info.dwSize.X - 1, info.dwSize.Y - 1 };
|
||||||
|
COORD destOrigin = { 0, 0 };
|
||||||
|
CHAR_INFO fillCharInfo = { 0 };
|
||||||
|
fillCharInfo.Char.AsciiChar = ' ';
|
||||||
|
fillCharInfo.Attributes = 7;
|
||||||
|
ScrollConsoleScreenBuffer(conout,
|
||||||
|
&src,
|
||||||
|
NULL,
|
||||||
|
destOrigin,
|
||||||
|
&fillCharInfo);
|
||||||
|
|
||||||
|
CHAR_INFO buffer = { 0 };
|
||||||
|
buffer.Char.AsciiChar = 'X';
|
||||||
|
buffer.Attributes = 7;
|
||||||
|
COORD bufferSize = { 1, 1 };
|
||||||
|
COORD bufferCoord = { 0, 0 };
|
||||||
|
SMALL_RECT writeRegion = { 0, 0, 0, 0 };
|
||||||
|
writeRegion.Left = writeRegion.Right = i;
|
||||||
|
writeRegion.Top = writeRegion.Bottom = 5;
|
||||||
|
WriteConsoleOutput(conout,
|
||||||
|
&buffer, bufferSize, bufferCoord,
|
||||||
|
&writeRegion);
|
||||||
|
|
||||||
|
Sleep(250);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Generated
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// I noticed this on the ConEmu web site:
|
||||||
|
//
|
||||||
|
// https://social.msdn.microsoft.com/Forums/en-US/40c8e395-cca9-45c8-b9b8-2fbe6782ac2b/readconsoleoutput-cause-access-violation-writing-location-exception
|
||||||
|
// https://conemu.github.io/en/MicrosoftBugs.html
|
||||||
|
//
|
||||||
|
// In Windows 7, 8, and 8.1, a ReadConsoleOutputW with an out-of-bounds read
|
||||||
|
// region crashes the application. I have reproduced the problem on Windows 8
|
||||||
|
// and 8.1, but not on Windows 7.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
setWindowPos(0, 0, 1, 1);
|
||||||
|
setBufferSize(80, 25);
|
||||||
|
setWindowPos(0, 0, 80, 25);
|
||||||
|
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
static CHAR_INFO lineBuf[80];
|
||||||
|
SMALL_RECT readRegion = { 0, 999, 79, 999 };
|
||||||
|
const BOOL ret = ReadConsoleOutputW(conout, lineBuf, {80, 1}, {0, 0}, &readRegion);
|
||||||
|
ASSERT(!ret && "ReadConsoleOutputW should have failed");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
static std::wstring mbsToWcs(const std::string &s) {
|
||||||
|
const size_t len = mbstowcs(nullptr, s.c_str(), 0);
|
||||||
|
if (len == static_cast<size_t>(-1)) {
|
||||||
|
assert(false && "mbsToWcs: invalid string");
|
||||||
|
}
|
||||||
|
std::wstring ret;
|
||||||
|
ret.resize(len);
|
||||||
|
const size_t len2 = mbstowcs(&ret[0], s.c_str(), len);
|
||||||
|
assert(len == len2);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t parseHex(wchar_t ch, bool &invalid) {
|
||||||
|
if (ch >= L'0' && ch <= L'9') {
|
||||||
|
return ch - L'0';
|
||||||
|
} else if (ch >= L'a' && ch <= L'f') {
|
||||||
|
return ch - L'a' + 10;
|
||||||
|
} else if (ch >= L'A' && ch <= L'F') {
|
||||||
|
return ch - L'A' + 10;
|
||||||
|
} else {
|
||||||
|
invalid = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
std::vector<std::wstring> args;
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
args.push_back(mbsToWcs(argv[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring out;
|
||||||
|
for (const auto &arg : args) {
|
||||||
|
if (!out.empty()) {
|
||||||
|
out.push_back(L' ');
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < arg.size(); ++i) {
|
||||||
|
wchar_t ch = arg[i];
|
||||||
|
wchar_t nch = i + 1 < arg.size() ? arg[i + 1] : L'\0';
|
||||||
|
if (ch == L'\\') {
|
||||||
|
switch (nch) {
|
||||||
|
case L'a': ch = L'\a'; ++i; break;
|
||||||
|
case L'b': ch = L'\b'; ++i; break;
|
||||||
|
case L'e': ch = L'\x1b'; ++i; break;
|
||||||
|
case L'f': ch = L'\f'; ++i; break;
|
||||||
|
case L'n': ch = L'\n'; ++i; break;
|
||||||
|
case L'r': ch = L'\r'; ++i; break;
|
||||||
|
case L't': ch = L'\t'; ++i; break;
|
||||||
|
case L'v': ch = L'\v'; ++i; break;
|
||||||
|
case L'\\': ch = L'\\'; ++i; break;
|
||||||
|
case L'\'': ch = L'\''; ++i; break;
|
||||||
|
case L'\"': ch = L'\"'; ++i; break;
|
||||||
|
case L'\?': ch = L'\?'; ++i; break;
|
||||||
|
case L'x':
|
||||||
|
if (i + 3 < arg.size()) {
|
||||||
|
bool invalid = false;
|
||||||
|
uint32_t d1 = parseHex(arg[i + 2], invalid);
|
||||||
|
uint32_t d2 = parseHex(arg[i + 3], invalid);
|
||||||
|
if (!invalid) {
|
||||||
|
i += 3;
|
||||||
|
ch = (d1 << 4) | d2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case L'u':
|
||||||
|
if (i + 5 < arg.size()) {
|
||||||
|
bool invalid = false;
|
||||||
|
uint32_t d1 = parseHex(arg[i + 2], invalid);
|
||||||
|
uint32_t d2 = parseHex(arg[i + 3], invalid);
|
||||||
|
uint32_t d3 = parseHex(arg[i + 4], invalid);
|
||||||
|
uint32_t d4 = parseHex(arg[i + 5], invalid);
|
||||||
|
if (!invalid) {
|
||||||
|
i += 5;
|
||||||
|
ch = (d1 << 24) | (d2 << 16) | (d3 << 8) | d4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.push_back(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD actual = 0;
|
||||||
|
if (!WriteConsoleW(
|
||||||
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||||
|
out.c_str(),
|
||||||
|
out.size(),
|
||||||
|
&actual,
|
||||||
|
nullptr)) {
|
||||||
|
fprintf(stderr, "WriteConsole failed (is stdout a console?)\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
name=$1
|
||||||
|
name=${name%.}
|
||||||
|
name=${name%.cc}
|
||||||
|
name=${name%.exe}
|
||||||
|
echo Compiling $name.cc to $name.exe
|
||||||
|
i686-w64-mingw32-g++.exe -static -std=c++11 $name.cc -o $name.exe
|
||||||
|
i686-w64-mingw32-strip $name.exe
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
name=$1
|
||||||
|
name=${name%.}
|
||||||
|
name=${name%.cc}
|
||||||
|
name=${name%.exe}
|
||||||
|
echo Compiling $name.cc to $name.exe
|
||||||
|
x86_64-w64-mingw32-g++.exe -static -std=c++11 $name.cc -o $name.exe
|
||||||
|
x86_64-w64-mingw32-strip $name.exe
|
||||||
+212
@@ -0,0 +1,212 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
FORE=$1
|
||||||
|
BACK=$2
|
||||||
|
FILL=$3
|
||||||
|
|
||||||
|
if [ "$FORE" = "" ]; then
|
||||||
|
FORE=DefaultFore
|
||||||
|
fi
|
||||||
|
if [ "$BACK" = "" ]; then
|
||||||
|
BACK=DefaultBack
|
||||||
|
fi
|
||||||
|
|
||||||
|
# To detect color changes, we want a character that fills the whole cell
|
||||||
|
# if possible. U+2588 is perfect, except that it becomes invisible in the
|
||||||
|
# original xterm, when bolded. For that terminal, use something else, like
|
||||||
|
# "#" or "@".
|
||||||
|
if [ "$FILL" = "" ]; then
|
||||||
|
FILL="█"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SGR (Select Graphic Rendition)
|
||||||
|
s() {
|
||||||
|
printf '\033[0m'
|
||||||
|
while [ "$1" != "" ]; do
|
||||||
|
printf '\033['"$1"'m'
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print
|
||||||
|
p() {
|
||||||
|
echo -n "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print with newline
|
||||||
|
pn() {
|
||||||
|
echo "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# For practical reasons, sandwich black and white in-between the other colors.
|
||||||
|
FORE_COLORS="31 30 37 32 33 34 35 36"
|
||||||
|
BACK_COLORS="41 40 47 42 43 44 45 46"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Test order of Invert(7) -- it does not matter what order it appears in.
|
||||||
|
|
||||||
|
# The Red color setting here (31) is shadowed by the green setting (32). The
|
||||||
|
# Reverse flag does not cause (32) to alter the background color immediately;
|
||||||
|
# instead, the Reverse flag is applied once to determine the final effective
|
||||||
|
# Fore/Back colors.
|
||||||
|
s 7 31 32; p " -- Should be: $BACK-on-green -- "; s; pn
|
||||||
|
s 31 7 32; p " -- Should be: $BACK-on-green -- "; s; pn
|
||||||
|
s 31 32 7; p " -- Should be: $BACK-on-green -- "; s; pn
|
||||||
|
|
||||||
|
# As above, but for the background color.
|
||||||
|
s 7 41 42; p " -- Should be: green-on-$FORE -- "; s; pn
|
||||||
|
s 41 7 42; p " -- Should be: green-on-$FORE -- "; s; pn
|
||||||
|
s 41 42 7; p " -- Should be: green-on-$FORE -- "; s; pn
|
||||||
|
|
||||||
|
# One last, related test
|
||||||
|
s 7; p "Invert text"; s 7 1; p " with some words bold"; s; pn;
|
||||||
|
s 0; p "Normal text"; s 0 1; p " with some words bold"; s; pn;
|
||||||
|
|
||||||
|
pn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Test effect of Bold(1) on color, with and without Invert(7).
|
||||||
|
|
||||||
|
# The Bold flag does not affect the background color when Reverse is missing.
|
||||||
|
# There should always be 8 colored boxes.
|
||||||
|
p " "
|
||||||
|
for x in $BACK_COLORS; do
|
||||||
|
s $x; p "-"; s $x 1; p "-"
|
||||||
|
done
|
||||||
|
s; pn " Bold should not affect background"
|
||||||
|
|
||||||
|
# On some terminals, Bold affects color, and on some it doesn't. If there
|
||||||
|
# are only 8 colored boxes, then the next two tests will also show 8 colored
|
||||||
|
# boxes. If there are 16 boxes, then exactly one of the next two tests will
|
||||||
|
# also have 16 boxes.
|
||||||
|
p " "
|
||||||
|
for x in $FORE_COLORS; do
|
||||||
|
s $x; p "$FILL"; s $x 1; p "$FILL"
|
||||||
|
done
|
||||||
|
s; pn " Does bold affect foreground color?"
|
||||||
|
|
||||||
|
# On some terminals, Bold+Invert highlights the final Background color.
|
||||||
|
p " "
|
||||||
|
for x in $FORE_COLORS; do
|
||||||
|
s $x 7; p "-"; s $x 7 1; p "-"
|
||||||
|
done
|
||||||
|
s; pn " Test if Bold+Invert affects background color"
|
||||||
|
|
||||||
|
# On some terminals, Bold+Invert highlights the final Foreground color.
|
||||||
|
p " "
|
||||||
|
for x in $BACK_COLORS; do
|
||||||
|
s $x 7; p "$FILL"; s $x 7 1; p "$FILL"
|
||||||
|
done
|
||||||
|
s; pn " Test if Bold+Invert affects foreground color"
|
||||||
|
|
||||||
|
pn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Test for support of ForeHi and BackHi properties.
|
||||||
|
|
||||||
|
# ForeHi
|
||||||
|
p " "
|
||||||
|
for x in $FORE_COLORS; do
|
||||||
|
hi=$(( $x + 60 ))
|
||||||
|
s $x; p "$FILL"; s $hi; p "$FILL"
|
||||||
|
done
|
||||||
|
s; pn " Test for support of ForeHi colors"
|
||||||
|
p " "
|
||||||
|
for x in $FORE_COLORS; do
|
||||||
|
hi=$(( $x + 60 ))
|
||||||
|
s $x; p "$FILL"; s $x $hi; p "$FILL"
|
||||||
|
done
|
||||||
|
s; pn " Test for support of ForeHi colors (w/compat)"
|
||||||
|
|
||||||
|
# BackHi
|
||||||
|
p " "
|
||||||
|
for x in $BACK_COLORS; do
|
||||||
|
hi=$(( $x + 60 ))
|
||||||
|
s $x; p "-"; s $hi; p "-"
|
||||||
|
done
|
||||||
|
s; pn " Test for support of BackHi colors"
|
||||||
|
p " "
|
||||||
|
for x in $BACK_COLORS; do
|
||||||
|
hi=$(( $x + 60 ))
|
||||||
|
s $x; p "-"; s $x $hi; p "-"
|
||||||
|
done
|
||||||
|
s; pn " Test for support of BackHi colors (w/compat)"
|
||||||
|
|
||||||
|
pn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Identify the default fore and back colors.
|
||||||
|
|
||||||
|
pn "Match default fore and back colors against 16-color palette"
|
||||||
|
pn " ==fore== ==back=="
|
||||||
|
for fore in $FORE_COLORS; do
|
||||||
|
forehi=$(( $fore + 60 ))
|
||||||
|
back=$(( $fore + 10 ))
|
||||||
|
backhi=$(( $back + 60 ))
|
||||||
|
p " "
|
||||||
|
s $fore; p "$FILL"; s; p "$FILL"; s $fore; p "$FILL"; s; p " "
|
||||||
|
s $forehi; p "$FILL"; s; p "$FILL"; s $forehi; p "$FILL"; s; p " "
|
||||||
|
s $back; p "-"; s; p "-"; s $back; p "-"; s; p " "
|
||||||
|
s $backhi; p "-"; s; p "-"; s $backhi; p "-"; s; p " "
|
||||||
|
pn " $fore $forehi $back $backhi"
|
||||||
|
done
|
||||||
|
|
||||||
|
pn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Test coloring of rest-of-line.
|
||||||
|
|
||||||
|
#
|
||||||
|
# When a new line is scrolled in, every cell in the line receives the
|
||||||
|
# current background color, which can be the default/transparent color.
|
||||||
|
#
|
||||||
|
|
||||||
|
p "Newline with red background: usually no red -->"; s 41; pn
|
||||||
|
s; pn "This text is plain, but rest is red if scrolled -->"
|
||||||
|
s; p " "; s 41; printf '\033[1K'; s; printf '\033[1C'; pn "<-- red Erase-in-Line to beginning"
|
||||||
|
s; p "red Erase-in-Line to end -->"; s 41; printf '\033[0K'; s; pn
|
||||||
|
pn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Moving the cursor around does not change colors of anything.
|
||||||
|
|
||||||
|
pn "Test modifying uncolored lines with a colored SGR:"
|
||||||
|
pn "aaaa"
|
||||||
|
pn
|
||||||
|
pn "____e"
|
||||||
|
s 31 42; printf '\033[4C\033[3A'; pn "bb"
|
||||||
|
pn "cccc"
|
||||||
|
pn "dddd"
|
||||||
|
s; pn
|
||||||
|
|
||||||
|
pn "Test modifying colored+inverted+bold line with plain text:"
|
||||||
|
s 42 31 7 1; printf 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r';
|
||||||
|
s; pn "This text is plain and followed by green-on-red -->"
|
||||||
|
pn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Full-width character overwriting
|
||||||
|
|
||||||
|
pn 'Overwrite part of a full-width char with a half-width char'
|
||||||
|
p 'initial U+4000 ideographs -->'; s 31 42; p '䀀䀀'; s; pn
|
||||||
|
p 'write X to index #1 -->'; s 31 42; p '䀀䀀'; s 35 44; printf '\033[24G'; p X; s; pn
|
||||||
|
p 'write X to index #2 -->'; s 31 42; p '䀀䀀'; s 35 44; printf '\033[25G'; p X; s; pn
|
||||||
|
p 'write X to index #3 -->'; s 31 42; p '䀀䀀'; s 35 44; printf '\033[26G'; p X; s; pn
|
||||||
|
p 'write X to index #4 -->'; s 31 42; p '䀀䀀'; s 35 44; printf '\033[27G'; p X; s; pn
|
||||||
|
pn
|
||||||
|
|
||||||
|
pn 'Verify that Erase-in-Line can "fix" last char in line'
|
||||||
|
p 'original -->'; s 31 42; p '䀀䀀'; s; pn
|
||||||
|
p 'overwrite -->'; s 31 42; p '䀀䀀'; s 35 44; printf '\033[30G'; p 'XXX'; s; pn
|
||||||
|
p 'overwrite + Erase-in-Line -->'; s 31 42; p '䀀䀀'; s 35 44; printf '\033[30G'; p 'XXX'; s; printf '\033[0K'; pn
|
||||||
|
p 'original -->'; s 31 42; p 'X䀀䀀'; s; pn
|
||||||
|
p 'overwrite -->'; s 31 42; p 'X䀀䀀'; s 35 44; printf '\033[30G'; p 'ーー'; s; pn
|
||||||
|
p 'overwrite + Erase-in-Line -->'; s 31 42; p 'X䀀䀀'; s 35 44; printf '\033[30G'; p 'ーー'; s; printf '\033[0K'; pn
|
||||||
|
pn
|
||||||
+300
@@ -0,0 +1,300 @@
|
|||||||
|
==================================================================
|
||||||
|
Notes regarding fonts, code pages, and East Asian character widths
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
|
||||||
|
Registry settings
|
||||||
|
=================
|
||||||
|
|
||||||
|
* There are console registry settings in `HKCU\Console`. That key has many
|
||||||
|
default settings (e.g. the default font settings) and also per-app subkeys
|
||||||
|
for app-specific overrides.
|
||||||
|
|
||||||
|
* It is possible to override the code page with an app-specific setting.
|
||||||
|
|
||||||
|
* There are registry settings in
|
||||||
|
`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console`. In particular,
|
||||||
|
the `TrueTypeFont` subkey has a list of suitable font names associated with
|
||||||
|
various CJK code pages, as well as default font names.
|
||||||
|
|
||||||
|
* There are two values in `HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage`
|
||||||
|
that specify the current code pages -- `OEMCP` and `ACP`. Setting the
|
||||||
|
system locale via the Control Panel's "Region" or "Language" dialogs seems
|
||||||
|
to change these code page values.
|
||||||
|
|
||||||
|
|
||||||
|
Console fonts
|
||||||
|
=============
|
||||||
|
|
||||||
|
* The `FontFamily` field of `CONSOLE_FONT_INFOEX` has two parts:
|
||||||
|
- The high four bits can be exactly one of the `FF_xxxx` font families:
|
||||||
|
FF_DONTCARE(0x00)
|
||||||
|
FF_ROMAN(0x10)
|
||||||
|
FF_SWISS(0x20)
|
||||||
|
FF_MODERN(0x30)
|
||||||
|
FF_SCRIPT(0x40)
|
||||||
|
FF_DECORATIVE(0x50)
|
||||||
|
- The low four bits are a bitmask:
|
||||||
|
TMPF_FIXED_PITCH(1) -- actually means variable pitch
|
||||||
|
TMPF_VECTOR(2)
|
||||||
|
TMPF_TRUETYPE(4)
|
||||||
|
TMPF_DEVICE(8)
|
||||||
|
|
||||||
|
* Each console has its own independent console font table. The current font
|
||||||
|
is identified with an index into this table. The size of the table is
|
||||||
|
returned by the undocumented `GetNumberOfConsoleFonts` API. It is apparently
|
||||||
|
possible to get the table size without this API, by instead calling
|
||||||
|
`GetConsoleFontSize` on each nonnegative index starting with 0 until the API
|
||||||
|
fails by returning (0, 0).
|
||||||
|
|
||||||
|
* The font table grows dynamically. Each time the console is configured with
|
||||||
|
a previously-unused (FaceName, Size) combination, two entries are added to
|
||||||
|
the font table -- one with normal weight and one with bold weight. Fonts
|
||||||
|
added this way are always TrueType fonts.
|
||||||
|
|
||||||
|
* Initially, the font table appears to contain only raster fonts. For
|
||||||
|
example, on an English Windows 8 installation, here is the initial font
|
||||||
|
table:
|
||||||
|
font 0: 4x6
|
||||||
|
font 1: 6x8
|
||||||
|
font 2: 8x8
|
||||||
|
font 3: 16x8
|
||||||
|
font 4: 5x12
|
||||||
|
font 5: 7x12
|
||||||
|
font 6: 8x12 -- the current font
|
||||||
|
font 7: 16x12
|
||||||
|
font 8: 12x16
|
||||||
|
font 9: 10x18
|
||||||
|
`GetNumberOfConsoleFonts` returns 10, and this table matches the raster font
|
||||||
|
sizes according to the console properties dialog.
|
||||||
|
|
||||||
|
* With a Japanese or Chinese locale, the initial font table appears to contain
|
||||||
|
the sizes applicable to both the East Asian raster font, as well as the
|
||||||
|
sizes for the CP437/CP1252 raster font.
|
||||||
|
|
||||||
|
* The index passed to `SetCurrentConsoleFontEx` apparently has no effect.
|
||||||
|
The undocumented `SetConsoleFont` API, however, accepts *only* a font index,
|
||||||
|
and on Windows 8 English, it switches between all 10 fonts, even font index
|
||||||
|
#0.
|
||||||
|
|
||||||
|
* If the index passed to `SetConsoleFont` identifies a Raster Font
|
||||||
|
incompatible with the current code page, then another Raster Font is
|
||||||
|
activated.
|
||||||
|
|
||||||
|
* Passing "Terminal" to `SetCurrentConsoleFontEx` seems to have no effect.
|
||||||
|
Perhaps relatedly, `SetCurrentConsoleFontEx` does not fail if it is given a
|
||||||
|
bogus `FaceName`. Some font is still chosen and activated. Passing a face
|
||||||
|
name and height seems to work reliably, modulo the CP936 issue described
|
||||||
|
below.
|
||||||
|
|
||||||
|
|
||||||
|
Console fonts and code pages
|
||||||
|
============================
|
||||||
|
|
||||||
|
* On an English Windows installation, the default code page is 437, and it
|
||||||
|
cannot be set to 932 (Shift-JIS). (The API call fails.) Changing the
|
||||||
|
system locale to "Japanese (Japan)" using the Region/Language dialog
|
||||||
|
changes the default CP to 932 and permits changing the console CP between
|
||||||
|
437 and 932.
|
||||||
|
|
||||||
|
* A console has both an input code page and an output code page
|
||||||
|
(`{Get,Set}ConsoleCP` and `{Get,Set}ConsoleOutputCP`). I'm not going to
|
||||||
|
distinguish between the two for this document; presumably only the output
|
||||||
|
CP matters. The code page can change while the console is open, e.g.
|
||||||
|
by running `mode con: cp select={932,437,1252}` or by calling
|
||||||
|
`SetConsoleOutputCP`.
|
||||||
|
|
||||||
|
* The current code page restricts which TrueType fonts and which Raster Font
|
||||||
|
sizes are available in the console properties dialog. This can change
|
||||||
|
while the console is open.
|
||||||
|
|
||||||
|
* Changing the code page almost(?) always changes the current console font.
|
||||||
|
So far, I don't know how the new font is chosen.
|
||||||
|
|
||||||
|
* With a CP of 932, the only TrueType font available in the console properties
|
||||||
|
dialog is "MS Gothic", displayed as "MS ゴシック". It is still possible to
|
||||||
|
use the English-default TrueType console fonts, Lucida Console and Consolas,
|
||||||
|
via `SetCurrentConsoleFontEx`.
|
||||||
|
|
||||||
|
* When using a Raster Font and CP437 or CP1252, writing a UTF-16 codepoint not
|
||||||
|
representable in the code page instead writes a question mark ('?') to the
|
||||||
|
console. This conversion does not apply with a TrueType font, nor with the
|
||||||
|
Raster Font for CP932 or CP936.
|
||||||
|
|
||||||
|
|
||||||
|
ReadConsoleOutput and double-width characters
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
* With a Raster Font active, when `ReadConsoleOutputW` reads two cells of a
|
||||||
|
double-width character, it fills only a single `CHAR_INFO` structure. The
|
||||||
|
unused trailing `CHAR_INFO` structures are zero-filled. With a TrueType
|
||||||
|
font active, `ReadConsoleOutputW` instead fills two `CHAR_INFO` structures,
|
||||||
|
the first marked with `COMMON_LVB_LEADING_BYTE` and the second marked with
|
||||||
|
`COMMON_LVB_TRAILING_BYTE`. The flag is a misnomer--there aren't two
|
||||||
|
*bytes*, but two cells, and they have equal `CHAR_INFO.Char.UnicodeChar`
|
||||||
|
values.
|
||||||
|
|
||||||
|
* `ReadConsoleOutputA`, on the other hand, reads two `CHAR_INFO` cells, and
|
||||||
|
if the UTF-16 value can be represented as two bytes in the ANSI/OEM CP, then
|
||||||
|
the two bytes are placed in the two `CHAR_INFO.Char.AsciiChar` values, and
|
||||||
|
the `COMMON_LVB_{LEADING,TRAILING}_BYTE` values are also used. If the
|
||||||
|
codepoint isn't representable, I don't remember what happens -- I think the
|
||||||
|
`AsciiChar` values take on an invalid marker.
|
||||||
|
|
||||||
|
* Reading only one cell of a double-width character reads a space (U+0020)
|
||||||
|
instead. Raster-vs-TrueType and wide-vs-ANSI do not matter.
|
||||||
|
- XXX: what about attributes? Can a double-width character have mismatched
|
||||||
|
color attributes?
|
||||||
|
- XXX: what happens when writing to just one cell of a double-width
|
||||||
|
character?
|
||||||
|
|
||||||
|
|
||||||
|
Default Windows fonts for East Asian languages
|
||||||
|
==============================================
|
||||||
|
CP932 / Japanese: "MS ゴシック" (MS Gothic)
|
||||||
|
CP936 / Chinese Simplified: "新宋体" (SimSun)
|
||||||
|
|
||||||
|
|
||||||
|
Unreliable character width (half-width vs full-width)
|
||||||
|
=====================================================
|
||||||
|
|
||||||
|
The half-width vs full-width status of a codepoint depends on at least these variables:
|
||||||
|
* OS version (Win10 legacy and new modes are different versions)
|
||||||
|
* system locale (English vs Japanese vs Chinese Simplified vs Chinese Traditional, etc)
|
||||||
|
* code page (437 vs 932 vs 936, etc)
|
||||||
|
* raster vs TrueType (Terminal vs MS Gothic vs SimSun, etc)
|
||||||
|
* font size
|
||||||
|
* rendered-vs-model (rendered width can be larger or smaller than model width)
|
||||||
|
|
||||||
|
Example 1: U+2014 (EM DASH): East_Asian_Width: Ambiguous
|
||||||
|
--------------------------------------------------------
|
||||||
|
rendered modeled
|
||||||
|
CP932: Win7/8 Raster Fonts half half
|
||||||
|
CP932: Win7/8 Gothic 14/15px half full
|
||||||
|
CP932: Win7/8 Consolas 14/15px half full
|
||||||
|
CP932: Win7/8 Lucida Console 14px half full
|
||||||
|
CP932: Win7/8 Lucida Console 15px half half
|
||||||
|
CP932: Win10New Raster Fonts half half
|
||||||
|
CP932: Win10New Gothic 14/15px half half
|
||||||
|
CP932: Win10New Consolas 14/15px half half
|
||||||
|
CP932: Win10New Lucida Console 14/15px half half
|
||||||
|
|
||||||
|
CP936: Win7/8 Raster Fonts full full
|
||||||
|
CP936: Win7/8 SimSun 14px full full
|
||||||
|
CP936: Win7/8 SimSun 15px full half
|
||||||
|
CP936: Win7/8 Consolas 14/15px half full
|
||||||
|
CP936: Win10New Raster Fonts full full
|
||||||
|
CP936: Win10New SimSum 14/15px full full
|
||||||
|
CP936: Win10New Consolas 14/15px half half
|
||||||
|
|
||||||
|
Example 2: U+3044 (HIRAGANA LETTER I): East_Asian_Width: Wide
|
||||||
|
-------------------------------------------------------------
|
||||||
|
rendered modeled
|
||||||
|
CP932: Win7/8/10N Raster Fonts full full
|
||||||
|
CP932: Win7/8/10N Gothic 14/15px full full
|
||||||
|
CP932: Win7/8/10N Consolas 14/15px half(*2) full
|
||||||
|
CP932: Win7/8/10N Lucida Console 14/15px half(*3) full
|
||||||
|
|
||||||
|
CP936: Win7/8/10N Raster Fonts full full
|
||||||
|
CP936: Win7/8/10N SimSun 14/15px full full
|
||||||
|
CP936: Win7/8/10N Consolas 14/15px full full
|
||||||
|
|
||||||
|
Example 3: U+30FC (KATAKANA-HIRAGANA PROLONGED SOUND MARK): East_Asian_Width: Wide
|
||||||
|
----------------------------------------------------------------------------------
|
||||||
|
rendered modeled
|
||||||
|
CP932: Win7 Raster Fonts full full
|
||||||
|
CP932: Win7 Gothic 14/15px full full
|
||||||
|
CP932: Win7 Consolas 14/15px half(*2) full
|
||||||
|
CP932: Win7 Lucida Console 14px half(*3) full
|
||||||
|
CP932: Win7 Lucida Console 15px half(*3) half
|
||||||
|
CP932: Win8 Raster Fonts full full
|
||||||
|
CP932: Win8 Gothic 14px full half
|
||||||
|
CP932: Win8 Gothic 15px full full
|
||||||
|
CP932: Win8 Consolas 14/15px half(*2) full
|
||||||
|
CP932: Win8 Lucida Console 14px half(*3) full
|
||||||
|
CP932: Win8 Lucida Console 15px half(*3) half
|
||||||
|
CP932: Win10New Raster Fonts full full
|
||||||
|
CP932: Win10New Gothic 14/15px full full
|
||||||
|
CP932: Win10New Consolas 14/15px half(*2) half
|
||||||
|
CP932: Win10New Lucida Console 14/15px half(*2) half
|
||||||
|
|
||||||
|
CP936: Win7/8 Raster Fonts full full
|
||||||
|
CP936: Win7/8 SimSun 14px full full
|
||||||
|
CP936: Win7/8 SimSun 15px full half
|
||||||
|
CP936: Win7/8 Consolas 14px full full
|
||||||
|
CP936: Win7/8 Consolas 15px full half
|
||||||
|
CP936: Win10New Raster Fonts full full
|
||||||
|
CP936: Win10New SimSum 14/15px full full
|
||||||
|
CP936: Win10New Consolas 14/15px full full
|
||||||
|
|
||||||
|
Example 4: U+4000 (CJK UNIFIED IDEOGRAPH-4000): East_Asian_Width: Wide
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
rendered modeled
|
||||||
|
CP932: Win7 Raster Fonts half(*1) half
|
||||||
|
CP932: Win7 Gothic 14/15px full full
|
||||||
|
CP932: Win7 Consolas 14/15px half(*2) full
|
||||||
|
CP932: Win7 Lucida Console 14px half(*3) full
|
||||||
|
CP932: Win7 Lucida Console 15px half(*3) half
|
||||||
|
CP932: Win8 Raster Fonts half(*1) half
|
||||||
|
CP932: Win8 Gothic 14px full half
|
||||||
|
CP932: Win8 Gothic 15px full full
|
||||||
|
CP932: Win8 Consolas 14/15px half(*2) full
|
||||||
|
CP932: Win8 Lucida Console 14px half(*3) full
|
||||||
|
CP932: Win8 Lucida Console 15px half(*3) half
|
||||||
|
CP932: Win10New Raster Fonts half(*1) half
|
||||||
|
CP932: Win10New Gothic 14/15px full full
|
||||||
|
CP932: Win10New Consolas 14/15px half(*2) half
|
||||||
|
CP932: Win10New Lucida Console 14/15px half(*2) half
|
||||||
|
|
||||||
|
CP936: Win7/8 Raster Fonts full full
|
||||||
|
CP936: Win7/8 SimSun 14px full full
|
||||||
|
CP936: Win7/8 SimSun 15px full half
|
||||||
|
CP936: Win7/8 Consolas 14px full full
|
||||||
|
CP936: Win7/8 Consolas 15px full half
|
||||||
|
CP936: Win10New Raster Fonts full full
|
||||||
|
CP936: Win10New SimSum 14/15px full full
|
||||||
|
CP936: Win10New Consolas 14/15px full full
|
||||||
|
|
||||||
|
(*1) Rendered as a half-width filled white box
|
||||||
|
(*2) Rendered as a half-width box with a question mark inside
|
||||||
|
(*3) Rendered as a half-width empty box
|
||||||
|
(!!) One of the only places in Win10New where rendered and modeled width disagree
|
||||||
|
|
||||||
|
|
||||||
|
Windows quirk: unreliable font heights with CP936 / Chinese Simplified
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
When I set the font to 新宋体 17px, using either the properties dialog or
|
||||||
|
`SetCurrentConsoleFontEx`, the height reported by `GetCurrentConsoleFontEx` is
|
||||||
|
not 17, but is instead 19. The same problem does not affect Raster Fonts,
|
||||||
|
nor have I seen the problem in the English or Japanese locales. I observed
|
||||||
|
this with Windows 7 and Windows 10 new mode.
|
||||||
|
|
||||||
|
If I set the font using the facename, width, *and* height, then the
|
||||||
|
`SetCurrentConsoleFontEx` and `GetCurrentConsoleFontEx` values agree. If I
|
||||||
|
set the font using *only* the facename and height, then the two values
|
||||||
|
disagree.
|
||||||
|
|
||||||
|
|
||||||
|
Windows bug: GetCurrentConsoleFontEx is initially invalid
|
||||||
|
=========================================================
|
||||||
|
|
||||||
|
- Assume there is no configured console font name in the registry. In this
|
||||||
|
case, the console defaults to a raster font.
|
||||||
|
- Open a new console and call the `GetCurrentConsoleFontEx` API.
|
||||||
|
- The `FaceName` field of the returned `CONSOLE_FONT_INFOEX` data
|
||||||
|
structure is incorrect. On Windows 7, 8, and 10, I observed that the
|
||||||
|
field was blank. On Windows 8, occasionally, it instead contained:
|
||||||
|
U+AE72 U+75BE U+0001
|
||||||
|
The other fields of the structure all appeared correct:
|
||||||
|
nFont=6 dwFontSize=(8,12) FontFamily=0x30 FontWeight=400
|
||||||
|
- The `FaceName` field becomes initialized easily:
|
||||||
|
- Open the console properties dialog and click OK. (Cancel is not
|
||||||
|
sufficient.)
|
||||||
|
- Call the undocumented `SetConsoleFont` with the current font table
|
||||||
|
index, which is 6 in the example above.
|
||||||
|
- It seems that the console uncritically accepts whatever string is
|
||||||
|
stored in the registry, including a blank string, and passes it on the
|
||||||
|
the `GetCurrentConsoleFontEx` caller. It is possible to get the console
|
||||||
|
to *write* a blank setting into the registry -- simply open the console
|
||||||
|
(default or app-specific) properties and click OK.
|
||||||
+201
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Test program demonstrating a problem in Windows 15048's ReadConsoleOutput API.
|
||||||
|
|
||||||
|
To compile:
|
||||||
|
|
||||||
|
cl /nologo /EHsc winbug-15048.cc shell32.lib
|
||||||
|
|
||||||
|
Example of regressed input:
|
||||||
|
|
||||||
|
Case 1:
|
||||||
|
|
||||||
|
> chcp 932
|
||||||
|
> winbug-15048 -face-gothic 3044
|
||||||
|
|
||||||
|
Correct output:
|
||||||
|
|
||||||
|
1**34 (nb: U+3044 replaced with '**' to avoid MSVC encoding warning)
|
||||||
|
5678
|
||||||
|
|
||||||
|
ReadConsoleOutputW (both rows, 3 cols)
|
||||||
|
row 0: U+0031(0007) U+3044(0107) U+3044(0207) U+0033(0007)
|
||||||
|
row 1: U+0035(0007) U+0036(0007) U+0037(0007) U+0038(0007)
|
||||||
|
|
||||||
|
ReadConsoleOutputW (both rows, 4 cols)
|
||||||
|
row 0: U+0031(0007) U+3044(0107) U+3044(0207) U+0033(0007) U+0034(0007)
|
||||||
|
row 1: U+0035(0007) U+0036(0007) U+0037(0007) U+0038(0007) U+0020(0007)
|
||||||
|
|
||||||
|
ReadConsoleOutputW (second row)
|
||||||
|
row 1: U+0035(0007) U+0036(0007) U+0037(0007) U+0038(0007) U+0020(0007)
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
Win10 15048 bad output:
|
||||||
|
|
||||||
|
1**34
|
||||||
|
5678
|
||||||
|
|
||||||
|
ReadConsoleOutputW (both rows, 3 cols)
|
||||||
|
row 0: U+0031(0007) U+3044(0007) U+0033(0007) U+0035(0007)
|
||||||
|
row 1: U+0036(0007) U+0037(0007) U+0038(0007) U+0000(0000)
|
||||||
|
|
||||||
|
ReadConsoleOutputW (both rows, 4 cols)
|
||||||
|
row 0: U+0031(0007) U+3044(0007) U+0033(0007) U+0034(0007) U+0035(0007)
|
||||||
|
row 1: U+0036(0007) U+0037(0007) U+0038(0007) U+0020(0007) U+0000(0000)
|
||||||
|
|
||||||
|
ReadConsoleOutputW (second row)
|
||||||
|
row 1: U+0035(0007) U+0036(0007) U+0037(0007) U+0038(0007) U+0020(0007)
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
The U+3044 character (HIRAGANA LETTER I) occupies two columns, but it only
|
||||||
|
fills one record in the ReadConsoleOutput output buffer, which has the
|
||||||
|
effect of shifting the first cell of the second row into the last cell of
|
||||||
|
the first row. Ordinarily, the first and second cells would also have the
|
||||||
|
COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE attributes set, which
|
||||||
|
allows winpty to detect the double-column character.
|
||||||
|
|
||||||
|
Case 2:
|
||||||
|
|
||||||
|
> chcp 437
|
||||||
|
> winbug-15048 -face "Lucida Console" -h 4 221A
|
||||||
|
|
||||||
|
The same issue happens with U+221A (SQUARE ROOT), but only in certain
|
||||||
|
fonts. The console seems to think this character occupies two columns
|
||||||
|
if the font is sufficiently small. The Windows console properties dialog
|
||||||
|
doesn't allow fonts below 5 pt, but winpty tries to use 2pt and 4pt Lucida
|
||||||
|
Console to allow very large console windows.
|
||||||
|
|
||||||
|
Case 3:
|
||||||
|
|
||||||
|
> chcp 437
|
||||||
|
> winbug-15048 -face "Lucida Console" -h 12 FF12
|
||||||
|
|
||||||
|
The console selection system thinks U+FF12 (FULLWIDTH DIGIT TWO) occupies
|
||||||
|
two columns, which happens to be correct, but it's displayed as a single
|
||||||
|
column unrecognized character. It otherwise behaves the same as the other
|
||||||
|
cases.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define COUNT_OF(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
|
||||||
|
// See https://en.wikipedia.org/wiki/List_of_CJK_fonts
|
||||||
|
const wchar_t kMSGothic[] = { 0xff2d, 0xff33, 0x0020, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 }; // Japanese
|
||||||
|
const wchar_t kNSimSun[] = { 0x65b0, 0x5b8b, 0x4f53, 0 }; // Simplified Chinese
|
||||||
|
const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
|
||||||
|
const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
|
||||||
|
|
||||||
|
static void set_font(const wchar_t *name, int size) {
|
||||||
|
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
CONSOLE_FONT_INFOEX fontex {};
|
||||||
|
fontex.cbSize = sizeof(fontex);
|
||||||
|
fontex.dwFontSize.Y = size;
|
||||||
|
fontex.FontWeight = 400;
|
||||||
|
fontex.FontFamily = 0x36;
|
||||||
|
wcsncpy(fontex.FaceName, name, COUNT_OF(fontex.FaceName));
|
||||||
|
assert(SetCurrentConsoleFontEx(conout, FALSE, &fontex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(const wchar_t *prog) {
|
||||||
|
printf("Usage: %ls [options]\n", prog);
|
||||||
|
printf(" -h HEIGHT\n");
|
||||||
|
printf(" -face FACENAME\n");
|
||||||
|
printf(" -face-{gothic|simsun|minglight|gulimche) [JP,CN-sim,CN-tra,KR]\n");
|
||||||
|
printf(" hhhh -- print U+hhhh\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_region(SMALL_RECT region, const char *name) {
|
||||||
|
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
CHAR_INFO buf[1000];
|
||||||
|
memset(buf, 0xcc, sizeof(buf));
|
||||||
|
|
||||||
|
const int w = region.Right - region.Left + 1;
|
||||||
|
const int h = region.Bottom - region.Top + 1;
|
||||||
|
|
||||||
|
assert(ReadConsoleOutputW(
|
||||||
|
conout, buf, { (short)w, (short)h }, { 0, 0 },
|
||||||
|
®ion));
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("ReadConsoleOutputW (%s)\n", name);
|
||||||
|
for (int y = 0; y < h; ++y) {
|
||||||
|
printf("row %d: ", region.Top + y);
|
||||||
|
for (int i = 0; i < region.Left * 13; ++i) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
for (int x = 0; x < w; ++x) {
|
||||||
|
const int i = y * w + x;
|
||||||
|
printf("U+%04x(%04x) ", buf[i].Char.UnicodeChar, buf[i].Attributes);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
wchar_t *cmdline = GetCommandLineW();
|
||||||
|
int argc = 0;
|
||||||
|
wchar_t **argv = CommandLineToArgvW(cmdline, &argc);
|
||||||
|
const wchar_t *font_name = L"Lucida Console";
|
||||||
|
int font_height = 8;
|
||||||
|
int test_ch = 0xff12; // U+FF12 FULLWIDTH DIGIT TWO
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
const std::wstring arg = argv[i];
|
||||||
|
const std::wstring next = i + 1 < argc ? argv[i + 1] : L"";
|
||||||
|
if (arg == L"-face" && i + 1 < argc) {
|
||||||
|
font_name = argv[i + 1];
|
||||||
|
i++;
|
||||||
|
} else if (arg == L"-face-gothic") {
|
||||||
|
font_name = kMSGothic;
|
||||||
|
} else if (arg == L"-face-simsun") {
|
||||||
|
font_name = kNSimSun;
|
||||||
|
} else if (arg == L"-face-minglight") {
|
||||||
|
font_name = kMingLight;
|
||||||
|
} else if (arg == L"-face-gulimche") {
|
||||||
|
font_name = kGulimChe;
|
||||||
|
} else if (arg == L"-h" && i + 1 < argc) {
|
||||||
|
font_height = _wtoi(next.c_str());
|
||||||
|
i++;
|
||||||
|
} else if (arg.c_str()[0] != '-') {
|
||||||
|
test_ch = wcstol(arg.c_str(), NULL, 16);
|
||||||
|
} else {
|
||||||
|
printf("Unrecognized argument: %ls\n", arg.c_str());
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
set_font(font_name, font_height);
|
||||||
|
|
||||||
|
system("cls");
|
||||||
|
DWORD actual = 0;
|
||||||
|
wchar_t output[] = L"1234\n5678\n";
|
||||||
|
output[1] = test_ch;
|
||||||
|
WriteConsoleW(conout, output, 10, &actual, nullptr);
|
||||||
|
|
||||||
|
dump_region({ 0, 0, 3, 1 }, "both rows, 3 cols");
|
||||||
|
dump_region({ 0, 0, 4, 1 }, "both rows, 4 cols");
|
||||||
|
dump_region({ 0, 1, 4, 1 }, "second row");
|
||||||
|
dump_region({ 0, 0, 4, 0 }, "first row");
|
||||||
|
dump_region({ 1, 0, 4, 0 }, "first row, skip 1");
|
||||||
|
dump_region({ 2, 0, 4, 0 }, "first row, skip 2");
|
||||||
|
dump_region({ 3, 0, 4, 0 }, "first row, skip 3");
|
||||||
|
|
||||||
|
set_font(font_name, 14);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Generated
Vendored
+36
@@ -0,0 +1,36 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
setlocal
|
||||||
|
cd %~dp0..
|
||||||
|
set Path=C:\Python27;C:\Program Files\Git\cmd;%Path%
|
||||||
|
|
||||||
|
call "%VS140COMNTOOLS%\VsDevCmd.bat" || goto :fail
|
||||||
|
|
||||||
|
rmdir /s/q build-libpty 2>NUL
|
||||||
|
mkdir build-libpty\win
|
||||||
|
mkdir build-libpty\win\x86
|
||||||
|
mkdir build-libpty\win\x86_64
|
||||||
|
mkdir build-libpty\win\xp
|
||||||
|
|
||||||
|
rmdir /s/q src\Release 2>NUL
|
||||||
|
rmdir /s/q src\.vs 2>NUL
|
||||||
|
del src\*.vcxproj src\*.vcxproj.filters src\*.sln src\*.sdf 2>NUL
|
||||||
|
|
||||||
|
call vcbuild.bat --msvc-platform Win32 --gyp-msvs-version 2015 --toolset v140_xp || goto :fail
|
||||||
|
copy src\Release\Win32\winpty.dll build-libpty\win\xp || goto :fail
|
||||||
|
copy src\Release\Win32\winpty-agent.exe build-libpty\win\xp || goto :fail
|
||||||
|
|
||||||
|
call vcbuild.bat --msvc-platform Win32 --gyp-msvs-version 2015 || goto :fail
|
||||||
|
copy src\Release\Win32\winpty.dll build-libpty\win\x86 || goto :fail
|
||||||
|
copy src\Release\Win32\winpty-agent.exe build-libpty\win\x86 || goto :fail
|
||||||
|
|
||||||
|
call vcbuild.bat --msvc-platform x64 --gyp-msvs-version 2015 || goto :fail
|
||||||
|
copy src\Release\x64\winpty.dll build-libpty\win\x86_64 || goto :fail
|
||||||
|
copy src\Release\x64\winpty-agent.exe build-libpty\win\x86_64 || goto :fail
|
||||||
|
|
||||||
|
echo success
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
:fail
|
||||||
|
echo error: build failed
|
||||||
|
exit /b 1
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if os.name != "nt":
|
||||||
|
sys.exit("Error: ship scripts require native Python 2.7. (wrong os.name)")
|
||||||
|
if sys.version_info[0:2] != (2,7):
|
||||||
|
sys.exit("Error: ship scripts require native Python 2.7. (wrong version)")
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from distutils.spawn import find_executable
|
||||||
|
|
||||||
|
topDir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||||
|
|
||||||
|
with open(topDir + "/VERSION.txt", "rt") as f:
|
||||||
|
winptyVersion = f.read().strip()
|
||||||
|
|
||||||
|
def rmrf(patterns):
|
||||||
|
for pattern in patterns:
|
||||||
|
for path in glob.glob(pattern):
|
||||||
|
if os.path.isdir(path) and not os.path.islink(path):
|
||||||
|
print "+ rm -r " + path
|
||||||
|
sys.stdout.flush()
|
||||||
|
shutil.rmtree(path)
|
||||||
|
elif os.path.isfile(path):
|
||||||
|
print "+ rm " + path
|
||||||
|
sys.stdout.flush()
|
||||||
|
os.remove(path)
|
||||||
|
|
||||||
|
def mkdir(path):
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
os.makedirs(path)
|
||||||
|
|
||||||
|
def requireExe(name, guesses):
|
||||||
|
if find_executable(name) is None:
|
||||||
|
for guess in guesses:
|
||||||
|
if os.path.exists(guess):
|
||||||
|
newDir = os.path.dirname(guess)
|
||||||
|
print "Adding " + newDir + " to Path to provide " + name
|
||||||
|
os.environ["Path"] = newDir + ";" + os.environ["Path"]
|
||||||
|
ret = find_executable(name)
|
||||||
|
if ret is None:
|
||||||
|
sys.exit("Error: required EXE is missing from Path: " + name)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
requireExe("git.exe", [
|
||||||
|
"C:\\Program Files\\Git\\cmd\\git.exe",
|
||||||
|
"C:\\Program Files (x86)\\Git\\cmd\\git.exe"
|
||||||
|
])
|
||||||
|
|
||||||
|
commitHash = subprocess.check_output(["git.exe", "rev-parse", "HEAD"]).decode().strip()
|
||||||
|
defaultPathEnviron = "C:\\Windows\\System32;C:\\Windows"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user