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

ruby-changes:35159

From: nobu <ko1@a...>
Date: Thu, 21 Aug 2014 17:10:48 +0900 (JST)
Subject: [ruby-changes:35159] nobu:r47241 (trunk): win32.c: manage reverse video

nobu	2014-08-21 17:10:34 +0900 (Thu, 21 Aug 2014)

  New Revision: 47241

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47241

  Log:
    win32.c: manage reverse video
    
    * win32/win32.c (constat_attr): manage reverse video internally
      since Windows console window does not manage it.  based on the
      patch by white leaf in [ruby-dev:48483].  [Bug #10158]

  Added directories:
    trunk/ext/-test-/win32/console/
  Added files:
    trunk/ext/-test-/win32/console/attribute.c
    trunk/ext/-test-/win32/console/depend
    trunk/ext/-test-/win32/console/extconf.rb
    trunk/ext/-test-/win32/console/init.c
    trunk/test/-ext-/win32/test_console_attr.rb
  Modified files:
    trunk/ChangeLog
    trunk/win32/win32.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 47240)
+++ ChangeLog	(revision 47241)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Aug 21 17:10:31 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* win32/win32.c (constat_attr): manage reverse video internally
+	  since Windows console window does not manage it.  based on the
+	  patch by white leaf in [ruby-dev:48483].  [Bug #10158]
+
 Thu Aug 21 14:45:41 2014  SHIBATA Hiroshi  <shibata.hiroshi@g...>
 
 	* lib/e2mmap.rb: removed commented-out code.
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 47240)
+++ win32/win32.c	(revision 47241)
@@ -615,7 +615,7 @@ static char *uenvarea; https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L615
 /* License: Ruby's */
 struct constat {
     struct {
-	int state, seq[16];
+	int state, seq[16], reverse;
 	WORD attr;
 	COORD saved;
     } vt100;
@@ -5901,6 +5901,7 @@ constat_handle(HANDLE h) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5901
 	p = ALLOC(struct constat);
 	p->vt100.state = constat_init;
 	p->vt100.attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
+	p->vt100.reverse = 0;
 	p->vt100.saved.X = p->vt100.saved.Y = 0;
 	if (GetConsoleScreenBufferInfo(h, &csbi)) {
 	    p->vt100.attr = csbi.wAttributes;
@@ -5922,16 +5923,26 @@ constat_reset(HANDLE h) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5923
     p->vt100.state = constat_init;
 }
 
+#define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
+#define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
+
+#define constat_attr_color_reverse(attr) \
+    (attr) & ~(FOREGROUND_MASK | BACKGROUND_MASK) | \
+	   (((attr) & FOREGROUND_MASK) << 4) | \
+	   (((attr) & BACKGROUND_MASK) >> 4);
+
 /* License: Ruby's */
 static WORD
-constat_attr(int count, const int *seq, WORD attr, WORD default_attr)
+constat_attr(int count, const int *seq, WORD attr, WORD default_attr, int *reverse)
 {
-#define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
-#define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)
-    WORD bold = attr & (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
-    int rev = 0;
+    int rev = *reverse;
+    WORD bold;
 
     if (!count) return attr;
+    if (rev) attr = constat_attr_color_reverse(attr);
+    bold = attr & FOREGROUND_INTENSITY;
+    attr &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
+
     while (count-- > 0) {
 	switch (*seq++) {
 	  case 0:
@@ -5940,7 +5951,7 @@ constat_attr(int count, const int *seq, https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5951
 	    bold = 0;
 	    break;
 	  case 1:
-	    bold |= rev ? BACKGROUND_INTENSITY : FOREGROUND_INTENSITY;
+	    bold = FOREGROUND_INTENSITY;
 	    break;
 	  case 4:
 #ifndef COMMON_LVB_UNDERSCORE
@@ -6010,12 +6021,10 @@ constat_attr(int count, const int *seq, https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L6021
 	    break;
 	}
     }
-    if (rev) {
-	attr = attr & ~(FOREGROUND_MASK | BACKGROUND_MASK) |
-	    ((attr & FOREGROUND_MASK) << 4) |
-	    ((attr & BACKGROUND_MASK) >> 4);
-    }
-    return attr | bold;
+    attr |= bold;
+    if (rev) attr = constat_attr_color_reverse(attr);
+    *reverse = rev;
+    return attr;
 }
 
 /* License: Ruby's */
@@ -6033,7 +6042,7 @@ constat_apply(HANDLE handle, struct cons https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L6042
     if (count > 0 && seq[0] > 0) arg1 = seq[0];
     switch (w) {
       case L'm':
-	SetConsoleTextAttribute(handle, constat_attr(count, seq, csbi.wAttributes, s->vt100.attr));
+	SetConsoleTextAttribute(handle, constat_attr(count, seq, csbi.wAttributes, s->vt100.attr, &s->vt100.reverse));
 	break;
       case L'F':
 	csbi.dwCursorPosition.X = 0;
Index: ext/-test-/win32/console/depend
===================================================================
--- ext/-test-/win32/console/depend	(revision 0)
+++ ext/-test-/win32/console/depend	(revision 47241)
@@ -0,0 +1 @@
+attribute.o: $(ruby_headers) $(hdrdir)/ruby/win32.h

Property changes on: ext/-test-/win32/console/depend
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/win32/console/attribute.c
===================================================================
--- ext/-test-/win32/console/attribute.c	(revision 0)
+++ ext/-test-/win32/console/attribute.c	(revision 47241)
@@ -0,0 +1,44 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/win32/console/attribute.c#L1
+#include <ruby.h>
+
+static VALUE rb_cConsoleScreenBufferInfo;
+
+static VALUE
+console_info(VALUE io)
+{
+    int fd = NUM2INT(rb_funcallv(io, rb_intern("fileno"), 0, 0));
+    HANDLE h = (HANDLE)rb_w32_get_osfhandle(fd);
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+    if (h == (HANDLE)-1) rb_raise(rb_eIOError, "invalid io");
+    if (!GetConsoleScreenBufferInfo(h, &csbi))
+	rb_syserr_fail(rb_w32_map_errno(GetLastError()), "not console");
+    return rb_struct_new(rb_cConsoleScreenBufferInfo,
+			 INT2FIX(csbi.dwSize.X), INT2FIX(csbi.dwSize.Y),
+			 INT2FIX(csbi.dwCursorPosition.X), INT2FIX(csbi.dwCursorPosition.Y),
+			 INT2FIX(csbi.wAttributes));
+}
+
+#define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
+#define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
+
+void
+Init_attribute(VALUE m)
+{
+    rb_cConsoleScreenBufferInfo = rb_struct_define_under(m, "ConsoleScreenBufferInfo",
+							 "size_x", "size_y",
+							 "cur_x", "cur_y",
+							 "attr", NULL);
+    rb_define_method(rb_cIO, "console_info", console_info, 0);
+
+    rb_define_const(m, "FOREGROUND_MASK", INT2FIX(FOREGROUND_MASK));
+    rb_define_const(m, "FOREGROUND_BLUE", INT2FIX(FOREGROUND_BLUE));
+    rb_define_const(m, "FOREGROUND_GREEN", INT2FIX(FOREGROUND_GREEN));
+    rb_define_const(m, "FOREGROUND_RED", INT2FIX(FOREGROUND_RED));
+    rb_define_const(m, "FOREGROUND_INTENSITY", INT2FIX(FOREGROUND_INTENSITY));
+
+    rb_define_const(m, "BACKGROUND_MASK", INT2FIX(BACKGROUND_MASK));
+    rb_define_const(m, "BACKGROUND_BLUE", INT2FIX(BACKGROUND_BLUE));
+    rb_define_const(m, "BACKGROUND_GREEN", INT2FIX(BACKGROUND_GREEN));
+    rb_define_const(m, "BACKGROUND_RED", INT2FIX(BACKGROUND_RED));
+    rb_define_const(m, "BACKGROUND_INTENSITY", INT2FIX(BACKGROUND_INTENSITY));
+}

Property changes on: ext/-test-/win32/console/attribute.c
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/win32/console/init.c
===================================================================
--- ext/-test-/win32/console/init.c	(revision 0)
+++ ext/-test-/win32/console/init.c	(revision 47241)
@@ -0,0 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/win32/console/init.c#L1
+#include "ruby.h"
+
+#define init(n) {void Init_##n(VALUE m); Init_##n(m);}
+
+void
+Init_console(void)
+{
+    VALUE mBug = rb_define_module("Bug");
+    VALUE m = rb_define_module_under(mBug, "Win32");
+    TEST_INIT_FUNCS(init);
+}

Property changes on: ext/-test-/win32/console/init.c
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/win32/console/extconf.rb
===================================================================
--- ext/-test-/win32/console/extconf.rb	(revision 0)
+++ ext/-test-/win32/console/extconf.rb	(revision 47241)
@@ -0,0 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/win32/console/extconf.rb#L1
+if $mingw or $mswin
+  $srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
+  inits = $srcs.map {|s| File.basename(s, ".*")}
+  inits.delete("init")
+  inits.map! {|s|"X(#{s})"}
+  $defs << "-DTEST_INIT_FUNCS(X)=\"#{inits.join(' ')}\""
+  create_makefile("-test-/win32/console")
+end

Property changes on: ext/-test-/win32/console/extconf.rb
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: test/-ext-/win32/test_console_attr.rb
===================================================================
--- test/-ext-/win32/test_console_attr.rb	(revision 0)
+++ test/-ext-/win32/test_console_attr.rb	(revision 47241)
@@ -0,0 +1,44 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/win32/test_console_attr.rb#L1
+if /mswin|mingw/ =~ RUBY_PLATFORM and STDOUT.tty?
+  require '-test-/win32/console'
+  require 'io/console'
+  require 'test/unit'
+
+  class Test_Win32Console < Test::Unit::TestCase
+    def setup
+      print "\e[m!"
+    end
+
+    def teardown
+      print "\e[m!"
+    end
+
+    def test_default
+      info = STDOUT.console_info
+      assert_equal(7, info.attr);
+    end
+
+    def test_reverse
+      print "\e[7m"
+      info = STDOUT.console_info
+      assert_equal(0x70, info.attr);
+    end
+
+    def test_bold
+      print "\e[1m"
+      info = STDOUT.console_info
+      assert_equal(0x8, info.attr&0x8);
+    end
+
+    def test_bold_reverse
+      print "\e[1;7m"
+      info = STDOUT.console_info
+      assert_equal(0xf0, info.attr);
+    end
+
+    def test_reverse_bold
+      print "\e[7;1m"
+      info = STDOUT.console_info
+      assert_equal(0xf0, info.attr);
+    end
+  end
+end

Property changes on: test/-ext-/win32/test_console_attr.rb
___________________________________________________________________
Added: svn:eol-style
   + LF


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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