vigilem-evdev 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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