Skip to content

Windows support #5

@HertzDevil

Description

@HertzDevil

The following implementation will work on Windows: (for simplicity it uses LibC declarations in the standard library rather than copying the used definitions into a separate, private lib)

# consoleapi2.h
lib LibC
  struct COORD
    x : Short
    y : Short
  end

  struct SMALL_RECT
    left : Short
    up : Short
    right : Short
    bottom : Short
  end

  struct CONSOLE_SCREEN_BUFFER_INFO
    dwSize : COORD
    dwCursorPosition : COORD
    wAttributes : WORD
    srWindow : SMALL_RECT
    dwMaximumWindowSize : COORD
  end

  fun GetConsoleScreenBufferInfo(hConsoleOutput : HANDLE, lpConsoleScreenBufferInfo : CONSOLE_SCREEN_BUFFER_INFO*) : BOOL
end

module Term
  module Screen
    def size
      {% if flag?(:win32) %}
        check_size(size_from_win_api) ||
          check_size(size_from_default) ||
          size_from_default
      {% else %}
        # ...
      {% end %}
    end

    def size_from_win_api
      handle = LibC._get_osfhandle(STDOUT.fd)
      return nil if handle == -1

      ret = LibC.GetConsoleScreenBufferInfo(LibC::HANDLE.new(handle), out buffer_info)
      return nil if ret == 0

      lines = buffer_info.srWindow.right - buffer_info.srWindow.left + 1
      cols = buffer_info.srWindow.bottom - buffer_info.srWindow.up + 1
      {lines.to_i, cols.to_i}
    end
  end
end

In case you are wondering, this is how ioctl from Cygwin's runtime does it as well, so flag?(:win32) will suffice, not just flag?(:msvc):

For this to truly compile, all the POSIX-specific stuffs must be guarded away on Windows as well, and vice versa. The simplest solution is to guard the individual bodies of the size_from_* methods, and then let #size continue to try all alternatives.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions