vigilem-evdev 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -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,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
|