ruby-changes:18725
From: nobu <ko1@a...>
Date: Tue, 1 Feb 2011 08:01:56 +0900 (JST)
Subject: [ruby-changes:18725] Ruby:r30751 (trunk): * ext/io/console/console.c (console_set_winsize): new method to set
nobu 2011-02-01 08:01:46 +0900 (Tue, 01 Feb 2011) New Revision: 30751 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30751 Log: * ext/io/console/console.c (console_set_winsize): new method to set console size. [EXPERIMENTAL] Modified files: trunk/ChangeLog trunk/ext/io/console/console.c Index: ChangeLog =================================================================== --- ChangeLog (revision 30750) +++ ChangeLog (revision 30751) @@ -1,5 +1,8 @@ -Tue Feb 1 07:56:02 2011 Nobuyoshi Nakada <nobu@r...> +Tue Feb 1 08:01:39 2011 Nobuyoshi Nakada <nobu@r...> + * ext/io/console/console.c (console_set_winsize): new method to set + console size. [EXPERIMENTAL] + * ext/io/console/console.c (console_winsize): use GetWriteFD. Tue Feb 1 02:28:14 2011 Masaya Tarui <tarui@r...> Index: ext/io/console/console.c =================================================================== --- ext/io/console/console.c (revision 30750) +++ ext/io/console/console.c (revision 30751) @@ -357,6 +357,7 @@ #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,8 +392,65 @@ 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 + /* * call-seq: * io.iflush @@ -547,6 +605,7 @@ 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); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/