From f4234c9b8f4707c5979d9a3beddc19ceeb417bd8 Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 31 Jan 2011 23:01:46 +0000 Subject: * ext/io/console/console.c (console_set_winsize): new method to set console size. [EXPERIMENTAL] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/io/console/console.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'ext/io/console') diff --git a/ext/io/console/console.c b/ext/io/console/console.c index 299a0ccf36..f7f95e933f 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -357,6 +357,7 @@ console_echo_p(VALUE io) #if defined TIOCGWINSZ typedef struct winsize rb_console_size_t; #define getwinsize(fd, buf) (ioctl((fd), TIOCGWINSZ, (buf)) == 0) +#define setwinsize(fd, buf) (ioctl((fd), TIOCSWINSZ, (buf)) == 0) #define winsize_row(buf) (buf)->ws_row #define winsize_col(buf) (buf)->ws_col #elif defined _WIN32 @@ -391,6 +392,63 @@ console_winsize(VALUE io) if (!getwinsize(fd, &ws)) rb_sys_fail(0); return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws))); } + +/* + * call-seq: + * io.winsize = [rows, columns] + * + * Tries to set console size. The effect depends on the platform and + * the running environment. + */ +static VALUE +console_set_winsize(VALUE io, VALUE size) +{ + rb_io_t *fptr; + rb_console_size_t ws; +#if defined _WIN32 + HANDLE wh; + int newrow, newcol; +#endif + VALUE row, col, xpixel, ypixel; + int fd; + + GetOpenFile(io, fptr); + size = rb_Array(size); + rb_scan_args(RARRAY_LEN(size), RARRAY_PTR(size), "22", + &row, &col, &xpixel, &ypixel); +#if defined TIOCSWINSZ + fd = GetWriteFD(fptr); + ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0; +#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) + SET(row); + SET(col); + SET(xpixel); + SET(ypixel); +#undef SET + if (!setwinsize(fd, &ws)) rb_sys_fail(0); +#elif defined _WIN32 + wh = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr)); + newrow = (SHORT)NUM2UINT(row); + newcol = (SHORT)NUM2UINT(col); + if (!getwinsize(GetReadFD(fptr), &ws)) { + rb_sys_fail("GetConsoleScreenBufferInfo"); + } + if ((ws.dwSize.X < newcol && (ws.dwSize.X = newcol, 1)) || + (ws.dwSize.Y < newrow && (ws.dwSize.Y = newrow, 1))) { + if (!(SetConsoleScreenBufferSize(wh, ws.dwSize) || SET_LAST_ERROR)) { + rb_sys_fail("SetConsoleScreenBufferInfo"); + } + } + ws.srWindow.Left = 0; + ws.srWindow.Top = 0; + ws.srWindow.Right = newcol; + ws.srWindow.Bottom = newrow; + if (!(SetConsoleWindowInfo(wh, FALSE, &ws.srWindow) || SET_LAST_ERROR)) { + rb_sys_fail("SetConsoleWindowInfo"); + } +#endif + return io; +} #endif /* @@ -547,6 +605,7 @@ InitVM_console(void) rb_define_method(rb_cIO, "echo?", console_echo_p, 0); rb_define_method(rb_cIO, "noecho", console_noecho, 0); rb_define_method(rb_cIO, "winsize", console_winsize, 0); + rb_define_method(rb_cIO, "winsize=", console_set_winsize, 1); rb_define_method(rb_cIO, "iflush", console_iflush, 0); rb_define_method(rb_cIO, "oflush", console_oflush, 0); rb_define_method(rb_cIO, "ioflush", console_ioflush, 0); -- cgit v1.2.3