fusuma-plugin-sendkey 0.11.1 → 0.13.0
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c611a6d5d766d2e57a3c413e3c06b83561f20d9768d785601c0a3395128c77f9
|
4
|
+
data.tar.gz: 5ddd9dc6449c2db16e3e4de26e08ed4334c2e9b274f81ba4bdfa1301815bfb44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 118858d9a59878f2e830e444577be1b543ceac410027e3be5e564385d19876f0d5aa4a21f55935fede4cbc18f613e99cc8489b0c4128c1dc5d5d4d8b4e65ad0f
|
7
|
+
data.tar.gz: 28bbb84b4aaa9a5903d6473bffd5139bd2fe8ab942cbbbfc99a47e5a2567a6c76f737eb4e84ed917807f554c868f0e7c52f9d4d1bfd340694bbcfbdca4b5358b
|
data/exe/fusuma-sendkey
CHANGED
@@ -1,34 +1,32 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
8
|
-
require_relative
|
4
|
+
require "optparse"
|
5
|
+
require "fusuma/config"
|
6
|
+
require "fusuma/plugin/executors/executor"
|
7
|
+
require "fusuma/plugin/inputs/libinput_command_input"
|
8
|
+
require_relative "../lib/fusuma/plugin/sendkey/keyboard"
|
9
|
+
require_relative "../lib/fusuma/plugin/executors/sendkey_executor"
|
10
|
+
require_relative "../lib/fusuma/plugin/sendkey/version"
|
9
11
|
|
10
12
|
option = {}
|
11
13
|
opt = OptionParser.new
|
12
14
|
|
13
|
-
opt.on(
|
14
|
-
|
15
|
+
opt.on("-l", "--list-keycodes",
|
16
|
+
"List available keycodes") do |v|
|
15
17
|
option[:list] = v
|
16
18
|
end
|
17
19
|
|
18
|
-
opt.on(
|
20
|
+
opt.on("--version", "Show version") do |v|
|
19
21
|
option[:version] = v
|
20
22
|
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
if option[:list]
|
30
|
-
puts Fusuma::Plugin::Sendkey::Keyboard.new(name_pattern: device_name).search_codes
|
31
|
-
return
|
24
|
+
begin
|
25
|
+
opt.parse!(ARGV)
|
26
|
+
rescue OptionParser::InvalidOption => e
|
27
|
+
warn e
|
28
|
+
warn opt.help
|
29
|
+
exit 1
|
32
30
|
end
|
33
31
|
|
34
32
|
if option[:version]
|
@@ -36,20 +34,29 @@ if option[:version]
|
|
36
34
|
return
|
37
35
|
end
|
38
36
|
|
37
|
+
executor_index = Fusuma::Config::Index.new([:plugin, :executors, :sendkey_executor])
|
38
|
+
name_patterns = Fusuma::Config.instance.fetch_config_params(:device_name, executor_index).fetch(:device_name)
|
39
|
+
|
40
|
+
device = Fusuma::Plugin::Sendkey::Keyboard.find_device(name_patterns: name_patterns)
|
41
|
+
keyboard = Fusuma::Plugin::Sendkey::Keyboard.new(device: device)
|
42
|
+
if option[:list]
|
43
|
+
puts keyboard.search_codes("KEY_").map { |sym| sym.to_s.delete_prefix("KEY_") }
|
44
|
+
puts keyboard.search_codes("BTN_")
|
45
|
+
return
|
46
|
+
end
|
47
|
+
|
39
48
|
args = ARGV.first
|
40
49
|
|
41
50
|
if args.nil?
|
42
|
-
warn
|
43
|
-
warn
|
44
|
-
warn
|
51
|
+
warn "fusuma-sendkey require 1 arugument"
|
52
|
+
warn "e.g. fusuma-sendkey LEFTALT+LEFT"
|
53
|
+
warn "e.g. fusuma-sendkey [A, B, C]"
|
45
54
|
exit 1
|
46
55
|
end
|
47
56
|
|
48
|
-
|
49
57
|
# remove [ and ] from args
|
50
|
-
params = args.delete(
|
58
|
+
params = args.delete("[]").split(",").map(&:strip)
|
51
59
|
|
52
|
-
keyboard = Fusuma::Plugin::Sendkey::Keyboard.new(name_pattern: device_name)
|
53
60
|
return unless keyboard.valid?(params)
|
54
61
|
|
55
62
|
if params.size == 1
|
@@ -18,7 +18,7 @@ module Fusuma
|
|
18
18
|
|
19
19
|
def config_param_types
|
20
20
|
{
|
21
|
-
device_name: String
|
21
|
+
device_name: [String, Array]
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
@@ -55,7 +55,10 @@ module Fusuma
|
|
55
55
|
private
|
56
56
|
|
57
57
|
def keyboard
|
58
|
-
@keyboard ||=
|
58
|
+
@keyboard ||= begin
|
59
|
+
device = Sendkey::Keyboard.find_device(name_patterns: @device_name)
|
60
|
+
Sendkey::Keyboard.new(device: device)
|
61
|
+
end
|
59
62
|
end
|
60
63
|
|
61
64
|
def search_param(event)
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "revdev"
|
4
|
+
require "set"
|
5
|
+
|
3
6
|
module Fusuma
|
4
7
|
module Plugin
|
5
8
|
module Sendkey
|
@@ -7,8 +10,11 @@ module Fusuma
|
|
7
10
|
class Device
|
8
11
|
def initialize(path:)
|
9
12
|
@evdev = Revdev::EventDevice.new(path)
|
13
|
+
@capabilities = Set.new
|
10
14
|
end
|
11
15
|
|
16
|
+
attr_reader :capabilities
|
17
|
+
|
12
18
|
def path
|
13
19
|
raise "Device path is not found" if @evdev.nil?
|
14
20
|
|
@@ -18,6 +24,31 @@ module Fusuma
|
|
18
24
|
def write_event(event)
|
19
25
|
@evdev.write_input_event(event)
|
20
26
|
end
|
27
|
+
|
28
|
+
def reload_capability
|
29
|
+
@capabilities.clear
|
30
|
+
|
31
|
+
buf = fetch_capabilities
|
32
|
+
buf.unpack("C*").each_with_index do |byte, i|
|
33
|
+
8.times do |bit| # 0..7
|
34
|
+
if byte[bit] != 0
|
35
|
+
@capabilities << (i * 8 + bit)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@capabilities
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
EVIOCGBIT = 2153792801
|
45
|
+
|
46
|
+
def fetch_capabilities
|
47
|
+
file = File.open(path, "r")
|
48
|
+
buf = +"" # unfreeze string
|
49
|
+
file.ioctl(EVIOCGBIT, buf)
|
50
|
+
buf
|
51
|
+
end
|
21
52
|
end
|
22
53
|
end
|
23
54
|
end
|
@@ -10,7 +10,7 @@ module Fusuma
|
|
10
10
|
module Sendkey
|
11
11
|
# Emulate Keyboard
|
12
12
|
class Keyboard
|
13
|
-
INTERVAL = 0.
|
13
|
+
INTERVAL = 0.03
|
14
14
|
|
15
15
|
MODIFIER_KEY_CODES = %w[
|
16
16
|
KEY_CAPSLOCK
|
@@ -24,25 +24,28 @@ module Fusuma
|
|
24
24
|
KEY_RIGHTMETA
|
25
25
|
].freeze
|
26
26
|
|
27
|
-
def self.find_device(
|
27
|
+
def self.find_device(name_patterns:)
|
28
28
|
Fusuma::Device.reset
|
29
|
-
Fusuma::Device.all.find { |d|
|
30
|
-
next unless /keyboard/.match?(d.capabilities)
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
Array(name_patterns).each do |name_pattern|
|
31
|
+
fusuma_device = Fusuma::Device.all.find { |d|
|
32
|
+
next unless d.capabilities.include?("keyboard")
|
35
33
|
|
36
|
-
|
37
|
-
|
34
|
+
d.name.match(/#{name_pattern}/)
|
35
|
+
}
|
38
36
|
|
39
|
-
|
37
|
+
if fusuma_device
|
38
|
+
MultiLogger.info "sendkey: Keyboard: #{fusuma_device.name}"
|
39
|
+
return Device.new(path: "/dev/input/#{fusuma_device.id}")
|
40
|
+
end
|
40
41
|
warn "sendkey: Keyboard: /#{name_pattern}/ is not found"
|
41
|
-
exit(1)
|
42
42
|
end
|
43
|
-
MultiLogger.info "sendkey: Keyboard: #{device.name}"
|
44
43
|
|
45
|
-
|
44
|
+
exit(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(device:)
|
48
|
+
@device = device
|
46
49
|
end
|
47
50
|
|
48
51
|
# @param params [Array]
|
@@ -65,8 +68,8 @@ module Fusuma
|
|
65
68
|
def type(param:, keep: "", clear: :none)
|
66
69
|
return unless param.is_a?(String)
|
67
70
|
|
68
|
-
param_keycodes =
|
69
|
-
type_keycodes = param_keycodes -
|
71
|
+
param_keycodes = param_to_codes(param)
|
72
|
+
type_keycodes = param_keycodes - param_to_codes(keep)
|
70
73
|
|
71
74
|
clear_keycodes =
|
72
75
|
case clear
|
@@ -76,12 +79,13 @@ module Fusuma
|
|
76
79
|
[]
|
77
80
|
else
|
78
81
|
# release keys specified by clearmodifiers
|
79
|
-
|
82
|
+
param_to_codes(clear)
|
80
83
|
end
|
81
84
|
|
82
85
|
clear_modifiers(clear_keycodes - param_keycodes)
|
83
86
|
|
84
87
|
type_keycodes.each { |keycode| keydown(keycode) && key_sync }
|
88
|
+
sleep(INTERVAL)
|
85
89
|
type_keycodes.reverse_each { |keycode| keyup(keycode) && key_sync }
|
86
90
|
end
|
87
91
|
|
@@ -100,7 +104,7 @@ module Fusuma
|
|
100
104
|
params.all? { |param| valid?(param) }
|
101
105
|
when String
|
102
106
|
param = params
|
103
|
-
keycodes =
|
107
|
+
keycodes = param_to_codes(param)
|
104
108
|
keycodes.all? { |keycode| support?(keycode) }
|
105
109
|
else
|
106
110
|
MultiLogger.error "sendkey: Invalid config: #{params}"
|
@@ -126,35 +130,40 @@ module Fusuma
|
|
126
130
|
0
|
127
131
|
)
|
128
132
|
@device.write_event(event)
|
129
|
-
sleep(INTERVAL)
|
130
133
|
end
|
131
134
|
|
132
|
-
def
|
133
|
-
@
|
134
|
-
|
135
|
+
def capabilities
|
136
|
+
return @capabilities if defined?(@capabilities)
|
137
|
+
|
138
|
+
@capabilities = Set.new.tap do |set|
|
139
|
+
@device.reload_capability.each do |id|
|
140
|
+
code_sym = Revdev::REVERSE_MAPS[:KEY][id]
|
141
|
+
set << code_sym if code_sym
|
142
|
+
end
|
143
|
+
end
|
135
144
|
end
|
136
145
|
|
137
|
-
def
|
138
|
-
|
146
|
+
def support?(code)
|
147
|
+
@supported_code ||= {}
|
148
|
+
@supported_code[code] ||= find_code(code)
|
149
|
+
end
|
139
150
|
|
140
|
-
|
151
|
+
def warn_undefined_codes(code)
|
152
|
+
candidates = search_codes(code).map { |c| remove_prefix(c.to_s) }
|
141
153
|
|
142
154
|
warn "Did you mean? #{candidates.join(" / ")}" unless candidates.empty?
|
143
|
-
warn "sendkey: #{remove_prefix(keycode)} is unsupported."
|
144
|
-
end
|
145
155
|
|
146
|
-
|
147
|
-
Revdev.constants
|
148
|
-
.select { |c| c[/KEY_.*#{query}.*/] }
|
149
|
-
.map { |c| c.to_s.gsub("KEY_", "") }
|
156
|
+
warn "sendkey: #{remove_prefix(code)} is unsupported."
|
150
157
|
end
|
151
158
|
|
152
|
-
def
|
153
|
-
|
159
|
+
def search_codes(code)
|
160
|
+
capabilities.select { |c| c[code] }
|
161
|
+
end
|
154
162
|
|
155
|
-
|
163
|
+
def find_code(code)
|
164
|
+
result = capabilities.find { |c| c == code.to_sym }
|
156
165
|
|
157
|
-
warn_undefined_codes(
|
166
|
+
warn_undefined_codes(code) unless result
|
158
167
|
result
|
159
168
|
end
|
160
169
|
|
@@ -169,14 +178,19 @@ module Fusuma
|
|
169
178
|
|
170
179
|
# @param [String]
|
171
180
|
# @return [Array<String>]
|
172
|
-
def
|
173
|
-
param.split("+").map { |keyname|
|
181
|
+
def param_to_codes(param)
|
182
|
+
param.split("+").map { |keyname| add_prefix(keyname) }
|
174
183
|
end
|
175
184
|
|
176
185
|
private
|
177
186
|
|
178
|
-
def
|
179
|
-
|
187
|
+
def add_prefix(code)
|
188
|
+
code.upcase!
|
189
|
+
if code.start_with?("BTN_")
|
190
|
+
code
|
191
|
+
else
|
192
|
+
"KEY_#{code}"
|
193
|
+
end
|
180
194
|
end
|
181
195
|
|
182
196
|
def remove_prefix(keycode)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fusuma-plugin-sendkey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iberianpig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-09-
|
11
|
+
date: 2024-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fusuma
|