[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]