vigilem-evdev 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/ext/Rakefile +31 -0
  4. data/ext/rake_helper.rb +10 -0
  5. data/lib/vigilem/_evdev.rb +24 -0
  6. data/lib/vigilem/evdev.rb +14 -0
  7. data/lib/vigilem/evdev/at_exit.rb +8 -0
  8. data/lib/vigilem/evdev/context_filter.rb +92 -0
  9. data/lib/vigilem/evdev/demultiplexer.rb +26 -0
  10. data/lib/vigilem/evdev/device.rb +182 -0
  11. data/lib/vigilem/evdev/device_capabilities.rb +53 -0
  12. data/lib/vigilem/evdev/dom.rb +8 -0
  13. data/lib/vigilem/evdev/dom/adapter.rb +87 -0
  14. data/lib/vigilem/evdev/dom/code_values_tables.rb +172 -0
  15. data/lib/vigilem/evdev/dom/input_event_converter.rb +329 -0
  16. data/lib/vigilem/evdev/dom/input_event_utils.rb +48 -0
  17. data/lib/vigilem/evdev/dom/key_values_tables.rb +248 -0
  18. data/lib/vigilem/evdev/dom/kp_table.rb +52 -0
  19. data/lib/vigilem/evdev/focus_context_filter.rb +124 -0
  20. data/lib/vigilem/evdev/input_system_handler.rb +69 -0
  21. data/lib/vigilem/evdev/key_map_cache.rb +64 -0
  22. data/lib/vigilem/evdev/multiplexer.rb +73 -0
  23. data/lib/vigilem/evdev/system.rb +17 -0
  24. data/lib/vigilem/evdev/system/input.rb +1053 -0
  25. data/lib/vigilem/evdev/system/input/event.rb +4 -0
  26. data/lib/vigilem/evdev/system/input/input_event.rb +33 -0
  27. data/lib/vigilem/evdev/system/int.rb +9 -0
  28. data/lib/vigilem/evdev/system/ioctl.rb +143 -0
  29. data/lib/vigilem/evdev/system/keymap_loaders.rb +89 -0
  30. data/lib/vigilem/evdev/system/keymap_loaders/dumpkeys_loader.rb +98 -0
  31. data/lib/vigilem/evdev/system/keymap_loaders/kmap_loader.rb +74 -0
  32. data/lib/vigilem/evdev/system/posix_types.rb +5 -0
  33. data/lib/vigilem/evdev/system/time.rb +21 -0
  34. data/lib/vigilem/evdev/transfer_agent.rb +40 -0
  35. data/lib/vigilem/evdev/version.rb +5 -0
  36. data/lib/vigilem/evdev/vty_context_filter.rb +216 -0
  37. data/spec/after_each_example_group.rb +29 -0
  38. data/spec/delete_test_cache_after_group.rb +26 -0
  39. data/spec/spec_helper.rb +30 -0
  40. data/spec/vigilem/_evdev_spec.rb +11 -0
  41. data/spec/vigilem/evdev/context_filter_spec.rb +114 -0
  42. data/spec/vigilem/evdev/demultiplexer_spec.rb +44 -0
  43. data/spec/vigilem/evdev/device_capabilities_spec.rb +0 -0
  44. data/spec/vigilem/evdev/device_spec.rb +97 -0
  45. data/spec/vigilem/evdev/dom/adapter_spec.rb +5 -0
  46. data/spec/vigilem/evdev/dom/input_event_converter_spec.rb +253 -0
  47. data/spec/vigilem/evdev/dom/input_event_utils_spec.rb +23 -0
  48. data/spec/vigilem/evdev/focus_context_filter_spec.rb +112 -0
  49. data/spec/vigilem/evdev/input_system_handler_spec.rb +146 -0
  50. data/spec/vigilem/evdev/key_map_cache_spec.rb +65 -0
  51. data/spec/vigilem/evdev/multiplexer_spec.rb +55 -0
  52. data/spec/vigilem/evdev/system/input/input_event_spec.rb +33 -0
  53. data/spec/vigilem/evdev/system/input_spec.rb +274 -0
  54. data/spec/vigilem/evdev/system/int_spec.rb +30 -0
  55. data/spec/vigilem/evdev/system/ioctl_spec.rb +206 -0
  56. data/spec/vigilem/evdev/system/keymap_loaders/dumpkeys_loader_spec.rb +5 -0
  57. data/spec/vigilem/evdev/system/keymap_loaders/kmap_loader_spec.rb +24 -0
  58. data/spec/vigilem/evdev/system/keymap_loaders_spec.rb +22 -0
  59. data/spec/vigilem/evdev/system/posix_types_spec.rb +15 -0
  60. data/spec/vigilem/evdev/system/time_spec.rb +18 -0
  61. data/spec/vigilem/evdev/transfer_agent_spec.rb +57 -0
  62. data/spec/vigilem/evdev/vty_context_filter_spec.rb +282 -0
  63. metadata +286 -0
