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.
The following implementation will work on Windows: (for simplicity it uses
LibCdeclarations in the standard library rather than copying the used definitions into a separate, private lib)In case you are wondering, this is how
ioctlfrom Cygwin's runtime does it as well, soflag?(:win32)will suffice, not justflag?(: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#sizecontinue to try all alternatives.