codecin 6.2.0__tar.gz → 6.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codecin-6.2.0 → codecin-6.2.2}/CHANGELOG.md +74 -0
- {codecin-6.2.0/codecin.egg-info → codecin-6.2.2}/PKG-INFO +1 -1
- {codecin-6.2.0 → codecin-6.2.2}/codecin/__init__.py +1 -1
- {codecin-6.2.0 → codecin-6.2.2}/codecin/cin.py +3 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/isa.py +3 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/gui.cin +12 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/compiler/codegen.go +3 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/compiler/syscalls.go +2 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/gui.go +31 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/gui_stub.go +2 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/gui_windows.go +193 -15
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/gui_x11.go +2 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/isa_gen.go +5 -1
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_windows_test.go +26 -0
- codecin-6.2.2/codecin/native/engine/lineedit.go +262 -0
- codecin-6.2.2/codecin/native/engine/lineedit_test.go +105 -0
- codecin-6.2.2/codecin/native/engine/lineint_unix.go +17 -0
- codecin-6.2.2/codecin/native/engine/lineint_windows.go +19 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/stdin.go +14 -8
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/version_gen.go +1 -1
- codecin-6.2.2/codecin/native/engine/vkb_darwin.go +62 -0
- codecin-6.2.2/codecin/native/engine/vkb_linux.go +95 -0
- codecin-6.2.2/codecin/native/engine/vkb_stub.go +11 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/vm.go +23 -4
- {codecin-6.2.0 → codecin-6.2.2}/codecin/pic_api.py +7 -4
- {codecin-6.2.0 → codecin-6.2.2/codecin.egg-info}/PKG-INFO +1 -1
- {codecin-6.2.0 → codecin-6.2.2}/codecin.egg-info/SOURCES.txt +7 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_pic_registry.py +13 -0
- {codecin-6.2.0 → codecin-6.2.2}/LICENSE +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/MANIFEST.in +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/README.md +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/aot.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/assembler.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/cli.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/config.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/console.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/cpu.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/crom.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/cvm.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/disasm.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/environment.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/errors.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/array.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/bigint.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/bits.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/bitset.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/codec.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/combin.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/conv.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/cppstd.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/cstd.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/csv.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/dp.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/ffi.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/fmt.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/frac.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/gostd.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/graph.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/hash.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/heap.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/io.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/json.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/key.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/math.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/matrix.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/net.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/path.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/queue.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/rand.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/set.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/sort.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/stat.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/str.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/termux.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/test.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/text.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/time.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/token.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/tree.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/unionfind.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/validate.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/lib/vec.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/logger.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/memory.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/mkn.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/aot/aot.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/aot/stub_main.go.txt +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/build.ps1 +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/build.sh +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/compiler/compile_test.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/compiler/parser.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/compiler/tokenizer.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/compiler/types.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/args.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/audio.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/audio_other.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/audio_test.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/audio_windows.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/canvas.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/console_other.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/console_windows.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/crom.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/encode.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/engine_test.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/ffi_nocgo.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/ffi_registry.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/ffi_unix.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/ffi_windows.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/gui_test.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/host_test.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/hostcrypto.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/hostdesktop.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/hostnet.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_other.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_stub.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_termios_darwin.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_termios_linux.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_test.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/keyboard_windows.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/mem_other.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/mem_windows.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/native.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/netsock.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/ops_ext.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/stdin_other.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/stdin_windows.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/system.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/engine/termux.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/go.mod +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/ir/ir.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native/main.go +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/native_codegen.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/object.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/optimizer.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/packaging/__init__.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/packaging/archive.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/packaging/model.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/packaging/store.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/packaging/toml.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/packaging/vcs.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/pic.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/pic_login.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/pic_registry.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/registers.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/stats.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/stdlib.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/toolkit.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin/version.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin.egg-info/dependency_links.txt +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin.egg-info/entry_points.txt +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin.egg-info/requires.txt +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/codecin.egg-info/top_level.txt +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/args_demo.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/asm_constants.asm +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/bitwise_builtins.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/control_flow.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/enum_range_for.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/gui_demo.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/literals_types.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/local_audio.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/modules_demo.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/stdlib_demo.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/examples/system_interaction.cin +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vim/ftdetect/codecin.vim +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vim/syntax/cin.vim +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vim/syntax/codecinasm.vim +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/.vscodeignore +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/README.md +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/build.bat +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/language-configuration.json +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/package.json +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/snippets/cin.json +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/misc/vscode-cin/syntaxes/cin.tmLanguage.json +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/pyproject.toml +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/script/bump_version.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/script/check_paths.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/script/gen_isa_docs.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/script/gen_native_isa.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/setup.cfg +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/setup.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_aggregate_and_const.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_all_libs_together.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_aot.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_assembler_ext.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_bin_compat.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cin_host.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cin_host_ext.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cin_new_features.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cin_syntax.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cin_syntax_ext.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cin_system.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_cli.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_compiler_errors.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_environment.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_examples.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_features_ab.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_features_import.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_features_importloc.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_ffi_net.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_gui.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_index_subscript_type.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_isa_single_source.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_issue_regress.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_keyboard.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_bigint.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_bitset.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_codec.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_combin.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_compat.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_csv.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_dp.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_fmt.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_frac.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_graph.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_heap.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_path.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_set.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_text.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_token.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_tree.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_lib_unionfind.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_libs.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_libs_ext.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_literals_and_bom.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_native_codegen.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_native_hardening.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_native_lib_lookup.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_nested_subscript_codegen.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_no_go_cli.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_object_link.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_p0_fixes.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_packaging.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_paths_consistency.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_sparse_memory.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_struct_value_semantics.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_switch_semantics.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_cvm.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_import.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_mkn.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_packaging.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_pic.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_v620_pic_git.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_version.py +0 -0
- {codecin-6.2.0 → codecin-6.2.2}/tests/test_workflows.py +0 -0
|
@@ -5,6 +5,80 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [6.2.2] - 2026-10-24
|
|
9
|
+
|
|
10
|
+
一次以「注册服务与输入设备」为主题的小版本:`registry` 服务端由 Go 迁移到
|
|
11
|
+
Python;CIN 的键盘监听与查询输入(`input` / `input_str`)统一为同一套按键
|
|
12
|
+
事件监听,行输入改由引擎自行编辑;虚拟键盘支持扩展为 Windows / Linux /
|
|
13
|
+
macOS 全平台;修复 `pic publish` 因 Cdifit 认证接口调用方式错误而返回 502
|
|
14
|
+
的问题。
|
|
15
|
+
|
|
16
|
+
### 新增 (Added)
|
|
17
|
+
|
|
18
|
+
#### 屏幕/触摸键盘 (虚拟键盘, 全平台)
|
|
19
|
+
|
|
20
|
+
- 新增内建 `vkb_show()` / `vkb_hide()`(SYS 158/159)与标准库包装
|
|
21
|
+
`g_vkb_show()` / `g_vkb_hide()`:弹出/收起当前图形会话的屏幕键盘,
|
|
22
|
+
成功返回 `0`,不可用返回 `-1`。
|
|
23
|
+
- **Windows**:经 WinRT `IInputPaneInterop` → `IInputPane2::TryShow/TryHide`
|
|
24
|
+
为顶层窗口弹出/收起系统触摸键盘 (TabTip / 输入体验)。绑定窗口优先
|
|
25
|
+
GUI 窗口;终端 raw 模式绑定可见的控制台窗口,ConPTY (Windows Terminal)
|
|
26
|
+
或无可控制台时退回前台窗口;GUI 窗口关闭 / 程序退出时自动收起键盘。
|
|
27
|
+
- **Linux**:按 `onboard` → `matchbox-keyboard` → `xvkbd` 顺序探测并启动
|
|
28
|
+
屏幕键盘;收起时结束本进程启动的实例,并对桌面常驻实例兜底执行
|
|
29
|
+
`onboard -x` / `pkill`。无 `DISPLAY` / `WAYLAND_DISPLAY` 或均未安装时
|
|
30
|
+
返回 `-1`,程序退出时清理自启进程。
|
|
31
|
+
- **macOS**:以 App 方式打开系统「辅助功能键盘」(Accessibility Keyboard),
|
|
32
|
+
收起时结束对应进程;系统路径不存在或未启用时返回 `-1`。
|
|
33
|
+
- 键盘监听补全虚拟键盘/输入法输入通道:Windows 窗口过程新增 `WM_UNICHAR`
|
|
34
|
+
(含 `UNICODE_NOCHAR` 能力探测) 与 `WM_IME_CHAR`,与既有
|
|
35
|
+
`WM_KEYDOWN`(VK_PACKET) / `WM_CHAR` 共用同一按键队列,`get_key` /
|
|
36
|
+
`key_wait` 无需区分按键来源;支持代理对与 emoji。
|
|
37
|
+
- 终端侧确认 `VK_PACKET + UnicodeChar` (`KEYEVENTF_UNICODE` 注入) 按字符
|
|
38
|
+
入队,并补充对应回归测试。
|
|
39
|
+
|
|
40
|
+
#### 统一的交互式行输入 (查询输入)
|
|
41
|
+
|
|
42
|
+
- `input()` / `input_str()`(`IN` 指令 / SYS 131)在真实终端与 GUI 窗口中
|
|
43
|
+
改由引擎的 **raw 键码队列** 直接读取,与 `get_key` / `key_wait` 使用同一
|
|
44
|
+
套事件监听:不再临时把终端切回行规程(Windows `ReadConsoleW` / Unix
|
|
45
|
+
canonical 模式),也不再依赖操作系统自带行编辑。
|
|
46
|
+
- 内置跨平台行编辑器:字符输入(UTF-8 / 代理对 / emoji)、退格、Delete、
|
|
47
|
+
左右方向键、Home/End、Ctrl+A/E/U/K/W、Ctrl+左右(按词移动)、Enter;
|
|
48
|
+
`Ctrl+D` 空行为 EOF,`Ctrl+C` 恢复终端后按 SIGINT / CTRL_C_EVENT 中断。
|
|
49
|
+
Windows 控制台(已开启 VT 输出)与 Unix 终端共用同一套 ANSI 重绘实现,
|
|
50
|
+
CJK 等宽字符按 2 列计算光标。
|
|
51
|
+
- GUI 窗口打开时,窗口过程注入的按键(含虚拟键盘/输入法)直接作为查询
|
|
52
|
+
输入来源;窗口关闭后 `input()` 立即按 EOF 返回,不再永久阻塞。
|
|
53
|
+
- 无真实终端且无 GUI 窗口(管道 / 重定向 / 测试捕获)时保持原有字节流
|
|
54
|
+
读取路径,输出字节与旧版本完全一致。
|
|
55
|
+
|
|
56
|
+
### 变更 (Changed)
|
|
57
|
+
|
|
58
|
+
- 交互式终端上首次执行 `input()` / `input_str()` 时,与键盘监听一样切换为
|
|
59
|
+
**直写输出**:提示与随后的 `print` 立即落到标准输出,不再等程序结束一次
|
|
60
|
+
性回传;管道 / 重定向 / 测试捕获仍保持纯缓冲语义。
|
|
61
|
+
- **`registry` 服务端由 Go 迁移为 Python**:仅使用标准库 `http.server`
|
|
62
|
+
(`ThreadingHTTPServer`,不依赖 Flask),终端输出与日志由 `rich` 渲染;
|
|
63
|
+
对外 HTTP API、存储布局与校验规则保持不变,默认监听端口为 `18080`,
|
|
64
|
+
Dockerfile / nginx / systemd 服务文件同步更新。
|
|
65
|
+
- 服务端测试由 Go 改为 `registry/test_server.py`(pytest);部署方式更新为
|
|
66
|
+
Python 3.10+ 虚拟环境 + `requirements.txt`,文档同步改写。
|
|
67
|
+
|
|
68
|
+
### 修复 (Fixed)
|
|
69
|
+
|
|
70
|
+
- 修复 `pic publish` 提交时返回 **502**:registry 调用 Cdifit 用户信息接口
|
|
71
|
+
误用了 `POST /api/v4/session/oauth/userinfo`(实际为 `GET`,POST 得到
|
|
72
|
+
`404 page not found`,被服务端包装成 `502 auth_unavailable`)。
|
|
73
|
+
- 修复无效/过期 Token 被误报为 502:Cdifit 以 `HTTP 200 + code=401` 返回
|
|
74
|
+
鉴权失败,服务端现将其映射为客户端 `401`;`pic_api.userinfo()` 同步改为
|
|
75
|
+
`GET`,并让 `code=401/403` 触发 Token 刷新,而非作为未知状态码上报。
|
|
76
|
+
- 修复 SYS 号 158/159 被 `syscallSupported` 上限拦截,导致 `vkb_show` /
|
|
77
|
+
`vkb_hide` 报 `unsupported SYS call id`。
|
|
78
|
+
- 修正 `registry/README.md` 中 Docker 端口映射为 `18080:18080`。
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
8
82
|
## [6.2.0] - 2026-10-23
|
|
9
83
|
|
|
10
84
|
一次以「工具链生态」为主题的发布:新增 **mkn**(Maven 风格构建)、**pic**
|
|
@@ -253,6 +253,9 @@ HOST_BUILTINS = {
|
|
|
253
253
|
'mouse_x': (Syscall.MOUSEX, 0, 'int'),
|
|
254
254
|
'mouse_y': (Syscall.MOUSEY, 0, 'int'),
|
|
255
255
|
'mouse_button': (Syscall.MOUSEBTN, 0, 'int'),
|
|
256
|
+
# 虚拟键盘 (Windows 屏幕/触摸键盘 TabTip; 其他平台 -1)
|
|
257
|
+
'vkb_show': (Syscall.VKBSHOW, 0, 'int'),
|
|
258
|
+
'vkb_hide': (Syscall.VKBHIDE, 0, 'int'),
|
|
256
259
|
# 音频扩展 (播放进度与蜂鸣合成)
|
|
257
260
|
'audio_pos': (Syscall.AUDIOPOS, 0, 'int'),
|
|
258
261
|
'beep': (Syscall.AUDIOBEEP, 2, 'int'),
|
|
@@ -303,6 +303,9 @@ class Syscall(IntEnum):
|
|
|
303
303
|
# -> 实际字节数; 来源 "ip:port" 写入 x2 (0 为不关心)
|
|
304
304
|
UDPCLOSE = 156 # udp_close(x0=句柄) -> 0 成功 / -1 失败
|
|
305
305
|
DNSLOOKUP = 157 # dns_lookup(x0=域名) -> 首个 IP 地址 (新堆字符串; 失败为空串)
|
|
306
|
+
# ---- 宿主能力: 虚拟键盘 (Windows 屏幕/触摸键盘; 其他平台 -1) ----
|
|
307
|
+
VKBSHOW = 158 # vkb_show() -> 0 已弹出触摸键盘 / -1 不可用
|
|
308
|
+
VKBHIDE = 159 # vkb_hide() -> 0 已收起 (本就收起也算成功) / -1 不可用
|
|
306
309
|
|
|
307
310
|
|
|
308
311
|
class Cond:
|
|
@@ -120,6 +120,18 @@ function g_mouse_middle() -> int {
|
|
|
120
120
|
return 0
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
// 弹出屏幕/触摸键盘: 0 成功 / -1 不可用
|
|
124
|
+
// (Windows: TabTip/输入体验; Linux: onboard/matchbox-keyboard/xvkbd;
|
|
125
|
+
// macOS: 辅助功能键盘)
|
|
126
|
+
function g_vkb_show() -> int {
|
|
127
|
+
return vkb_show()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 收起屏幕/触摸键盘: 0 成功 / -1 不可用
|
|
131
|
+
function g_vkb_hide() -> int {
|
|
132
|
+
return vkb_hide()
|
|
133
|
+
}
|
|
134
|
+
|
|
123
135
|
// ==================== 二、离屏绘图助手 ====================
|
|
124
136
|
|
|
125
137
|
// 打包 RGB 颜色 (0xRRGGBB)
|
|
@@ -122,6 +122,9 @@ var hostBuiltins = map[string]hostBuiltin{
|
|
|
122
122
|
"mouse_x": {SysMOUSEX, 0, kInt},
|
|
123
123
|
"mouse_y": {SysMOUSEY, 0, kInt},
|
|
124
124
|
"mouse_button": {SysMOUSEBTN, 0, kInt},
|
|
125
|
+
// 虚拟键盘 (Windows 屏幕/触摸键盘 TabTip; 其他平台 -1)
|
|
126
|
+
"vkb_show": {SysVKBSHOW, 0, kInt},
|
|
127
|
+
"vkb_hide": {SysVKBHIDE, 0, kInt},
|
|
125
128
|
// 音频扩展 (播放进度与蜂鸣合成)
|
|
126
129
|
"audio_pos": {SysAUDIOPOS, 0, kInt},
|
|
127
130
|
"beep": {SysAUDIOBEEP, 2, kInt},
|
|
@@ -136,6 +136,37 @@ func guiMarkClosed() {
|
|
|
136
136
|
guiMu.Unlock()
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
// guiWindowOpen 是否已打开 GUI 窗口 (行输入据此决定是否走键码队列)。
|
|
140
|
+
func guiWindowOpen() bool {
|
|
141
|
+
guiMu.Lock()
|
|
142
|
+
defer guiMu.Unlock()
|
|
143
|
+
return guiOpen
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// guiUserClosed 用户已请求关闭且窗口仍标记为打开: 行输入应立即返回 EOF,
|
|
147
|
+
// 避免窗口关闭后 input/input_str 永久阻塞在键码轮询上。
|
|
148
|
+
func guiUserClosed() bool {
|
|
149
|
+
guiMu.Lock()
|
|
150
|
+
defer guiMu.Unlock()
|
|
151
|
+
return guiOpen && guiClosedF
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// vkbShow SYS 158: 弹出 Windows 屏幕/触摸键盘 -> 0 成功 / -1 不可用。
|
|
155
|
+
func (vm *vmState) vkbShow() uint64 {
|
|
156
|
+
if guiVkbShow() {
|
|
157
|
+
return 0
|
|
158
|
+
}
|
|
159
|
+
return mask64
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// vkbHide SYS 159: 收起 Windows 屏幕/触摸键盘 -> 0 成功 / -1 不可用。
|
|
163
|
+
func (vm *vmState) vkbHide() uint64 {
|
|
164
|
+
if guiVkbHide() {
|
|
165
|
+
return 0
|
|
166
|
+
}
|
|
167
|
+
return mask64
|
|
168
|
+
}
|
|
169
|
+
|
|
139
170
|
func guiInjectKey(code uint64) {
|
|
140
171
|
keyMu.Lock()
|
|
141
172
|
keyQueue = append(keyQueue, code)
|
|
@@ -40,6 +40,7 @@ const (
|
|
|
40
40
|
wmKeydown = 0x0100
|
|
41
41
|
wmChar = 0x0102
|
|
42
42
|
wmSyskeydown = 0x0104
|
|
43
|
+
wmUnichar = 0x0109 // UTF-32 字符提交 (输入法/虚拟键盘)
|
|
43
44
|
wmMousemove = 0x0200
|
|
44
45
|
wmLbuttondown = 0x0201
|
|
45
46
|
wmLbuttonup = 0x0202
|
|
@@ -47,6 +48,9 @@ const (
|
|
|
47
48
|
wmRbuttonup = 0x0205
|
|
48
49
|
wmMbuttondown = 0x0207
|
|
49
50
|
wmMbuttonup = 0x0208
|
|
51
|
+
wmImeChar = 0x0286 // IME/触摸键盘提交的 UTF-16 字符
|
|
52
|
+
|
|
53
|
+
unicodeNoChar = 0xFFFF // WM_UNICHAR 探测: 应答复 1 表示支持
|
|
50
54
|
|
|
51
55
|
wsOverlappedWindow = 0x00CF0000
|
|
52
56
|
wsVisible = 0x10000000
|
|
@@ -316,6 +320,7 @@ func guiWndProc(hwnd uintptr, msg uintptr, wp, lp uintptr) uintptr {
|
|
|
316
320
|
}
|
|
317
321
|
return 0
|
|
318
322
|
case wmClose:
|
|
323
|
+
guiVkbHide() // 程序窗口关闭时连带收起触摸键盘
|
|
319
324
|
guiMarkClosed() // gui_closed() 置 1; 交给 DefWindowProc 销毁窗口
|
|
320
325
|
case wmDestroy:
|
|
321
326
|
// 窗口已销毁 (无论来自 gui_close 还是用户点 X): 清理句柄,
|
|
@@ -332,6 +337,16 @@ func guiWndProc(hwnd uintptr, msg uintptr, wp, lp uintptr) uintptr {
|
|
|
332
337
|
case wmChar:
|
|
333
338
|
guiWinChar(wp, lp)
|
|
334
339
|
return 0
|
|
340
|
+
case wmImeChar:
|
|
341
|
+
// IME / 屏幕键盘提交的字符可能绕过 WM_CHAR
|
|
342
|
+
guiWinChar(wp, lp)
|
|
343
|
+
return 0
|
|
344
|
+
case wmUnichar:
|
|
345
|
+
if wp == unicodeNoChar {
|
|
346
|
+
return 1 // 宣告本窗口支持 WM_UNICHAR
|
|
347
|
+
}
|
|
348
|
+
guiWinUniChar(wp)
|
|
349
|
+
return 0
|
|
335
350
|
case wmSyskeydown:
|
|
336
351
|
// Alt+F4 等交给 DefWindowProc (产生 WM_CLOSE)
|
|
337
352
|
case wmMousemove:
|
|
@@ -366,14 +381,7 @@ func guiWinKeyDown(vk, lp uintptr) {
|
|
|
366
381
|
if repeat > 8 {
|
|
367
382
|
repeat = 8
|
|
368
383
|
}
|
|
369
|
-
|
|
370
|
-
if s, _, _ := procGetKeyState.Call(vkShift); s&0x8000 != 0 {
|
|
371
|
-
state |= ksShift
|
|
372
|
-
}
|
|
373
|
-
if s, _, _ := procGetKeyState.Call(vkControl); s&0x8000 != 0 {
|
|
374
|
-
state |= ksLeftCtrl
|
|
375
|
-
}
|
|
376
|
-
if code, ok := consoleKeyCode(uint16(vk), 0, state); ok {
|
|
384
|
+
if code, ok := consoleKeyCode(uint16(vk), 0, guiWinKeyState()); ok {
|
|
377
385
|
guiInjectKey(code)
|
|
378
386
|
for i := 1; i < repeat; i++ {
|
|
379
387
|
guiInjectKey(code)
|
|
@@ -381,7 +389,8 @@ func guiWinKeyDown(vk, lp uintptr) {
|
|
|
381
389
|
}
|
|
382
390
|
}
|
|
383
391
|
|
|
384
|
-
// guiWinChar WM_CHAR: UTF-16 字符
|
|
392
|
+
// guiWinChar WM_CHAR / WM_IME_CHAR: UTF-16 字符
|
|
393
|
+
// (含代理对组合 / Ctrl+字母控制字节)。
|
|
385
394
|
func guiWinChar(wp, lp uintptr) {
|
|
386
395
|
repeat := int(lp & 0xFFFF)
|
|
387
396
|
if repeat < 1 {
|
|
@@ -390,6 +399,29 @@ func guiWinChar(wp, lp uintptr) {
|
|
|
390
399
|
if repeat > 8 {
|
|
391
400
|
repeat = 8
|
|
392
401
|
}
|
|
402
|
+
if code, ok := consoleKeyCode(0, rune(wp), guiWinKeyState()); ok {
|
|
403
|
+
guiInjectKey(code)
|
|
404
|
+
for i := 1; i < repeat; i++ {
|
|
405
|
+
guiInjectKey(code)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// guiWinUniChar WM_UNICHAR: UTF-32 字符 (虚拟键盘/输入法的文本提交通道)。
|
|
411
|
+
func guiWinUniChar(wp uintptr) {
|
|
412
|
+
if wp > 0x10FFFF || (wp >= 0xD800 && wp <= 0xDFFF) {
|
|
413
|
+
return // 越界码点或裸代理项: 丢弃
|
|
414
|
+
}
|
|
415
|
+
if wp == 0 {
|
|
416
|
+
return
|
|
417
|
+
}
|
|
418
|
+
if code, ok := consoleKeyCode(0, rune(wp), guiWinKeyState()); ok {
|
|
419
|
+
guiInjectKey(code)
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// guiWinKeyState 取当前 Shift/Ctrl 状态位 (与控制台 dwControlKeyState 对齐)。
|
|
424
|
+
func guiWinKeyState() uint32 {
|
|
393
425
|
state := uint32(0)
|
|
394
426
|
if s, _, _ := procGetKeyState.Call(vkShift); s&0x8000 != 0 {
|
|
395
427
|
state |= ksShift
|
|
@@ -397,12 +429,7 @@ func guiWinChar(wp, lp uintptr) {
|
|
|
397
429
|
if s, _, _ := procGetKeyState.Call(vkControl); s&0x8000 != 0 {
|
|
398
430
|
state |= ksLeftCtrl
|
|
399
431
|
}
|
|
400
|
-
|
|
401
|
-
guiInjectKey(code)
|
|
402
|
-
for i := 1; i < repeat; i++ {
|
|
403
|
-
guiInjectKey(code)
|
|
404
|
-
}
|
|
405
|
-
}
|
|
432
|
+
return state
|
|
406
433
|
}
|
|
407
434
|
|
|
408
435
|
// guiMouseXY lParam 拆坐标 (16 位有符号)。
|
|
@@ -424,3 +451,154 @@ func rgbaToBgra(pix []byte, w, h int) {
|
|
|
424
451
|
winScratch[i+3] = 0
|
|
425
452
|
}
|
|
426
453
|
}
|
|
454
|
+
|
|
455
|
+
// ---------------- 虚拟键盘 (Windows 屏幕/触摸键盘) ----------------
|
|
456
|
+
//
|
|
457
|
+
// 通过 WinRT InputPane 的桌面互操作接口为指定顶层窗口弹出/收起触摸键盘
|
|
458
|
+
// (TabTip / 输入体验)。这类键盘的按键由系统注入 (WM_KEYDOWN VK_PACKET +
|
|
459
|
+
// WM_CHAR / WM_IME_CHAR / WM_UNICHAR), 已由窗口过程统一转入按键队列,
|
|
460
|
+
// 因此 get_key 无需感知按键来源。
|
|
461
|
+
|
|
462
|
+
var (
|
|
463
|
+
combaseDLL = syscall.NewLazyDLL("combase.dll")
|
|
464
|
+
procRoInitialize = combaseDLL.NewProc("RoInitialize")
|
|
465
|
+
procRoGetActivationFactory = combaseDLL.NewProc("RoGetActivationFactory")
|
|
466
|
+
procWindowsCreateString = combaseDLL.NewProc("WindowsCreateString")
|
|
467
|
+
procWindowsDeleteString = combaseDLL.NewProc("WindowsDeleteString")
|
|
468
|
+
procGetConsoleWindow = kernel32.NewProc("GetConsoleWindow")
|
|
469
|
+
procIsWindowVisible = user32.NewProc("IsWindowVisible")
|
|
470
|
+
procGetForegroundWindow = user32.NewProc("GetForegroundWindow")
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
// winGUID GUID (Data1..Data4, sizeof=16)。
|
|
474
|
+
type winGUID struct {
|
|
475
|
+
Data1 uint32
|
|
476
|
+
Data2 uint16
|
|
477
|
+
Data3 uint16
|
|
478
|
+
Data4 [8]byte
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
var (
|
|
482
|
+
// IInputPaneInterop (Win32 桌面互操作, inputpaneinterop.h)
|
|
483
|
+
iidInputPaneInterop = winGUID{0x75CF2C57, 0x9195, 0x4931,
|
|
484
|
+
[8]byte{0x83, 0x32, 0xF0, 0xB4, 0x09, 0xE9, 0x16, 0xAF}}
|
|
485
|
+
// IInputPane2 提供 TryShow / TryHide
|
|
486
|
+
iidInputPane2 = winGUID{0x8A6B3F26, 0x7090, 0x4793,
|
|
487
|
+
[8]byte{0x94, 0x4C, 0xC3, 0xF2, 0xCD, 0xE2, 0x62, 0x76}}
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
const (
|
|
491
|
+
vtRelease = 2 // IUnknown::Release
|
|
492
|
+
vtFirstMethod = 6 // IUnknown(3) + IInspectable(3) 之后的第一个接口方法
|
|
493
|
+
vtInputPaneShow = vtFirstMethod // IInputPane2::TryShow
|
|
494
|
+
vtInputPaneHide = vtFirstMethod + 1 // IInputPane2::TryHide
|
|
495
|
+
rpcEChangedMode = 0x80010106
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
// winVtFn 读取 COM 对象虚表第 idx 项的函数指针。
|
|
499
|
+
func winVtFn(obj unsafe.Pointer, idx int) uintptr {
|
|
500
|
+
vt := *(*unsafe.Pointer)(obj)
|
|
501
|
+
return *(*uintptr)(unsafe.Add(vt, uintptr(idx)*unsafe.Sizeof(uintptr(0))))
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// guiVkbTargetHwnd 虚拟键盘的绑定窗口: 优先 GUI 窗口; 终端模式下用可见的
|
|
505
|
+
// 控制台窗口; ConPTY (Windows Terminal) / 无控制台时退回前台窗口。
|
|
506
|
+
func guiVkbTargetHwnd() uintptr {
|
|
507
|
+
guiWinMu.Lock()
|
|
508
|
+
h := guiWinHwnd
|
|
509
|
+
guiWinMu.Unlock()
|
|
510
|
+
if h != 0 {
|
|
511
|
+
return h
|
|
512
|
+
}
|
|
513
|
+
if ch, _, _ := procGetConsoleWindow.Call(); ch != 0 {
|
|
514
|
+
if v, _, _ := procIsWindowVisible.Call(ch); v != 0 {
|
|
515
|
+
return ch
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
fg, _, _ := procGetForegroundWindow.Call()
|
|
519
|
+
return fg
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// guiVkbAction 在 STA 线程上取得目标窗口的 IInputPane2 并调用 TryShow/TryHide。
|
|
523
|
+
func guiVkbAction(show bool) bool {
|
|
524
|
+
hwnd := guiVkbTargetHwnd()
|
|
525
|
+
if hwnd == 0 {
|
|
526
|
+
return false
|
|
527
|
+
}
|
|
528
|
+
// InputPane 只支持 STA: 固定 OS 线程并初始化单线程套间。
|
|
529
|
+
// 已初始化时 RoInitialize 返回 S_FALSE (1), 仍可继续。
|
|
530
|
+
runtime.LockOSThread()
|
|
531
|
+
defer runtime.UnlockOSThread()
|
|
532
|
+
if hr, _, _ := procRoInitialize.Call(0 /*RO_INIT_SINGLETHREADED*/); int32(hr) < 0 &&
|
|
533
|
+
uint32(hr) != rpcEChangedMode {
|
|
534
|
+
return false
|
|
535
|
+
}
|
|
536
|
+
name := "Windows.UI.ViewManagement.InputPane"
|
|
537
|
+
u16, _ := syscall.UTF16FromString(name)
|
|
538
|
+
var hstr uintptr
|
|
539
|
+
if hr, _, _ := procWindowsCreateString.Call(uintptr(unsafe.Pointer(&u16[0])),
|
|
540
|
+
uintptr(len(u16)-1), uintptr(unsafe.Pointer(&hstr))); int32(hr) < 0 || hstr == 0 {
|
|
541
|
+
return false
|
|
542
|
+
}
|
|
543
|
+
defer procWindowsDeleteString.Call(hstr)
|
|
544
|
+
var factory unsafe.Pointer
|
|
545
|
+
if hr, _, _ := procRoGetActivationFactory.Call(hstr,
|
|
546
|
+
uintptr(unsafe.Pointer(&iidInputPaneInterop)),
|
|
547
|
+
uintptr(unsafe.Pointer(&factory))); int32(hr) < 0 || factory == nil {
|
|
548
|
+
return false
|
|
549
|
+
}
|
|
550
|
+
defer syscall.SyscallN(winVtFn(factory, vtRelease), uintptr(factory))
|
|
551
|
+
var pane unsafe.Pointer
|
|
552
|
+
if hr, _, _ := syscall.SyscallN(winVtFn(factory, vtFirstMethod), uintptr(factory), hwnd,
|
|
553
|
+
uintptr(unsafe.Pointer(&iidInputPane2)),
|
|
554
|
+
uintptr(unsafe.Pointer(&pane))); int32(hr) < 0 || pane == nil {
|
|
555
|
+
return false
|
|
556
|
+
}
|
|
557
|
+
defer syscall.SyscallN(winVtFn(pane, vtRelease), uintptr(pane))
|
|
558
|
+
idx := vtInputPaneShow
|
|
559
|
+
if !show {
|
|
560
|
+
idx = vtInputPaneHide
|
|
561
|
+
}
|
|
562
|
+
var ret byte // WinRT boolean (1 字节)
|
|
563
|
+
hr, _, _ := syscall.SyscallN(winVtFn(pane, idx), uintptr(pane),
|
|
564
|
+
uintptr(unsafe.Pointer(&ret)))
|
|
565
|
+
return int32(hr) >= 0 && ret != 0
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// vkbWinShown 记录触摸键盘是否由本程序弹出 (退出时据此收起)。
|
|
569
|
+
var (
|
|
570
|
+
vkbWinMu sync.Mutex
|
|
571
|
+
vkbWinShown bool
|
|
572
|
+
)
|
|
573
|
+
|
|
574
|
+
// guiVkbShow 弹出屏幕/触摸键盘。
|
|
575
|
+
func guiVkbShow() bool {
|
|
576
|
+
vkbWinMu.Lock()
|
|
577
|
+
defer vkbWinMu.Unlock()
|
|
578
|
+
ok := guiVkbAction(true)
|
|
579
|
+
if ok {
|
|
580
|
+
vkbWinShown = true
|
|
581
|
+
}
|
|
582
|
+
return ok
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// guiVkbHide 收起屏幕/触摸键盘。
|
|
586
|
+
func guiVkbHide() bool {
|
|
587
|
+
vkbWinMu.Lock()
|
|
588
|
+
defer vkbWinMu.Unlock()
|
|
589
|
+
ok := guiVkbAction(false)
|
|
590
|
+
if ok {
|
|
591
|
+
vkbWinShown = false
|
|
592
|
+
}
|
|
593
|
+
return ok
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// vkbProcessCleanup 程序退出时收起本程序弹出的触摸键盘。
|
|
597
|
+
func vkbProcessCleanup() {
|
|
598
|
+
vkbWinMu.Lock()
|
|
599
|
+
defer vkbWinMu.Unlock()
|
|
600
|
+
if vkbWinShown {
|
|
601
|
+
_ = guiVkbAction(false)
|
|
602
|
+
vkbWinShown = false
|
|
603
|
+
}
|
|
604
|
+
}
|
|
@@ -521,9 +521,11 @@ const sysUDPSENDTO = 154
|
|
|
521
521
|
const sysUDPRECVFROM = 155
|
|
522
522
|
const sysUDPCLOSE = 156
|
|
523
523
|
const sysDNSLOOKUP = 157
|
|
524
|
+
const sysVKBSHOW = 158
|
|
525
|
+
const sysVKBHIDE = 159
|
|
524
526
|
|
|
525
527
|
// SYS 功能号名 (按下标索引, 用于错误信息; 与 isa.py Syscall 名一致)
|
|
526
|
-
var syscallNames = [
|
|
528
|
+
var syscallNames = [160]string{
|
|
527
529
|
sysSQRT: "SQRT",
|
|
528
530
|
sysPOW: "POW",
|
|
529
531
|
sysABS: "ABS",
|
|
@@ -682,4 +684,6 @@ var syscallNames = [158]string{
|
|
|
682
684
|
sysUDPRECVFROM: "UDPRECVFROM",
|
|
683
685
|
sysUDPCLOSE: "UDPCLOSE",
|
|
684
686
|
sysDNSLOOKUP: "DNSLOOKUP",
|
|
687
|
+
sysVKBSHOW: "VKBSHOW",
|
|
688
|
+
sysVKBHIDE: "VKBHIDE",
|
|
685
689
|
}
|
|
@@ -87,6 +87,32 @@ func TestConsoleKeyCodeSurrogatePair(t *testing.T) {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
// 屏幕/触摸键盘以 KEYEVENTF_UNICODE 注入字符时, conhost 给出
|
|
91
|
+
// VK_PACKET + UnicodeChar 的 KEY_EVENT; 必须按字符入队而不是丢弃。
|
|
92
|
+
func TestDecodeKeyEventVKPacket(t *testing.T) {
|
|
93
|
+
resetKeyState()
|
|
94
|
+
defer resetKeyState()
|
|
95
|
+
rec := make([]byte, 16)
|
|
96
|
+
putLE32(rec[0:4], 1)
|
|
97
|
+
putLE16(rec[4:6], 1)
|
|
98
|
+
putLE16(rec[6:8], 0xE7) // VK_PACKET
|
|
99
|
+
putLE16(rec[10:12], '中')
|
|
100
|
+
code, ok := decodeKeyEvent(rec)
|
|
101
|
+
if !ok || code != '中' {
|
|
102
|
+
t.Fatalf("VK_PACKET 应产出字符 '中', 实际 %d ok=%v", code, ok)
|
|
103
|
+
}
|
|
104
|
+
// 高代理 + 低代理连续两次注入 (emoji) 仍应组合成完整码点
|
|
105
|
+
putLE16(rec[10:12], 0xD83D)
|
|
106
|
+
if _, ok := decodeKeyEvent(rec); ok {
|
|
107
|
+
t.Fatal("VK_PACKET 高代理不应单独入队")
|
|
108
|
+
}
|
|
109
|
+
putLE16(rec[10:12], 0xDE00) // U+1F600
|
|
110
|
+
code, ok = decodeKeyEvent(rec)
|
|
111
|
+
if !ok || code != 0x1F600 {
|
|
112
|
+
t.Fatalf("VK_PACKET 代理对应组合为 0x1F600, 实际 %d ok=%v", code, ok)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
90
116
|
func putLE16(b []byte, v uint16) { b[0] = byte(v); b[1] = byte(v >> 8) }
|
|
91
117
|
|
|
92
118
|
func putLE32(b []byte, v uint32) {
|