@@ -0,0 +1,4 @@
1
+ require 'vigilem/evdev/system/input/input_event'
2
+
3
+ input = Vigilem::Evdev::System::Input
4
+ input::Event = input::InputEvent
@@ -0,0 +1,33 @@
1
+ require 'vigilem/support'
2
+
3
+ require 'vigilem/support/metadata'
4
+
5
+ require 'vigilem/evdev/system/input'
6
+
7
+ require 'vigilem/evdev/system/time'
8
+
9
+ module Vigilem
10
+ module Evdev
11
+ module System
12
+ module Input
13
+ #
14
+ # represents struct input_event from input.h
15
+ class InputEvent < ::VFFIStruct
16
+ layout_with_methods :time, Time::Timeval,
17
+ :type, :__u16,
18
+ :code, :__u16,
19
+ :value, :__s32
20
+
21
+ include Support::Metadata
22
+
23
+ # @fixme kludge
24
+ attr_accessor :leds
25
+
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ require 'vigilem/evdev/system/input/event'
@@ -0,0 +1,9 @@
1
+ require 'ffi'
2
+
3
+ FFI.typedef(:uint8, :__u8)
4
+ FFI.typedef(:uint16, :__u16)
5
+ FFI.typedef(:uint32, :__u32)
6
+
7
+ FFI.typedef(:int8, :__s8)
8
+ FFI.typedef(:int16, :__s16)
9
+ FFI.typedef(:int32, :__s32)
@@ -0,0 +1,143 @@
1
+ require 'vigilem/evdev/system'
2
+
3
+ module Vigilem
4
+ module Evdev
5
+ module System
6
+ # @see http://lxr.free-electrons.com/source/include/uapi/asm-generic/ioctl.h
7
+ # @todo consider the possibility of switching to RubyInline?
8
+ # - RubyInline (and ZenTest) gave significant problems
9
+ # installing "invalid gem: package metadata is missing"
10
+ # updating to the newest rubygems and clearing the gem from the cache worked
11
+ # A C/C++ compiler (the same one that compiled your ruby interpreter)
12
+ # irb keeps throwing
13
+ # Errno::ENOENT: No such file or directory - /...home dir.../(irb)
14
+ # from /.../.rvm/gems/ruby-1.9.3-p545/gems/RubyInline-3.12.3/lib/inline.rb:532:in `mtime'
15
+ # - move this note to it's own file
16
+ module IOCTL
17
+
18
+ include Support::Sys
19
+
20
+ # versions which are compatible with
21
+ # this file
22
+ # @return [Array<Integer>]
23
+ def self.kernel_versions
24
+ %w(3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16)
25
+ end
26
+
27
+ # @return [Integer] 8
28
+ def _IOC_NRBITS; 8; end
29
+ # @return [Integer] 8
30
+ def _IOC_TYPEBITS; 8; end
31
+ # @return [Integer] 14
32
+ def _IOC_SIZEBITS; 14; end
33
+ # @return [Integer] 2
34
+ def _IOC_DIRBITS; 2; end
35
+ # @return [Integer]
36
+ def _IOC_NRMASK; ((1 << _IOC_NRBITS)-1); end
37
+ # @return [Integer]
38
+ def _IOC_TYPEMASK; ((1 << _IOC_TYPEBITS)-1); end
39
+ # @return [Integer]
40
+ def _IOC_SIZEMASK; ((1 << _IOC_SIZEBITS)-1); end
41
+ # @return [Integer]
42
+ def _IOC_DIRMASK; ((1 << _IOC_DIRBITS)-1); end
43
+ # @return [Integer]
44
+ def _IOC_NRSHIFT; 0; end
45
+ # @return [Integer]
46
+ def _IOC_TYPESHIFT; (_IOC_NRSHIFT+_IOC_NRBITS); end
47
+ # @return [Integer]
48
+ def _IOC_SIZESHIFT; (_IOC_TYPESHIFT+_IOC_TYPEBITS); end
49
+ # @return [Integer]
50
+ def _IOC_DIRSHIFT; (_IOC_SIZESHIFT+_IOC_SIZEBITS); end
51
+ #
52
+ def IOC_IN; (_IOC_WRITE << _IOC_DIRSHIFT); end
53
+ #
54
+ def IOC_OUT; (_IOC_READ << _IOC_DIRSHIFT); end
55
+ #
56
+ def IOC_INOUT; ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT); end
57
+ #
58
+ def IOCSIZE_MASK; (_IOC_SIZEMASK << _IOC_SIZESHIFT); end
59
+ #
60
+ def IOCSIZE_SHIFT; (_IOC_SIZESHIFT); end
61
+
62
+ # @return [Integer]
63
+ def IOCSIZE_MASK; (_IOC_SIZEMASK << _IOC_SIZESHIFT); end
64
+ # @return [Integer]
65
+ def IOCSIZE_SHIFT; (_IOC_SIZESHIFT); end
66
+
67
+ # direction bits
68
+
69
+ # no data transfer
70
+ # @return [Integer] 0
71
+ def _IOC_NONE; 0; end
72
+ # @return [Integer] 1
73
+ def _IOC_WRITE; 1; end
74
+ # @return [Integer] 2
75
+ def _IOC_READ; 2; end
76
+
77
+ #
78
+ # @param [Integer] dir The direction of data transfer
79
+ # @option dir [Integer] _IOC_NONE
80
+ # @option dir [Integer] _IOC_READ
81
+ # @option dir [Integer] _IOC_WRITE
82
+ # @option dir [Integer] _IOC_READ|_IOC_WRITE
83
+ # @!macro type_nr_fmt_return_Integer
84
+ def _IOC(dir, type, nr, size)
85
+ (System.native_signed_long(dir << _IOC_DIRSHIFT) | (type.ord << _IOC_TYPESHIFT) |
86
+ (nr << _IOC_NRSHIFT) | (size << _IOC_SIZESHIFT))
87
+ end
88
+
89
+ # /* used to create numbers */
90
+
91
+ # an ioctl with no parameters
92
+ # @!macro type_nr
93
+ # @return [Integer]
94
+ def _IO(type,nr); return _IOC(_IOC_NONE,type.ord,nr,0); end
95
+ # for reading data (copy_to_user)
96
+ # @!macro type_nr_fmt_return_Integer
97
+ def _IOR(type,nr,fmt_or_size); return _IOC(_IOC_READ,type.ord,nr,_size_of(fmt_or_size)); end
98
+ # for writing data (copy_from_user)
99
+ # @!macro type_nr_fmt_return_Integer
100
+ def _IOW(type,nr,fmt_or_size); return _IOC(_IOC_WRITE,(type.ord),(nr),_size_of(fmt_or_size)); end
101
+ # for bidirectional transfers
102
+ # @!macro type_nr_fmt_return_Integer
103
+ def _IOWR(type,nr,fmt_or_size); return _IOC(_IOC_READ|_IOC_WRITE,(type.ord),(nr),_size_of(fmt_or_size)); end
104
+
105
+ #define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
106
+ #define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
107
+ #define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
108
+
109
+ # /* used to decode ioctl numbers.. */
110
+
111
+ #
112
+ # @!macro nr
113
+ # @return [Integer]
114
+ def _IOC_DIR(nr); return (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK); end
115
+ # @!macro nr
116
+ # @return [Integer]
117
+ def _IOC_TYPE(nr); return (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK); end
118
+ # @!macro nr
119
+ # @return [Integer]
120
+ def _IOC_NR(nr); return (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK); end
121
+ # @!macro nr
122
+ # @return [Integer]
123
+ def _IOC_SIZE(nr); return (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK); end
124
+
125
+ #
126
+ # @param [String || Numeric] numeric_or_format
127
+ # @return [Fixnum]
128
+ def _size_of(numeric_or_format)
129
+ if numeric_or_format.is_a? String
130
+ sizeof(numeric_or_format)
131
+ elsif numeric_or_format.is_a? Numeric
132
+ numeric_or_format
133
+ else numeric_or_format.respond_to? :size
134
+ numeric_or_format.size
135
+ end
136
+ end
137
+
138
+ extend self
139
+
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,89 @@
1
+ require 'vigilem/support/key_map'
2
+
3
+ require 'vigilem/evdev/key_map_cache'
4
+
5
+ module Vigilem
6
+ module Evdev
7
+ module System
8
+ #
9
+ # the entry point for loading keymaps
10
+ module KeymapLoaders
11
+
12
+ extend Support::Metadata
13
+
14
+ KeyMap = Support::KeyMap
15
+
16
+ attr_writer :all
17
+
18
+ attr_reader :loader
19
+
20
+ #
21
+ # @return [Array<KeymapLoader>]
22
+ def all
23
+ @all ||= []
24
+ end
25
+
26
+ #
27
+ # @return [FalseClass || TrueClass]
28
+ def cached?
29
+ Evdev::KeyMapCache.exists?
30
+ end
31
+
32
+ #
33
+ # @raise [NotImplementedError] 'Cannot find keymap'
34
+ # @return [KeyMap]
35
+ def exec
36
+ attempt ||= 1
37
+ if cached?
38
+ k = KeyMapCache.restore
39
+ @loader = k.metadata[:loader]
40
+ metadata[:cached] = true
41
+ else
42
+ #@todo just gets the first
43
+ if @loader = all.find(&:available?)
44
+ @loader.exec
45
+ else
46
+ raise NotImplementedError, 'Cannot find keymap'
47
+ end
48
+ end
49
+ rescue ArgumentError #, 'marshal data too short'
50
+ KeyMapCache.delete
51
+ retry unless (attempts -= 1).zero?
52
+ else
53
+ KeyMapCache.dump((mapping = @loader.key_map))
54
+ mapping[:cached] = true
55
+ mapping.left_side_aliases(:keycode, :keycodes)
56
+ mapping.right_side_aliases(:keysym, :keysyms, :char_ref, :char_refs)
57
+ mapping
58
+ end
59
+
60
+ #
61
+ # @return [Array<KeymapLoader>]
62
+ def set_default
63
+ if not @set
64
+ @set = true
65
+ all.concat([DumpkeysLoader.new, KmapLoader.new])
66
+ end
67
+ end
68
+
69
+ # returns the default system keymap
70
+ # @return [KeyMap]
71
+ def key_map
72
+ set_default
73
+ if loader
74
+ loader.key_map
75
+ else
76
+ exec
77
+ end
78
+ end
79
+
80
+ alias_method :build_cache, :key_map
81
+
82
+ extend self
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ require 'vigilem/evdev/system/keymap_loaders/dumpkeys_loader'
89
+ require 'vigilem/evdev/system/keymap_loaders/kmap_loader'
@@ -0,0 +1,98 @@
1
+ require 'vigilem/support/key_map'
2
+
3
+ require 'vigilem/support/key_map_info'
4
+
5
+ module Vigilem
6
+ module Evdev
7
+ module System
8
+ module KeymapLoaders
9
+ #
10
+ # this takes longer than keymap_loader, but is more thorough
11
+ class DumpkeysLoader
12
+
13
+ KeyMap = Support::KeyMap
14
+
15
+ attr_writer :key_map
16
+
17
+ #
18
+ # @param [String] args
19
+ # @return [KeyMap]
20
+ def exec(args='')
21
+ @key_map = if self.class.available?
22
+ if args =~ /\s+/
23
+ raise ArgumentError, "Argument: `#{args}' invalid"
24
+ else
25
+ k = KeyMap.load_string(self.class.run_dumpkeys("fn#{args}"))
26
+ k.metadata[:loader] = self
27
+ k
28
+ end
29
+ end
30
+ key_map_info
31
+ @key_map
32
+ end
33
+
34
+ alias_method :key_map!, :exec
35
+
36
+ #
37
+ # @return [KeyMap]
38
+ def key_map
39
+ @key_map ||= exec
40
+ end
41
+
42
+ #
43
+ # @return [KeyMapInfo]
44
+ def key_map_info
45
+ key_map.info ||= key_map.info(self.class.run_dumpkeys('l'))
46
+ end
47
+
48
+ #
49
+ # @return [TrueClass || FalseClass]
50
+ def available?
51
+ self.class.available?
52
+ end
53
+
54
+ class << self
55
+ #
56
+ # @return [FalseClass || TrueClass]
57
+ def available?
58
+ tty and command
59
+ end
60
+
61
+ #
62
+ # @return [String || NilClass] returns the command path, otherwise
63
+ # returns nil if there isn't one
64
+ def command
65
+ if not @checked_for_command
66
+ str = `which dumpkeys`.chomp
67
+ @checked_for_command = true
68
+ @command = str.empty? ? nil : str
69
+ else
70
+ @command
71
+ end
72
+ end
73
+
74
+ # as long as it's sudo does this matter?
75
+ # @return [String || nil]
76
+ def tty
77
+ @tty_command ||= `which tty`.chomp
78
+ @tty ||= `#{@tty_command}` if @tty_command
79
+ end
80
+
81
+ # needs sudo on xserver
82
+ # loads dumpkeys string from system command
83
+ # @param [Array] *dumpkeys_args
84
+ # @raise command not run?
85
+ # @return [String || nil]
86
+ def run_dumpkeys(*dumpkeys_args)
87
+ if tty and command
88
+ args = dumpkeys_args.empty? ? '' : "-#{dumpkeys_args.join}"
89
+ `#{command} #{args} < #{tty}`
90
+ end
91
+ end
92
+ end
93
+
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,74 @@
1
+ require 'zlib'
2
+
3
+ require 'vigilem/support/key_map'
4
+
5
+ module Vigilem
6
+ module Evdev
7
+ module System
8
+ module KeymapLoaders
9
+ #
10
+ # change name to console-setup kmap
11
+ class KmapLoader
12
+
13
+ KeyMap = Support::KeyMap
14
+
15
+ attr_writer :cache_glob, :key_map
16
+
17
+ #
18
+ # @param [NilClass || String] path
19
+ # @return [KeyMap]
20
+ def exec(path=nil)
21
+ k = if not path
22
+ if filepath = filepaths.find {|f| File.extname(f) !~ /\.g(un)?z(ip)?/ }
23
+ KeyMap.load_string(File.read(filepath))
24
+ elsif filepath = filepaths.find {|f| File.extname(f) =~ /\.g(un)?z(ip)?/ }
25
+ KeyMap.load_string(Zlib::GzipReader.open(filepath).read)
26
+ end
27
+ else
28
+ KeyMap.load_string(Zlib::GzipReader.open(path).read)
29
+ end
30
+ k.metadata[:loader] = self
31
+ @key_map = k
32
+ key_map_info
33
+ @key_map
34
+ end
35
+
36
+ alias_method :keymap!, :exec
37
+
38
+ #
39
+ # @return
40
+ def key_map
41
+ @key_map ||= exec
42
+ end
43
+
44
+ #
45
+ # @return [KeyMapInfo]
46
+ def key_map_info
47
+ @key_map_info ||= if DumpkeysLoader.available?
48
+ key_map.info(DumpkeysLoader.run_dumpkeys('l'))
49
+ end
50
+ end
51
+
52
+ #
53
+ # @return [Array<String>]
54
+ def filepaths
55
+ @filepaths ||= Dir[cache_glob]
56
+ end
57
+
58
+ #
59
+ # @return [TrueClass || FalseClass]
60
+ def available?
61
+ filepaths.any? {|f| File.exists? f }
62
+ end
63
+
64
+ #
65
+ # @return [String] glob
66
+ def cache_glob
67
+ @cache_glob ||= '/etc/console-setup/cached*.kmap*'
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end