summaryrefslogtreecommitdiff
path: root/ext/io/console/console.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-31 23:01:46 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-31 23:01:46 +0000
commitf4234c9b8f4707c5979d9a3beddc19ceeb417bd8 (patch)
tree425d8e69662b29d72adb810c4eaf980c1a1a461e /ext/io/console/console.c
parentc90d5be882ea616e281361fa72bce8bae8f4f8d3 (diff)
* 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
Diffstat (limited to 'ext/io/console/console.c')
-rw-r--r--ext/io/console/console.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/ext/io/console/console.c b/ext/io/console/console.c
index 299a0ccf365..f7f95e933fb 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);