diff --git a/lib/textbringer/window.rb b/lib/textbringer/window.rb index 921a9eb..b4be844 100644 --- a/lib/textbringer/window.rb +++ b/lib/textbringer/window.rb @@ -2,45 +2,8 @@ require "curses" require "unicode/display_width" -require "fiddle/import" module Textbringer - # These features should be provided by curses.gem. - module PDCurses - KEY_OFFSET = 0xec00 - ALT_0 = KEY_OFFSET + 0x97 - ALT_9 = KEY_OFFSET + 0xa0 - ALT_A = KEY_OFFSET + 0xa1 - ALT_Z = KEY_OFFSET + 0xba - ALT_NUMBER_BASE = ALT_0 - ?0.ord - ALT_ALPHA_BASE = ALT_A - ?a.ord - - KEY_MODIFIER_SHIFT = 1 - KEY_MODIFIER_CONTROL = 2 - KEY_MODIFIER_ALT = 4 - KEY_MODIFIER_NUMLOCK = 8 - - @dll_loaded = false - - class << self - attr_writer :dll_loaded - - def dll_loaded? - @dll_loaded - end - end - - begin - extend Fiddle::Importer - dlload "pdcurses.dll" - extern "unsigned long PDC_get_key_modifiers(void)" - extern "int PDC_save_key_modifiers(unsigned char)" - extern "int PDC_return_key_modifiers(unsigned char)" - @dll_loaded = true - rescue Fiddle::DLError - end - end - class Window KEY_NAMES = {} Curses.constants.grep(/\AKEY_/).each do |name| @@ -48,6 +11,12 @@ class Window name.slice(/\AKEY_(.*)/, 1).downcase.intern end + HAVE_GET_KEY_MODIFIERS = defined?(Curses.get_key_modifiers) + if HAVE_GET_KEY_MODIFIERS + ALT_NUMBER_BASE = Curses::ALT_0 - ?0.ord + ALT_ALPHA_BASE = Curses::ALT_A - ?a.ord + end + @@started = false @@list = [] @@current = nil @@ -325,12 +294,12 @@ def current? def read_event key = get_char if key.is_a?(Integer) - if PDCurses.dll_loaded? - if PDCurses::ALT_0 <= key && key <= PDCurses::ALT_9 - @key_buffer.push((key - PDCurses::ALT_NUMBER_BASE).chr) + if HAVE_GET_KEY_MODIFIERS + if Curses::ALT_0 <= key && key <= Curses::ALT_9 + @key_buffer.push((key - ALT_NUMBER_BASE).chr) return "\e" - elsif PDCurses::ALT_A <= key && key <= PDCurses::ALT_Z - @key_buffer.push((key - PDCurses::ALT_ALPHA_BASE).chr) + elsif Curses::ALT_A <= key && key <= Curses::ALT_Z + @key_buffer.push((key - ALT_ALPHA_BASE).chr) return "\e" end end @@ -780,7 +749,7 @@ def delete_marks def get_char if @key_buffer.empty? - PDCurses.PDC_save_key_modifiers(1) if PDCurses.dll_loaded? + Curses.save_key_modifiers(true) if HAVE_GET_KEY_MODIFIERS begin need_retry = false if @raw_key_buffer.empty? @@ -788,13 +757,13 @@ def get_char else key = @raw_key_buffer.shift end - if PDCurses.dll_loaded? - mods = PDCurses.PDC_get_key_modifiers + if HAVE_GET_KEY_MODIFIERS + mods = Curses.get_key_modifiers if key.is_a?(String) && key.ascii_only? - if (mods & PDCurses::KEY_MODIFIER_CONTROL) != 0 + if (mods & Curses::PDC_KEY_MODIFIER_CONTROL) != 0 key = key == ?? ? "\x7f" : (key.ord & 0x9f).chr end - if (mods & PDCurses::KEY_MODIFIER_ALT) != 0 + if (mods & Curses::PDC_KEY_MODIFIER_ALT) != 0 if key == "\0" # Alt + `, Alt + < etc. return NUL, so ignore it. need_retry = true diff --git a/test/test_helper.rb b/test/test_helper.rb index bb131d0..aa9f70d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,6 +1,7 @@ require "simplecov" require "test/unit" require "tmpdir" +require "curses" SimpleCov.profiles.define "textbringer" do add_filter "/test/" @@ -26,6 +27,36 @@ def format(*args) SimpleCov.formatter = SimpleCov::Formatter::Codecov end +module Curses + if !defined?(Curses.get_key_modifiers) + @key_modifiers = 0 + + def self.save_key_modifiers(flag) + end + + def self.get_key_modifiers + @key_modifiers + end + + def self.set_key_modifiers(key_modifiers) + @key_modifiers = key_modifiers + end + + KEY_OFFSET = 0xec00 + ALT_0 = KEY_OFFSET + 0x97 + ALT_9 = KEY_OFFSET + 0xa0 + ALT_A = KEY_OFFSET + 0xa1 + ALT_Z = KEY_OFFSET + 0xba + ALT_NUMBER_BASE = ALT_0 - ?0.ord + ALT_ALPHA_BASE = ALT_A - ?a.ord + + PDC_KEY_MODIFIER_SHIFT = 1 + PDC_KEY_MODIFIER_CONTROL = 2 + PDC_KEY_MODIFIER_ALT = 4 + PDC_KEY_MODIFIER_NUMLOCK = 8 + end +end + require "textbringer" module Curses @@ -190,23 +221,6 @@ def method_missing(mid, *args) end ::Curses.send(:remove_const, :Window) ::Curses.const_set(:Window, FakeCursesWindow) - - module PDCurses - self.dll_loaded = true - - @key_modifiers = 0 - - def PDCurses.PDC_save_key_modifiers(flag) - end - - def PDCurses.PDC_get_key_modifiers - @key_modifiers - end - - def PDCurses.PDC_set_key_modifiers(key_modifiers) - @key_modifiers = key_modifiers - end - end class Window class << self diff --git a/test/textbringer/test_window.rb b/test/textbringer/test_window.rb index fe5355d..717afda 100644 --- a/test/textbringer/test_window.rb +++ b/test/textbringer/test_window.rb @@ -233,27 +233,27 @@ def test_read_event @window.window.push_key(Curses::KEY_RIGHT) assert_equal(:right, @window.read_event) - @window.window.push_key(PDCurses::ALT_0 + 3) + @window.window.push_key(Curses::ALT_0 + 3) assert_equal("\e", @window.read_event) assert_equal("3", @window.read_event) - @window.window.push_key(PDCurses::ALT_A + 5) + @window.window.push_key(Curses::ALT_A + 5) assert_equal("\e", @window.read_event) assert_equal("f", @window.read_event) - PDCurses.PDC_set_key_modifiers(PDCurses::KEY_MODIFIER_CONTROL) + Curses.set_key_modifiers(Curses::PDC_KEY_MODIFIER_CONTROL) @window.window.push_key("a") assert_equal("\C-a", @window.read_event) @window.window.push_key("?") assert_equal("\x7f", @window.read_event) - PDCurses.PDC_set_key_modifiers(PDCurses::KEY_MODIFIER_ALT) + Curses.set_key_modifiers(Curses::PDC_KEY_MODIFIER_ALT) @window.window.push_key("\0") @window.window.push_key("a") assert_equal("\e", @window.read_event) assert_equal("a", @window.read_event) ensure - PDCurses.PDC_set_key_modifiers(0) + Curses.set_key_modifiers(0) end def test_read_event_nonblock @@ -267,13 +267,13 @@ def test_wait_input @window.window.push_key("a") assert_equal("a", @window.wait_input(1)) - PDCurses.PDC_set_key_modifiers(PDCurses::KEY_MODIFIER_ALT) + Curses.set_key_modifiers(Curses::PDC_KEY_MODIFIER_ALT) @window.window.push_key("\0") @window.window.push_key("a") assert_equal("\e", @window.read_event) assert_equal("a", @window.wait_input(1)) ensure - PDCurses.PDC_set_key_modifiers(0) + Curses.set_key_modifiers(0) end def test_has_input? @@ -282,13 +282,13 @@ def test_has_input? @window.window.push_key("a") assert_equal(true, @window.has_input?) - PDCurses.PDC_set_key_modifiers(PDCurses::KEY_MODIFIER_ALT) + Curses.set_key_modifiers(Curses::PDC_KEY_MODIFIER_ALT) @window.window.push_key("\0") @window.window.push_key("a") assert_equal("\e", @window.read_event) assert_equal(true, @window.has_input?) ensure - PDCurses.PDC_set_key_modifiers(0) + Curses.set_key_modifiers(0) end def test_echo_area_redisplay diff --git a/textbringer.gemspec b/textbringer.gemspec index bff646e..95a6f70 100644 --- a/textbringer.gemspec +++ b/textbringer.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 2.3' - spec.add_runtime_dependency "curses", "~> 1.2" + spec.add_runtime_dependency "curses", ">= 1.2.2" spec.add_runtime_dependency "unicode-display_width", "~> 1.1" spec.add_runtime_dependency "clipboard", "~> 1.1" spec.add_runtime_dependency "fiddley", ">= 0.0.5"