summaryrefslogtreecommitdiff
path: root/lib/reline/terminfo.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/reline/terminfo.rb')
-rw-r--r--lib/reline/terminfo.rb80
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/reline/terminfo.rb b/lib/reline/terminfo.rb
new file mode 100644
index 0000000000..9c1615cc2b
--- /dev/null
+++ b/lib/reline/terminfo.rb
@@ -0,0 +1,80 @@
+require 'fiddle'
+require 'fiddle/import'
+
+module Reline::Terminfo
+ extend Fiddle::Importer
+
+ class TerminfoError < StandardError; end
+
+ @curses_dl = nil
+ def self.curses_dl
+ return @curses_dl if @curses_dl
+ if Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
+ # Fiddle::TYPE_VARIADIC is supported from Fiddle 1.0.1.
+ %w[libncursesw.so libcursesw.so libncurses.so libcurses.so].each do |curses_name|
+ result = Fiddle::Handle.new(curses_name)
+ rescue Fiddle::DLError
+ next
+ else
+ @curses_dl = result
+ break
+ end
+ end
+ @curses_dl
+ end
+end
+
+module Reline::Terminfo
+ dlload curses_dl
+ #extern 'int setupterm(char *term, int fildes, int *errret)'
+ @setupterm = Fiddle::Function.new(curses_dl['setupterm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
+ #extern 'char *tigetstr(char *capname)'
+ @tigetstr = Fiddle::Function.new(curses_dl['tigetstr'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOIDP)
+ #extern 'char *tiparm(const char *str, ...)'
+ @tiparm = Fiddle::Function.new(curses_dl['tiparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
+
+ def self.setupterm(term, fildes)
+ errret_int = String.new("\x00" * 8, encoding: 'ASCII-8BIT')
+ ret = @setupterm.(term, fildes, errret_int)
+ errret = errret_int.unpack('i')[0]
+ case ret
+ when 0 # OK
+ 0
+ when -1 # ERR
+ case errret
+ when 1
+ raise TerminfoError.new('The terminal is hardcopy, cannot be used for curses applications.')
+ when 0
+ raise TerminfoError.new('The terminal could not be found, or that it is a generic type, having too little information for curses applications to run.')
+ when -1
+ raise TerminfoError.new('The terminfo database could not be found.')
+ else # unknown
+ -1
+ end
+ else # unknown
+ -2
+ end
+ end
+
+ def self.tigetstr(capname)
+ @tigetstr.(capname)
+ end
+
+ def self.tiparm(str, *args)
+ new_args = []
+ args.each do |a|
+ new_args << Fiddle::TYPE_INT << a
+ end
+ @tiparm.(str, *new_args)
+ end
+
+ def self.enabled?
+ true
+ end
+end if Reline::Terminfo.curses_dl
+
+module Reline::Terminfo
+ def self.enabled?
+ false
+ end
+end unless Reline::Terminfo.curses_dl