lib/textbringer/window.rb in textbringer-0.1.6 vs lib/textbringer/window.rb in textbringer-0.1.7

- old
+ new

@@ -3,47 +3,53 @@ require "curses" require "unicode/display_width" require "fiddle/import" module Textbringer - begin - # These features should be provided by curses.gem. - module PDCurses + # 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)" - - KEY_MODIFIER_SHIFT = 1 - KEY_MODIFIER_CONTROL = 2 - KEY_MODIFIER_ALT = 4 - KEY_MODIFIER_NUMLOCK = 8 + @dll_loaded = true + rescue Fiddle::DLError end - rescue - remove_const :PDCurses end class Window KEY_NAMES = {} Curses.constants.grep(/\AKEY_/).each do |name| KEY_NAMES[Curses.const_get(name)] = name.slice(/\AKEY_(.*)/, 1).downcase.intern end - ALT_IS_FUNCTION_KEY = - /mswin32|mingw32/ =~ RUBY_PLATFORM && /PDCurses/ =~ Curses::VERSION - if ALT_IS_FUNCTION_KEY - 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 - end - @@windows = [] @@current = nil @@echo_area = nil def self.windows @@ -265,16 +271,16 @@ end def read_char key = get_char if key.is_a?(Integer) - if ALT_IS_FUNCTION_KEY - if ALT_0 <= key && key <= ALT_9 - @key_buffer.push((key - ALT_NUMBER_BASE).chr) + if PDCurses.dll_loaded? + if PDCurses::ALT_0 <= key && key <= PDCurses::ALT_9 + @key_buffer.push((key - PDCurses::ALT_NUMBER_BASE).chr) return "\e" - elsif ALT_A <= key && key <= ALT_Z - @key_buffer.push((key - ALT_ALPHA_BASE).chr) + elsif PDCurses::ALT_A <= key && key <= PDCurses::ALT_Z + @key_buffer.push((key - PDCurses::ALT_ALPHA_BASE).chr) return "\e" end end KEY_NAMES[key] || key else @@ -290,10 +296,13 @@ @window.nodelay = false end end def wait_input(msecs) + unless @key_buffer.empty? + return @key_buffer.first + end @window.timeout = msecs begin c = @window.get_char if c Curses.unget_char(c) @@ -303,10 +312,13 @@ @window.timeout = -1 end end def has_input? + unless @key_buffer.empty? + return true + end @window.nodelay = true begin c = @window.get_char if c Curses.unget_char(c) @@ -444,17 +456,23 @@ recenter end end def scroll_up + if @bottom_of_window.location == @buffer.point_max + raise EditorError, "End of buffer" + end @buffer.point_to_mark(@bottom_of_window) @buffer.previous_line @buffer.beginning_of_line @buffer.mark_to_point(@top_of_window) end def scroll_down + if @top_of_window.location == @buffer.point_min + raise EditorError, "Beginning of buffer" + end @buffer.point_to_mark(@top_of_window) @buffer.next_line @buffer.beginning_of_line @top_of_window.location = 0 end @@ -605,14 +623,14 @@ end end def get_char if @key_buffer.empty? - PDCurses.PDC_save_key_modifiers(1) if defined?(PDCurses) + PDCurses.PDC_save_key_modifiers(1) if PDCurses.dll_loaded? begin need_retry = false key = @window.get_char - if defined?(PDCurses) + if PDCurses.dll_loaded? mods = PDCurses.PDC_get_key_modifiers if key.is_a?(String) && key.ascii_only? if (mods & PDCurses::KEY_MODIFIER_CONTROL) != 0 key = key == ?? ? "\x7f" : (key.ord & 0x9f).chr end