class Kaitai::ConsoleWindows

Constants

CHAR_BL
CHAR_BR
CHAR_H
CHAR_TL
CHAR_TR
CHAR_V
COLORS
DOUBLE_CHARSET
E0_ESCAPE
FILL_CONSOLE_OUTPUT_ATTRIBUTE
FILL_CONSOLE_OUTPUT_CHARACTER
GETCH
GET_CONSOLE_SCREEN_BUFFER_INFO
GET_STD_HANDLE
HEAVY_CHARSET
KEY_MAP
SET_CONSOLE_CURSOR_POSITION
SET_CONSOLE_TEXT_ATTRIBUTE
SINGLE_CHARSET
WRITE_CONSOLE
ZERO_ESCAPE

Attributes

cols[R]
rows[R]

Public Class Methods

is_windows?() click to toggle source

Detects if current platform is Windows-based.

# File lib/kaitai/console_windows.rb, line 243
def self.is_windows?
  @@is_windows
end
new() click to toggle source
# File lib/kaitai/console_windows.rb, line 23
def initialize
  @stdin_handle = GET_STD_HANDLE.call(-10)
  @stdout_handle = GET_STD_HANDLE.call(-11)
  @fg_color = 7
  @bg_color = 0

  # typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
  #   COORD      dwSize;
  #   COORD      dwCursorPosition;
  #   WORD       wAttributes;
  #   SMALL_RECT srWindow;
  #   COORD      dwMaximumWindowSize;
  # } CONSOLE_SCREEN_BUFFER_INFO;

  # 4 + 4 + 2 + 4 * 2 + 4 = 22
     
  csbi = 'X' * 22
  
  GET_CONSOLE_SCREEN_BUFFER_INFO.call(@stdout_handle, csbi)
  @buf_cols, @buf_rows,
    cur_x, cur_y, cur_attr,
    win_left, win_top, win_right, win_bottom,
    max_win_x, max_win_y = csbi.unpack('vvvvvvvvvvv')

  # Getting size of actual visible portion of Windows console
  # http://stackoverflow.com/a/12642749/487064
  @cols = win_right - win_left + 1
  @rows = win_bottom - win_top + 1
end

Public Instance Methods

bg_color=(col) click to toggle source
# File lib/kaitai/console_windows.rb, line 118
def bg_color=(col)
  code = COLORS[col]
  raise "Invalid color: #{col}" unless code
  @bg_color = code
  update_colors
end
clear() click to toggle source
# File lib/kaitai/console_windows.rb, line 64
def clear
  con_size = @buf_cols * @buf_rows
  num_written = 'XXXX'
  FILL_CONSOLE_OUTPUT_CHARACTER.call(
    @stdout_handle,
    0x20, # ' '
    con_size,
    0, # [0, 0] coords
    num_written
  )
  FILL_CONSOLE_OUTPUT_ATTRIBUTE.call(
    @stdout_handle,
    current_color_code,
    con_size,
    0, # [0, 0] coords
    num_written
  )
  goto(0, 0)
end
draw_button(x, y, w, caption) click to toggle source
# File lib/kaitai/console_windows.rb, line 233
def draw_button(x, y, w, caption)
  goto(x, y)
  puts "[ #{caption} ]"
end
draw_rectangle(x, y, w, h, charset = DOUBLE_CHARSET) click to toggle source
# File lib/kaitai/console_windows.rb, line 214
def draw_rectangle(x, y, w, h, charset = DOUBLE_CHARSET)
  goto(x, y)
  print charset[CHAR_TL]
  print charset[CHAR_H] * (w - 2)
  print charset[CHAR_TR]

  ((y + 1)..(y + h - 1)).each { |i|
    goto(x, i)
    print charset[CHAR_V]
    print ' ' * (w - 2)
    print charset[CHAR_V]
  }

  goto(x, y + h)
  print charset[CHAR_BL]
  print charset[CHAR_H] * (w - 2)
  print charset[CHAR_BR]
end
fg_color=(col) click to toggle source
# File lib/kaitai/console_windows.rb, line 111
def fg_color=(col)
  code = COLORS[col]
  raise "Invalid color: #{col}" unless code
  @fg_color = code
  update_colors
end
goto(x, y) click to toggle source

Put the cursor up to screen position (x, y). First line is 0, first column is 0.

# File lib/kaitai/console_windows.rb, line 87
def goto(x, y)
  coord = [x, y].pack('vv').unpack('V')[0]
  SET_CONSOLE_CURSOR_POSITION.call(@stdout_handle, coord)
end
input_str(header, msg) click to toggle source
# File lib/kaitai/console_windows.rb, line 204
def input_str(header, msg)
  top_y = @rows / 2 - 5
  draw_rectangle(10, top_y, @cols - 20, 10)
  goto(@cols / 2 - (header.length / 2) - 1, top_y)
  print ' ', header, ' '

  goto(11, top_y + 1)
  Readline.readline('', false)
end
message_box(header, msg) click to toggle source
# File lib/kaitai/console_windows.rb, line 190
def message_box(header, msg)
  top_y = @rows / 2 - 5
  draw_rectangle(10, top_y, @cols - 20, 10)
  goto(@cols / 2 - (header.length / 2) - 1, top_y)
  print ' ', header, ' '
  goto(11, top_y + 1)
  puts msg
  draw_button(@cols / 2 - 10, top_y + 8, 10, 'OK')
  loop {
    c = read_char_mapped
    return if c == :enter
  }
end
message_box_exception(e) click to toggle source
# File lib/kaitai/console_windows.rb, line 175
def message_box_exception(e)
  message_box("Error while parsing", e.message)
end
on_resize=(handler) click to toggle source
# File lib/kaitai/console_windows.rb, line 53
def on_resize=(handler)
  @on_resize = handler
end
puts(s) click to toggle source
# File lib/kaitai/console_windows.rb, line 57
  def puts(s)
    Kernel::puts s
#    num_written = 'XXXX'
#    reserved = 'XXXX'
#    WRITE_CONSOLE.call(@stdout_handle, s, s.length, num_written, reserved)
  end
read_char() click to toggle source

Reads keypresses from the user including 2 and 3 escape character sequences.

# File lib/kaitai/console_windows.rb, line 135
def read_char
  input = GETCH.call.chr
  if input == E0_ESCAPE || input == ZERO_ESCAPE
    input << GETCH.call.chr
  end
  return input
end
read_char_mapped() click to toggle source
# File lib/kaitai/console_windows.rb, line 143
def read_char_mapped
  c = read_char
  c2 = KEY_MAP[c]
  c2 ? c2 : c
end
reset_colors() click to toggle source
# File lib/kaitai/console_windows.rb, line 125
def reset_colors
  @fg_color = 7
  @bg_color = 0
  update_colors
end

Private Instance Methods

current_color_code() click to toggle source
# File lib/kaitai/console_windows.rb, line 248
def current_color_code
  (@bg_color << 4) | @fg_color
end
update_colors() click to toggle source
# File lib/kaitai/console_windows.rb, line 252
def update_colors
  SET_CONSOLE_TEXT_ATTRIBUTE.call(@stdout_handle, current_color_code)
end