fusuma-plugin-sendkey 0.12.0 → 0.13.1
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: 65cd0d7ac4a2a78edf9e316d12e1a013a534817fb672228811d2a53deadb6d48
|
4
|
+
data.tar.gz: 7fac8215b62b4cfd7f7e83eaa2005864b94b56f295042ef610c0bca525752d5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6a6d245843e9e9bc4549e15290d3c64d01c19362b5da5892db2df79a807c3fde7a1d31ced8a0c1bf57dccaefa66aa962a5bc64fcf4198c429375c4cf3565a4c
|
7
|
+
data.tar.gz: e2bc2a7f42436038b2da1c68c72ad585375fa633c6d41396144815f101be42fe972899a5b0a0033d721124d63f680611f77b147ed54bad6ee60e866e3255a2fc
|
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
|
@@ -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
|
-
|
13
|
+
KEY_INTERVAL = 0.03
|
14
14
|
|
15
15
|
MODIFIER_KEY_CODES = %w[
|
16
16
|
KEY_CAPSLOCK
|
@@ -24,30 +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
|
-
|
35
|
-
|
36
|
-
def initialize(name_pattern: nil)
|
37
|
-
device = nil
|
30
|
+
Array(name_patterns).each do |name_pattern|
|
31
|
+
fusuma_device = Fusuma::Device.all.find { |d|
|
32
|
+
next unless d.capabilities.include?("keyboard")
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
break if device
|
42
|
-
end
|
34
|
+
d.name.match(/#{name_pattern}/)
|
35
|
+
}
|
43
36
|
|
44
|
-
|
37
|
+
if fusuma_device
|
38
|
+
MultiLogger.info "sendkey: Keyboard: #{fusuma_device.name}"
|
39
|
+
return Device.new(path: "/dev/input/#{fusuma_device.id}")
|
40
|
+
end
|
45
41
|
warn "sendkey: Keyboard: /#{name_pattern}/ is not found"
|
46
|
-
exit(1)
|
47
42
|
end
|
48
|
-
MultiLogger.info "sendkey: Keyboard: #{device.name}"
|
49
43
|
|
50
|
-
|
44
|
+
exit(1)
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(device:)
|
48
|
+
@device = device
|
51
49
|
end
|
52
50
|
|
53
51
|
# @param params [Array]
|
@@ -70,8 +68,8 @@ module Fusuma
|
|
70
68
|
def type(param:, keep: "", clear: :none)
|
71
69
|
return unless param.is_a?(String)
|
72
70
|
|
73
|
-
param_keycodes =
|
74
|
-
type_keycodes = param_keycodes -
|
71
|
+
param_keycodes = param_to_codes(param)
|
72
|
+
type_keycodes = param_keycodes - param_to_codes(keep)
|
75
73
|
|
76
74
|
clear_keycodes =
|
77
75
|
case clear
|
@@ -81,13 +79,13 @@ module Fusuma
|
|
81
79
|
[]
|
82
80
|
else
|
83
81
|
# release keys specified by clearmodifiers
|
84
|
-
|
82
|
+
param_to_codes(clear)
|
85
83
|
end
|
86
84
|
|
87
85
|
clear_modifiers(clear_keycodes - param_keycodes)
|
88
86
|
|
89
|
-
type_keycodes.each { |keycode| keydown(keycode) && key_sync }
|
90
|
-
type_keycodes.reverse_each { |keycode| keyup(keycode) && key_sync }
|
87
|
+
type_keycodes.each { |keycode| keydown(keycode) && key_sync && sleep(KEY_INTERVAL) }
|
88
|
+
type_keycodes.reverse_each { |keycode| keyup(keycode) && key_sync && sleep(KEY_INTERVAL) }
|
91
89
|
end
|
92
90
|
|
93
91
|
def keydown(keycode)
|
@@ -105,7 +103,7 @@ module Fusuma
|
|
105
103
|
params.all? { |param| valid?(param) }
|
106
104
|
when String
|
107
105
|
param = params
|
108
|
-
keycodes =
|
106
|
+
keycodes = param_to_codes(param)
|
109
107
|
keycodes.all? { |keycode| support?(keycode) }
|
110
108
|
else
|
111
109
|
MultiLogger.error "sendkey: Invalid config: #{params}"
|
@@ -131,35 +129,40 @@ module Fusuma
|
|
131
129
|
0
|
132
130
|
)
|
133
131
|
@device.write_event(event)
|
134
|
-
sleep(INTERVAL)
|
135
132
|
end
|
136
133
|
|
137
|
-
def
|
138
|
-
@
|
139
|
-
|
134
|
+
def capabilities
|
135
|
+
return @capabilities if defined?(@capabilities)
|
136
|
+
|
137
|
+
@capabilities = Set.new.tap do |set|
|
138
|
+
@device.reload_capability.each do |id|
|
139
|
+
code_sym = Revdev::REVERSE_MAPS[:KEY][id]
|
140
|
+
set << code_sym if code_sym
|
141
|
+
end
|
142
|
+
end
|
140
143
|
end
|
141
144
|
|
142
|
-
def
|
143
|
-
|
145
|
+
def support?(code)
|
146
|
+
@supported_code ||= {}
|
147
|
+
@supported_code[code] ||= find_code(code)
|
148
|
+
end
|
144
149
|
|
145
|
-
|
150
|
+
def warn_undefined_codes(code)
|
151
|
+
candidates = search_codes(code).map { |c| remove_prefix(c.to_s) }
|
146
152
|
|
147
153
|
warn "Did you mean? #{candidates.join(" / ")}" unless candidates.empty?
|
148
|
-
warn "sendkey: #{remove_prefix(keycode)} is unsupported."
|
149
|
-
end
|
150
154
|
|
151
|
-
|
152
|
-
Revdev.constants
|
153
|
-
.select { |c| c[/KEY_.*#{query}.*/] }
|
154
|
-
.map { |c| c.to_s.gsub("KEY_", "") }
|
155
|
+
warn "sendkey: #{remove_prefix(code)} is unsupported."
|
155
156
|
end
|
156
157
|
|
157
|
-
def
|
158
|
-
|
158
|
+
def search_codes(code)
|
159
|
+
capabilities.select { |c| c[code] }
|
160
|
+
end
|
159
161
|
|
160
|
-
|
162
|
+
def find_code(code)
|
163
|
+
result = capabilities.find { |c| c == code.to_sym }
|
161
164
|
|
162
|
-
warn_undefined_codes(
|
165
|
+
warn_undefined_codes(code) unless result
|
163
166
|
result
|
164
167
|
end
|
165
168
|
|
@@ -174,14 +177,19 @@ module Fusuma
|
|
174
177
|
|
175
178
|
# @param [String]
|
176
179
|
# @return [Array<String>]
|
177
|
-
def
|
178
|
-
param.split("+").map { |keyname|
|
180
|
+
def param_to_codes(param)
|
181
|
+
param.split("+").map { |keyname| add_prefix(keyname) }
|
179
182
|
end
|
180
183
|
|
181
184
|
private
|
182
185
|
|
183
|
-
def
|
184
|
-
|
186
|
+
def add_prefix(code)
|
187
|
+
code.upcase!
|
188
|
+
if code.start_with?("BTN_")
|
189
|
+
code
|
190
|
+
else
|
191
|
+
"KEY_#{code}"
|
192
|
+
end
|
185
193
|
end
|
186
194
|
|
187
195
|
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.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iberianpig
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fusuma
|
@@ -62,7 +62,7 @@ homepage: https://github.com/iberianpig/fusuma-plugin-sendkey
|
|
62
62
|
licenses:
|
63
63
|
- MIT
|
64
64
|
metadata: {}
|
65
|
-
post_install_message:
|
65
|
+
post_install_message:
|
66
66
|
rdoc_options: []
|
67
67
|
require_paths:
|
68
68
|
- lib
|
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
version: '0'
|
79
79
|
requirements: []
|
80
80
|
rubygems_version: 3.4.19
|
81
|
-
signing_key:
|
81
|
+
signing_key:
|
82
82
|
specification_version: 4
|
83
83
|
summary: Fusuma plugin to send keyboard events
|
84
84
|
test_files: []
|