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/