Class: Canis::DefaultKeyReader

Inherits:
Object
  • Object
show all
Defined in:
lib/canis/core/system/window.rb

Overview

created on 2014-04-20 - 00:19 so that user can install own handler

A class that reads keys and handles function, shifted function, control, alt, and other extended keys. THis essentially consists of a method getchar which will be called by the application to get keys in a loop. Application may also call getchar to get one key in some situations.

Originally, rbcurse returned an int, but we are movign to a string, so that user can use the exact control codes he gets on the terminal using C-v and map them here.

Constant Summary collapse

KEY_S_F1 =
''

Instance Method Summary collapse

Constructor Details

#initialize(win) ⇒ DefaultKeyReader

— {{{



784
785
786
787
# File 'lib/canis/core/system/window.rb', line 784

def initialize win
  @window = win
  #@stack = []
end

Instance Method Details

#_get_int_for_newkey(x) ⇒ Object

Generate and return an int for a newkey which user has specified in yml file. We use hash, which won’t allow me to derive key string in case loop user can do:

when KEY_ENTER
when 32
when $kh_int["S-F2"]


1078
1079
1080
1081
1082
1083
1084
# File 'lib/canis/core/system/window.rb', line 1078

def _get_int_for_newkey x
  # FIXME put the declaration somewhere else maybe in window cons ???
  y = $kh_int[x]
  # when i give user the hash, he can get the string back ???
  $kh_int[y] = x unless $kh_int.key? y
  return y
end

#getchObject

return an int for the key read. this is just a single int, and is not interpreted for control or function keys. it also will return -1 when no action. You may re-implenent it or call the original one.



793
794
795
# File 'lib/canis/core/system/window.rb', line 793

def getch
  @window.getch
end

#getcharObject

NOTE: This is a reworked and much simpler version of the original getchar which was taken from manveru’s codebase. This also currently returns the keycode as int while placing the char version in a global $key_chr. Until we are ready to return a char, we use this.

FIXME : I have tried very hard to revert to nodelay but it does not seem to have an effect when ESC is pressed. Somewhere, there is a delay when ESC is pressed. I not longer wish to provide the feature of pressing ESC and then a key to be evaluated as Meta-key. This slows down when a user just presses ESC.

Read a char from the window (from user) and returns int code. In some cases, such as codes entered in the $kh hash, we do not yet have a keycode defined so we return 9999 and the user can access $key_chr.

NOTE: Do not convert to string, that is doing two things. Allow user to convert if required using ‘key_tos`



844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
# File 'lib/canis/core/system/window.rb', line 844

def getchar
  $key_chr = nil
    c = nil
    while true
      c = self.getch
      break if c != -1
    end

    cn = c
    $key_int = c
    # handle control codes 0 to 127 but not escape
    if cn >= 0 && cn < 128 && cn != 27
      #$key_chr = key_tos(c)
      return c
    end
    
    # if escape then get into a loop and keep checking till -1 or another escape
    #
    if c == 27
      buff=c.chr
      # if there is another escape coming through then 2 keys were pressed so
      # evaluate upon hitting an escape
      # NOTE : i think only if ESc is followed by [ should be keep collectig
      # otherwise the next char should evaluate. cases like F1 are already being sent in as high integer codes
      while true
        #$log.debug " #{Time.now.to_f} inside LOOP before getch "
        # This getch seems to take enough time not to return a -1 for almost a second
        # even if nodelay is true ??? XXX
        FFI::NCurses.set_escdelay(5)
        k = self.getch
        #$log.debug "elapsed #{elapsed} millis  inside LOOP AFTER getch #{k} (#{elapsed1})"
        $log.debug "inside LOOP AFTER getch #{k} "

        if k == 27
          # seems like two Meta keys pressed in quick succession without chance for -1 to kick in
          # but this still does not catch meta char followed by single char. M-za , it does.
          if $esc_esc
            if buff == 27.chr
              $key_chr = "<ESC-ESC>"
              return 2727
            else
              alert "buff is #{buff}"
            end
          end
          $log.debug "  1251 before evaluate "
          x = _evaluate_buff buff
          # return ESC so it can be interpreted again.
          @window.ungetch k
          $key_chr = x if x
          return $key_int if x
          $log.warn "getchar: window.rb 1200 Found no mapping for #{buff} "
          $key_chr = buff
          return $key_int
          #return buff # otherwise caught in loop ???
        elsif k > -1
          # FIXME next lne crashes if M-C-h pressed which gives 263
          if k > 255
            $log.warn "getchar: window.rb 1247 Found no mapping for #{buff} #{k} "
            $key_int = k + 128
            return $key_int
            # this contains ESc followed by a high number
=begin
            ka = key_tos(k)
            if ka
              $key_chr = "<M-" + ka[1..-1]
              $key_int = k + 128
              return $key_int
            else
              $key_chr = "UNKNOWN: Meta + #{k}"
              return 9999
            end
=end
          end

          buff += k.chr
          # this is an alt/meta code. All other complex codes seem to have a [ after the escape
          # so we will keep accumulating them.
          # NOTE this still means that user can press Alt-[ and some letter in quick succession
          # and it will accumulate rather than be interpreted as M-[.
          #
          if buff.length == 2 and k == 79
            # this is Alt-O and can be a F key in some terms like xterm-color
          elsif buff.length == 2 and k.chr != '['
            x = _evaluate_buff buff
    
            $key_chr = x
            return $key_int if x
          end
          #$log.debug "XXX:  getchar adding #{k}, #{k.chr} to buff #{buff} "
        else
          #$log.debug "  GOT -1 in escape "
          # it is -1 so evaluate
          x = _evaluate_buff buff
          $key_chr = x if x
          return $key_int if x
          $log.warn "getchar: window.rb 1256 Found no mapping for #{buff} "
          $key_chr = buff
          return $key_int
        end
      end
    end
    
    # what if keyname does not return anything
    if c > 127
      #$log.info "xxxgetchar: window.rb sending #{c} "
=begin
      ch =  FFI::NCurses::keyname(c) 
      # remove those ugly brackets around function keys
      if ch && ch[-1]==')'
        ch = ch.gsub(/[()]/,'')
      end
      if ch && ch.index("KEY_")
        ch = ch.gsub(/KEY_/,'')
      end
      ch = "<#{ch}>" if ch
      #return ch if ch
      $key_chr = ch if ch
      $key_chr = "UNKNOWN:#{c}" unless ch
      $log.warn "getchar: window.rb 1234 Found no mapping for #{c} " unless ch
=end
      #$key_chr = key_tos(ch)
      return c
    end
    if c
      #$key_chr =  c.chr 
      return c 
    end
end

#getchar_as_charObject



974
975
976
977
978
# File 'lib/canis/core/system/window.rb', line 974

def getchar_as_char
  $key_int = getchar
  $key_chr = key_tos( $key_int )
  return $key_chr
end