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.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/ext/Rakefile +31 -0
- data/ext/rake_helper.rb +10 -0
- data/lib/vigilem/_evdev.rb +24 -0
- data/lib/vigilem/evdev.rb +14 -0
- data/lib/vigilem/evdev/at_exit.rb +8 -0
- data/lib/vigilem/evdev/context_filter.rb +92 -0
- data/lib/vigilem/evdev/demultiplexer.rb +26 -0
- data/lib/vigilem/evdev/device.rb +182 -0
- data/lib/vigilem/evdev/device_capabilities.rb +53 -0
- data/lib/vigilem/evdev/dom.rb +8 -0
- data/lib/vigilem/evdev/dom/adapter.rb +87 -0
- data/lib/vigilem/evdev/dom/code_values_tables.rb +172 -0
- data/lib/vigilem/evdev/dom/input_event_converter.rb +329 -0
- data/lib/vigilem/evdev/dom/input_event_utils.rb +48 -0
- data/lib/vigilem/evdev/dom/key_values_tables.rb +248 -0
- data/lib/vigilem/evdev/dom/kp_table.rb +52 -0
- data/lib/vigilem/evdev/focus_context_filter.rb +124 -0
- data/lib/vigilem/evdev/input_system_handler.rb +69 -0
- data/lib/vigilem/evdev/key_map_cache.rb +64 -0
- data/lib/vigilem/evdev/multiplexer.rb +73 -0
- data/lib/vigilem/evdev/system.rb +17 -0
- data/lib/vigilem/evdev/system/input.rb +1053 -0
- data/lib/vigilem/evdev/system/input/event.rb +4 -0
- data/lib/vigilem/evdev/system/input/input_event.rb +33 -0
- data/lib/vigilem/evdev/system/int.rb +9 -0
- data/lib/vigilem/evdev/system/ioctl.rb +143 -0
- data/lib/vigilem/evdev/system/keymap_loaders.rb +89 -0
- data/lib/vigilem/evdev/system/keymap_loaders/dumpkeys_loader.rb +98 -0
- data/lib/vigilem/evdev/system/keymap_loaders/kmap_loader.rb +74 -0
- data/lib/vigilem/evdev/system/posix_types.rb +5 -0
- data/lib/vigilem/evdev/system/time.rb +21 -0
- data/lib/vigilem/evdev/transfer_agent.rb +40 -0
- data/lib/vigilem/evdev/version.rb +5 -0
- data/lib/vigilem/evdev/vty_context_filter.rb +216 -0
- data/spec/after_each_example_group.rb +29 -0
- data/spec/delete_test_cache_after_group.rb +26 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/vigilem/_evdev_spec.rb +11 -0
- data/spec/vigilem/evdev/context_filter_spec.rb +114 -0
- data/spec/vigilem/evdev/demultiplexer_spec.rb +44 -0
- data/spec/vigilem/evdev/device_capabilities_spec.rb +0 -0
- data/spec/vigilem/evdev/device_spec.rb +97 -0
- data/spec/vigilem/evdev/dom/adapter_spec.rb +5 -0
- data/spec/vigilem/evdev/dom/input_event_converter_spec.rb +253 -0
- data/spec/vigilem/evdev/dom/input_event_utils_spec.rb +23 -0
- data/spec/vigilem/evdev/focus_context_filter_spec.rb +112 -0
- data/spec/vigilem/evdev/input_system_handler_spec.rb +146 -0
- data/spec/vigilem/evdev/key_map_cache_spec.rb +65 -0
- data/spec/vigilem/evdev/multiplexer_spec.rb +55 -0
- data/spec/vigilem/evdev/system/input/input_event_spec.rb +33 -0
- data/spec/vigilem/evdev/system/input_spec.rb +274 -0
- data/spec/vigilem/evdev/system/int_spec.rb +30 -0
- data/spec/vigilem/evdev/system/ioctl_spec.rb +206 -0
- data/spec/vigilem/evdev/system/keymap_loaders/dumpkeys_loader_spec.rb +5 -0
- data/spec/vigilem/evdev/system/keymap_loaders/kmap_loader_spec.rb +24 -0
- data/spec/vigilem/evdev/system/keymap_loaders_spec.rb +22 -0
- data/spec/vigilem/evdev/system/posix_types_spec.rb +15 -0
- data/spec/vigilem/evdev/system/time_spec.rb +18 -0
- data/spec/vigilem/evdev/transfer_agent_spec.rb +57 -0
- data/spec/vigilem/evdev/vty_context_filter_spec.rb +282 -0
- metadata +286 -0
checksums.yaml
ADDED
@@ -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
|
data/LICENSE.txt
ADDED
@@ -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.
|
data/ext/Rakefile
ADDED
@@ -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
|
data/ext/rake_helper.rb
ADDED
@@ -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,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
|