Module: Ruby2D::CLI::Browser::WinConsole
- Defined in:
- lib/ruby2d/cli/browser.rb
Overview
Drives the Win32 console input mode through SetConsoleMode, because
native-Windows Ruby's io/console raw is unreliable here (confirmed on
aarch64-mingw-ucrt: raw left LINE/ECHO input enabled). Enabling
VIRTUAL_TERMINAL_INPUT is what makes arrow keys arrive as \e[A
sequences instead of being swallowed. All Fiddle use is lazy and
failure-tolerant: any problem returns nil and the caller falls back to
the plain io/console path.
Constant Summary collapse
- STD_INPUT_HANDLE =
-10
- PROCESSED_INPUT =
0x0001- LINE_INPUT =
0x0002- ECHO_INPUT =
0x0004- VT_INPUT =
0x0200
Class Method Summary collapse
-
.api ⇒ Object
Lazily resolve the three kernel32 calls we need; memoize the result (nil if Fiddle or the console API is unavailable).
-
.enable_raw ⇒ Object
Switch the console to raw + virtual-terminal input.
-
.reassert_raw ⇒ Object
Re-apply raw + VT without disturbing the saved prior mode — used after a child example returns, in case it left the shared console mode changed.
- .restore(prev) ⇒ Object
Class Method Details
.api ⇒ Object
Lazily resolve the three kernel32 calls we need; memoize the result (nil if Fiddle or the console API is unavailable).
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ruby2d/cli/browser.rb', line 39 def self.api unless @resolved @resolved = true @api = begin require 'fiddle' k32 = Fiddle.dlopen('kernel32') { get_handle: Fiddle::Function.new(k32['GetStdHandle'], [Fiddle::TYPE_LONG], Fiddle::TYPE_VOIDP), get_mode: Fiddle::Function.new(k32['GetConsoleMode'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT), set_mode: Fiddle::Function.new(k32['SetConsoleMode'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG], Fiddle::TYPE_INT) } rescue LoadError, StandardError nil end end @api end |
.enable_raw ⇒ Object
Switch the console to raw + virtual-terminal input. Returns the prior
mode (to hand back to restore), or nil when there's no console to set
(Fiddle missing, stdin redirected, GetConsoleMode failed).
61 62 63 64 65 66 67 68 69 |
# File 'lib/ruby2d/cli/browser.rb', line 61 def self.enable_raw fns = api or return nil handle = fns[:get_handle].call(STD_INPUT_HANDLE) buf = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT, Fiddle::RUBY_FREE) return nil if fns[:get_mode].call(handle, buf) == 0 prev = buf[0, Fiddle::SIZEOF_INT].unpack1('L') fns[:set_mode].call(handle, (prev & ~(LINE_INPUT | ECHO_INPUT | PROCESSED_INPUT)) | VT_INPUT) prev end |
.reassert_raw ⇒ Object
Re-apply raw + VT without disturbing the saved prior mode — used after a child example returns, in case it left the shared console mode changed.
74 75 76 |
# File 'lib/ruby2d/cli/browser.rb', line 74 def self.reassert_raw enable_raw end |
.restore(prev) ⇒ Object
78 79 80 81 82 |
# File 'lib/ruby2d/cli/browser.rb', line 78 def self.restore(prev) return if prev.nil? fns = api or return fns[:set_mode].call(fns[:get_handle].call(STD_INPUT_HANDLE), prev) end |