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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e80bd4eb4d68f4e6733160a7751b53eddc521418
4
+ data.tar.gz: 61a2de4f8075c808c18449fb5b7eb072fd09ebd7
5
+ SHA512:
6
+ metadata.gz: 5c36fcfaf61bd5101b93deb38ce30118ceba52789428bb343d1a8a84fdcf0b3fe4bd92847608a805e31dfa77f7d774cbe23185d899fd497fb9e3c88d1c8d1f54
7
+ data.tar.gz: 5a98d71e5163fe763a1517c9a1188b17accee111480d555c5896496e34647d45ff95c859fa337bdb2349e206ae6889cd3b01061534b8bcc75bb68d6844ef9aa3
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 jtzero
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ root = File.expand_path('../../', __FILE__)
2
+ lib = File.join(root, 'lib')
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ task :setup_key_map do
6
+ require 'vigilem/evdev/system/keymap_loaders'
7
+ require 'fileutils'
8
+
9
+ sudo_cmd = if not `which rvmsudo`.empty?
10
+ 'rvmsudo'
11
+ else
12
+ `which sudo`.chomp
13
+ end
14
+ user = `whoami`
15
+ puts `#{sudo_cmd} ruby ./rake_helper.rb #{user}`
16
+ end
17
+
18
+ task :x11_context_filter do
19
+ require 'vigilem/x11/stat'
20
+ vxd = Vigilem::X11::Stat.default
21
+ if vxd.available?
22
+ vxd.install
23
+ end
24
+ end
25
+
26
+ task :init_steps do
27
+ Rake::Task["setup_key_map"].invoke
28
+ Rake::Task["x11_context_filter"].invoke
29
+ end
30
+
31
+ task default: :init_steps
@@ -0,0 +1,10 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'vigilem/evdev/system/keymap_loaders'
5
+
6
+ Vigilem::Evdev::System::KeymapLoaders.build_cache
7
+
8
+ require 'fileutils'
9
+
10
+ FileUtils.chown (user = ARGV[0]), user, Vigilem::Evdev.data_dir
@@ -0,0 +1,24 @@
1
+ require 'vigilem/support/utils'
2
+
3
+ module Vigilem
4
+ # loading this will load less than the tld
5
+ module Evdev
6
+
7
+ module_function
8
+
9
+ #
10
+ #
11
+ def data_dir
12
+ @data_dir ||= Support::GemUtils.data_dir(__FILE__)
13
+ end
14
+
15
+ #
16
+ # @return [KeyMap]
17
+ def key_map
18
+ System::KeymapLoaders.key_map
19
+ end
20
+
21
+ end
22
+ end
23
+
24
+ require 'vigilem/evdev/system/keymap_loaders'
@@ -0,0 +1,14 @@
1
+ module Vigilem
2
+ module Evdev
3
+ end
4
+ end
5
+
6
+ require 'vigilem/_evdev'
7
+
8
+ require 'vigilem/evdev/input_system_handler'
9
+
10
+ require 'vigilem/evdev/dom'
11
+
12
+ require 'vigilem/evdev/system'
13
+
14
+ require 'vigilem/evdev/device'
@@ -0,0 +1,8 @@
1
+ if $0 != "irb"
2
+ require 'io/console'
3
+ begin
4
+ $stdout.echo= false
5
+ at_exit { $stdout.echo = true }
6
+ rescue Errno::EINVAL
7
+ end
8
+ end
@@ -0,0 +1,92 @@
1
+ require 'observer'
2
+
3
+ require 'forwardable'
4
+
5
+ module Vigilem
6
+ module Evdev
7
+ #
8
+ #
9
+ module ContextFilter
10
+
11
+ #
12
+ # states of the ContextFilter
13
+ module States
14
+ ON = 1
15
+ UNKNOWN = nil
16
+ OFF = 0
17
+ end
18
+
19
+ include States
20
+
21
+ #
22
+ # @return [Hash]
23
+ def state_hash
24
+ @state_hash ||= States.constants.each_with_object({}) do |const, memo|
25
+ memo[States.const_get(const)] = const
26
+ end
27
+ end
28
+
29
+ include Observable
30
+
31
+ #
32
+ #
33
+ def self.included(base)
34
+ base.extend Forwardable
35
+ end
36
+
37
+ attr_reader :last_known_state
38
+
39
+ #
40
+ # @return [TrueClass || FalseClass]
41
+ def was_on?
42
+ last_known_state == ON
43
+ end
44
+
45
+ #
46
+ # @return [TrueClass || FalseClass]
47
+ def was_off?
48
+ last_known_state.nil? || last_known_state == OFF
49
+ end
50
+
51
+ #
52
+ # @raise [NotImplementedError]
53
+ def on?
54
+ raise NotImplementedError, '#on?, not overriden'
55
+ end
56
+
57
+ alias_method :filtered?, :on?
58
+
59
+ #
60
+ # @raise [NotImplementedError]
61
+ def off?
62
+ raise NotImplementedError, '#off?, not overriden'
63
+ end
64
+
65
+ #
66
+ # @param [Fixnum<1 || 0>] state
67
+ # @return
68
+ def on_change(state)
69
+ self.last_known_state = state
70
+ changed
71
+ notify_observers(self, state)
72
+ end
73
+
74
+ private
75
+ attr_writer :last_known_state
76
+
77
+ #
78
+ # @param [TrueClass || FalseClass] bool
79
+ # @return [Fixnum<1 || 0>]
80
+ def was_on=(bool)
81
+ self.last_known_state= if bool then ON else OFF end
82
+ end
83
+
84
+ #
85
+ # @param [TrueClass || FalseClass] bool
86
+ # @return [Fixnum<1 || 0>]
87
+ def was_off=(bool)
88
+ self.was_on=!bool
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,26 @@
1
+ require 'vigilem/core/demultiplexer'
2
+
3
+ require 'vigilem/core/buffer'
4
+
5
+ module Vigilem
6
+ module Evdev
7
+ #
8
+ #
9
+ class Demultiplexer < Core::Demultiplexer
10
+
11
+ class << self
12
+ # @todo move away from singleton and look at the one used by x11
13
+ # there should only be one demultiplexer for Evdev
14
+ # @param [Array<Array<observer_object, Hash{@see #add_observer}>>] observers
15
+ # @return [Demultiplexer]
16
+ def acquire(outputs=[])
17
+ @demultiplexer ||= new(nil, outputs || [])
18
+ end
19
+
20
+ private :new
21
+
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,182 @@
1
+ require 'vigilem/evdev/system/input'
2
+
3
+ require 'vigilem/evdev/device_capabilities'
4
+
5
+ require 'vigilem/support/core_ext/enumerable'
6
+
7
+ module Vigilem
8
+ module Evdev
9
+ #
10
+ #
11
+ #
12
+ class Device < File
13
+
14
+ BITS_PER_BYTE = 8
15
+
16
+ include System::Input
17
+ extend System::Input
18
+
19
+ include DeviceCapabilities
20
+
21
+ class << self
22
+
23
+ alias_method :super_open, :open
24
+
25
+ private :super_open
26
+
27
+ #
28
+ # implement with udev
29
+ # @raises [NotImplemented]
30
+ # @param fd
31
+ # @param [String] mode
32
+ # @param [Hash] opt
33
+ # @return
34
+ def new(fd, mode='r', opt={})
35
+ raise NotImplemented, 'Cannot create device yet'
36
+ end
37
+
38
+ # @todo mode, opt
39
+ # open(filename, mode="r" [, opt])
40
+ # open(filename [, mode [, perm]] [, opt]) {|file| block } → obj
41
+ # /lib/udev/findkeyboards; method_missing -> get_keyboards?
42
+ # @see File::open
43
+ def open(filename, mode='r', opt={})
44
+ if dev = all.find {|d| File.expand_path(filename) == d.path }
45
+ dev
46
+ else
47
+ raise NotImplemented, "mode of #{mode} not supported yet" if mode != 'r'
48
+ obj_register(super(filename, mode, opt))
49
+ end
50
+ end
51
+
52
+ #
53
+ # @return [Array<Device>]
54
+ def all
55
+ @all ||= chardev_glob(default_glob).map {|fp| send(:super_open, fp) }
56
+ end
57
+
58
+ # defaults to "/dev/input"
59
+ # @return [String]
60
+ def default_dir
61
+ @default_dir ||= '/dev/input'
62
+ end
63
+
64
+ # defaults to "/dev/input/event*"
65
+ # @return [String]
66
+ def default_glob
67
+ @default_glob ||= File.join(default_dir, 'event*')
68
+ end
69
+
70
+ attr_writer :default_dir, :default_glob
71
+
72
+ # @todo
73
+ #def [](opts={})
74
+ #
75
+ #end
76
+
77
+ # executes EVIOCGNAME against known chardev's, and compares that to the
78
+ # regexp. If there is a filename_glob it checks that first.
79
+ # @param [Regexp] name_regexp
80
+ # @param [NilClass || String] glob
81
+ # @return [Array<Device>]
82
+ def name_grep(name_regexp, filename_glob=nil)
83
+ if filename_glob
84
+ file_paths = chardev_glob(filename_glob).map {|fn| File.expand_path(fn) }
85
+ file_paths.map {|f_path| dev if (dev = send(:super_open, f_path)).name =~ name_regexp }.compact.uniq
86
+ else
87
+ all.select {|dev| dev.name =~ name_regexp }
88
+ end
89
+ end
90
+
91
+ # Expands pattern, which is an Array of patterns or a pattern String,
92
+ # and returns the results as matches or as arguments given to the block.
93
+ # and returns only character devices
94
+ # @see Dir::glob
95
+ # @param [String] glob defaults to './*'
96
+ # @return [Array<String>]
97
+ def chardev_glob(glob='./*')
98
+ Dir[glob].select {|f| File::Stat.new(f).chardev? }
99
+ end
100
+ end
101
+
102
+ # name of this device
103
+ # @return [String]
104
+ def name
105
+ @name ||= begin
106
+ ioctl(EVIOCGNAME(len = 256), out_name = " " * len)
107
+ out_name.rstrip
108
+ end
109
+ end
110
+
111
+ #
112
+ # gets the ids of this device in an array
113
+ # @return [Array<Fixnum, Fixnum, Fixnum, Fixnum>] [idbus, idvendor, idproduct, idversion]
114
+ def ids
115
+ @ids ||= begin
116
+ ioctl(EVIOCGID, buf = '\x00' * 8)
117
+ buf.unpack('S!4')
118
+ end
119
+ end
120
+
121
+ # @todo test
122
+ # @todo this doesn't really belong here
123
+ def led_bits
124
+
125
+ no_of_bytes = bit_count_to_byte_count(LED_CNT - 1)
126
+
127
+ ledbit = "\x00" * no_of_bytes
128
+
129
+ ioctl(EVIOCGLED(System.sizeof("C#{no_of_bytes}")), ledbit)
130
+
131
+ ledbit[0..no_of_bytes].unpack("b*").first
132
+ end
133
+
134
+ #
135
+ # @todo test
136
+ def _bits
137
+ unless @bits
138
+ ioctl(EVIOCGBIT(0), bits = [0].pack('i'))
139
+ @bits = bits.unpack('i')[0]
140
+ end
141
+ return @bits
142
+ end
143
+
144
+ =begin @todo
145
+ def grab
146
+
147
+ end
148
+
149
+ def ungrab
150
+
151
+ end
152
+ =end
153
+
154
+ #
155
+ # @param max_len
156
+ # @param out_buf=nil
157
+ # @return [Array?]
158
+ def read_nonblock(maxlen, out_buf=nil)
159
+ raise Evdev::SizeError, 'maxlen', maxlen, ie_size if maxlen < (ie_size = InputEvent.size)
160
+ super(*[maxlen, out_buf])
161
+ end
162
+
163
+ #
164
+ # @param [Fixnum] length
165
+ # @param out_buf=nill
166
+ # @return [Array?]
167
+ def read(length=nil, outbuf=nil)
168
+ length ||= Event.size
169
+ raise Evdev::SizeError, arg_name: 'length', arg_size: length, max_size: sze if length < (sze = InputEvent.size)
170
+ super(*[length, outbuf])
171
+ end
172
+
173
+ private
174
+ #
175
+ # @todo test
176
+ def bit_count_to_byte_count(no_of_bits)
177
+ # closest without going over
178
+ (no_of_bits+7)/BITS_PER_BYTE
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,53 @@
1
+ require 'vigilem/evdev/system/input'
2
+
3
+ module Vigilem
4
+ module Evdev
5
+ #/sys/class/input/event1/device/capabilities
6
+ module DeviceCapabilities
7
+
8
+ def keys?(fd)
9
+ ((_bits >> System::Input::EV_KEY) & 1) == 1
10
+ end
11
+
12
+ def leds?
13
+ ((_bits >> System::Input::EV_LED) & 1) == 1
14
+ end
15
+
16
+ def sound?
17
+ ((_bits >> System::Input::EV_SND) & 1) == 1
18
+ end
19
+
20
+ def relative_axes?
21
+ ((_bits >> System::Input::EV_REL) & 1) == 1
22
+ end
23
+
24
+ def absolute_axes?
25
+ ((_bits >> System::Input::EV_ABS) & 1) == 1
26
+ end
27
+
28
+ def misc?
29
+ ((_bits >> System::Input::EV_MSC) & 1) == 1
30
+ end
31
+
32
+ def switches?
33
+ ((_bits >> System::Input::EV_SW) & 1) == 1
34
+ end
35
+
36
+ def repeat?
37
+ ((_bits >> System::Input::EV_REP) & 1) == 1
38
+ end
39
+
40
+ def forcefeedback?
41
+ ((_bits >> System::Input::EV_FF) & 1) == 1
42
+ end
43
+
44
+ def forcefeedback_status?
45
+ ((_bits >> System::Input::EV_FF_STATUS) & 1) == 1
46
+ end
47
+
48
+ def power?
49
+ ((_bits >> System::Input::EV_PWR) & 1) == 1
50
+ end
51
+ end
52
+ end
53
+ end