xinput_wrapper 0.4.1 → 0.7.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/xinput_wrapper.rb +234 -25
- metadata +33 -33
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af1558bd803a67895343a73b2001a42194b5402bc8998d410d9c388b4836a593
|
4
|
+
data.tar.gz: 63e171df3280f2385b404f82673037a2a69e47e758be649253dc6701bc61a089
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1874c64eed6da4e726bc9e2e8ae755e0e7e3162cce593db5109aa344210b10f414c4917daecd8e188a28287c4a1d13188b23912e42680354adcc114714476e6b
|
7
|
+
data.tar.gz: 9af8809d460ff318ff88fc6f49e310bff9ad612f8c800a9aceae0efe55d4a8f70f32cac93e704de837f6683cb09ef8a366b029d78283587bd1af6450b7246b33
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/xinput_wrapper.rb
CHANGED
@@ -2,14 +2,40 @@
|
|
2
2
|
|
3
3
|
# file: xinput_wrapper.rb
|
4
4
|
|
5
|
+
# Captures keyboard or mouse events using program xinput.
|
6
|
+
|
7
|
+
|
8
|
+
# note: To display a list of xinput devices, run the
|
9
|
+
# xinput program without any options.
|
10
|
+
|
5
11
|
require 'c32'
|
6
12
|
|
7
13
|
|
14
|
+
MOTION = 6
|
15
|
+
RAWKEY_PRESS = 13
|
16
|
+
RAWKEY_RELEASE = 14
|
17
|
+
RAWBUTTON_PRESS = 15
|
18
|
+
RAWBUTTON_RELEASE = 16
|
19
|
+
BUTTONS = %i(left middle right scrollup scrolldown)
|
20
|
+
|
21
|
+
|
8
22
|
class XInputWrapper
|
9
23
|
using ColouredText
|
24
|
+
|
25
|
+
attr_accessor :stop
|
10
26
|
|
11
|
-
|
27
|
+
# device list:
|
28
|
+
# 3 = Virtual core keyboard
|
29
|
+
# 4 = Virtual core XTEST pointer (active when using VNC)
|
30
|
+
# 5 = Virtual core XTEST keyboard (active when using VNC)
|
31
|
+
# 10 = USB Optical Mouse (locally attached)
|
32
|
+
# 11 = Microsoft Wired Keyboard 600 (locally attached)
|
33
|
+
#
|
34
|
+
def initialize(device: nil, verbose: true, lookup: {}, debug: false,
|
35
|
+
callback: nil )
|
12
36
|
|
37
|
+
@callback = callback
|
38
|
+
|
13
39
|
# defaults to QWERTY keyboard layout
|
14
40
|
@modifiers = {
|
15
41
|
62 => :shift, # right control
|
@@ -29,7 +55,7 @@ class XInputWrapper
|
|
29
55
|
40=>:d, 41=>:f, 42=>:g, 43=>:h, 44=>:j, 45=>:k, 46=>:l, 47=>:";",
|
30
56
|
48=>:"'", 49=>nil, 52=>:z, 53=>:x, 54=>:c, 55=>:v, 56=>:b, 57=>:n,
|
31
57
|
58=>:m, 59=>:",", 60=>:".", 61=>:/, 65=>:space,
|
32
|
-
9 => :
|
58
|
+
9 => :esc,
|
33
59
|
66 => :capslock,
|
34
60
|
67 => :f1,
|
35
61
|
68 => :f2,
|
@@ -42,18 +68,18 @@ class XInputWrapper
|
|
42
68
|
75 => :f9,
|
43
69
|
76 => :f10,
|
44
70
|
77 => :numlock,
|
45
|
-
78 => :
|
71
|
+
78 => :scrolllock,
|
46
72
|
95 => :f11,
|
47
73
|
96 => :f12,
|
48
|
-
107 => :print_screen
|
74
|
+
107 => :sysrq, # print_screen
|
49
75
|
110 => :home,
|
50
|
-
111 => :
|
51
|
-
112 => :
|
52
|
-
113 => :
|
53
|
-
114 => :
|
54
|
-
115 => :end,
|
55
|
-
116 => :
|
56
|
-
117 => :
|
76
|
+
111 => :up, # arrow keys
|
77
|
+
112 => :pageup,
|
78
|
+
113 => :left, # arrow keys
|
79
|
+
114 => :right, # arrow keys
|
80
|
+
115 => :end,
|
81
|
+
116 => :down, # arrow keys
|
82
|
+
117 => :pagedown,
|
57
83
|
121 => :mute,
|
58
84
|
122 => :vol_down,
|
59
85
|
123 => :vol_up,
|
@@ -78,27 +104,109 @@ class XInputWrapper
|
|
78
104
|
end
|
79
105
|
|
80
106
|
def listen()
|
81
|
-
|
107
|
+
|
108
|
+
@stop = false
|
109
|
+
|
82
110
|
command = "xinput test-xi2 --root #{@device}"
|
83
111
|
|
84
112
|
type = 0
|
85
113
|
raw_keys = []
|
114
|
+
t1 = Time.now
|
115
|
+
lines = []
|
86
116
|
|
87
117
|
IO.popen(command).each_line do |x|
|
88
118
|
|
119
|
+
break if @stop
|
89
120
|
#print "GOT ", x
|
90
|
-
|
121
|
+
if x[/EVENT type \d \(Motion\)/] and (Time.now > (t1 + 0.06125)) then
|
122
|
+
|
123
|
+
type = x[/EVENT type (\d+)/,1].to_i
|
124
|
+
|
125
|
+
r = lines.join[/^\s+root: (\d+\.\d{2}\/\d+\.\d{2})/,1]
|
126
|
+
|
127
|
+
if r then
|
128
|
+
|
129
|
+
x1, y1 = r.split('/').map(&:to_f)
|
130
|
+
puts "x1: %s y1: %s" % [x1, y1] if @debug
|
131
|
+
on_mousemove(x1, y1)
|
132
|
+
@callback.on_mousemove(x1, y1) if @callback
|
133
|
+
@mouse_pos = [x1,y1]
|
134
|
+
t1 = Time.now
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
lines = [x]
|
139
|
+
|
140
|
+
elsif x[/EVENT type \d+ \(Raw(?:Key|Button)(?:Release|Press)\)/]
|
141
|
+
|
142
|
+
type = x[/EVENT type (\d+)/,1].to_i
|
143
|
+
|
144
|
+
lines = [x]
|
145
|
+
|
146
|
+
|
147
|
+
elsif [MOTION, RAWKEY_PRESS, RAWKEY_RELEASE, RAWBUTTON_PRESS,
|
148
|
+
RAWBUTTON_RELEASE].include? type
|
149
|
+
|
150
|
+
lines << x
|
151
|
+
|
152
|
+
if x == "\n" then
|
153
|
+
case lines.first[/(?<=EVENT type )\d+/].to_i
|
154
|
+
when RAWKEY_PRESS
|
155
|
+
|
156
|
+
r = lines.join[/detail: (\d+)/,1]
|
157
|
+
|
158
|
+
keycode = r.to_i if r
|
91
159
|
|
92
|
-
|
93
|
-
|
160
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
161
|
+
|
162
|
+
when RAWKEY_RELEASE
|
163
|
+
|
164
|
+
r = lines.join[/detail: (\d+)/,1]
|
165
|
+
|
166
|
+
keycode = r.to_i if r
|
167
|
+
|
168
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
94
169
|
|
95
|
-
|
96
|
-
|
170
|
+
|
171
|
+
when RAWBUTTON_PRESS
|
172
|
+
|
173
|
+
r = lines.join[/detail: (\d+)/,1]
|
174
|
+
|
175
|
+
buttoncode = r.to_i if r
|
176
|
+
|
177
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
178
|
+
|
179
|
+
when RAWBUTTON_RELEASE
|
180
|
+
|
181
|
+
r = lines.join[/detail: (\d+)/,1]
|
182
|
+
|
183
|
+
buttoncode = r.to_i if r
|
184
|
+
|
185
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
else
|
191
|
+
next
|
192
|
+
end
|
193
|
+
|
194
|
+
else
|
195
|
+
next
|
196
|
+
end
|
197
|
+
|
198
|
+
next unless keycode or buttoncode
|
199
|
+
puts 'keycode: ' + keycode.inspect if @debug
|
200
|
+
puts 'buttoncode: ' + buttoncode.inspect if @debug
|
97
201
|
|
98
202
|
# type = 13 means a key has been pressed
|
99
|
-
if type ==
|
203
|
+
if type == RAWKEY_PRESS then
|
100
204
|
|
101
|
-
raw_keys
|
205
|
+
if @modifiers.include? raw_keys.last or @modifiers.include? keycode then
|
206
|
+
raw_keys << keycode
|
207
|
+
end
|
208
|
+
|
209
|
+
next if @modifiers.include? keycode
|
102
210
|
|
103
211
|
puts 'raw_keys: ' + raw_keys.inspect if @debug
|
104
212
|
|
@@ -113,29 +221,82 @@ class XInputWrapper
|
|
113
221
|
puts ('key: ' + key.inspect).debug if @debug
|
114
222
|
|
115
223
|
if key then
|
224
|
+
|
116
225
|
puts key.to_s + ' key presssed' if @verbose
|
117
226
|
name = "on_#{key}_key".to_sym
|
118
227
|
method(name).call if self.protected_methods.include? name
|
119
228
|
|
120
|
-
keystring = ((key.length > 1 or key == ' ') ? "{%s}" % key : key)
|
121
|
-
|
229
|
+
keystring = ((key.length > 1 or key == ' ') ? "{%s}" % key : key)
|
230
|
+
block_given? ? yield(keystring) : on_key_press(keystring, keycode)
|
231
|
+
@callback.on_keypress(keystring, keycode) if @callback
|
232
|
+
|
122
233
|
end
|
123
234
|
|
124
235
|
else
|
125
236
|
|
126
237
|
keys = raw_keys.map {|kc| @lookup[kc] }
|
127
238
|
puts ('keys: ' + keys.inspect) if @debug
|
128
|
-
|
239
|
+
|
240
|
+
if block_given? then
|
241
|
+
yield(format_key(keys.last, keys[0..-2]))
|
242
|
+
else
|
243
|
+
on_key_press(keys.last, keycode, keys[0..-2])
|
244
|
+
@callback.on_keypress(keys.last, keycode, keys[0..-2]) if @callback
|
245
|
+
end
|
246
|
+
|
247
|
+
raw_keys = []
|
129
248
|
|
130
249
|
end
|
131
250
|
|
132
251
|
|
133
252
|
|
134
|
-
|
253
|
+
# a key has been released
|
254
|
+
elsif type == RAWKEY_RELEASE
|
255
|
+
|
256
|
+
# here we are only looking to detect a
|
257
|
+
# single modifier key press and release
|
258
|
+
|
259
|
+
key = @lookup[keycode]
|
260
|
+
|
261
|
+
unless raw_keys.empty? then
|
262
|
+
puts key.to_s + ' key presssed'
|
263
|
+
|
264
|
+
if block_given? then
|
265
|
+
|
266
|
+
yield(format_key(key.to_s))
|
267
|
+
|
268
|
+
else
|
269
|
+
name = "on_#{key}_key".to_sym
|
270
|
+
method(name).call if self.protected_methods.include? name
|
271
|
+
on_key_press(key, keycode)
|
272
|
+
@callback.on_keypress(key, keycode) if @callback
|
273
|
+
end
|
274
|
+
end
|
135
275
|
|
136
276
|
index = raw_keys.rindex(keycode)
|
137
277
|
raw_keys.delete_at index if index
|
138
|
-
|
278
|
+
|
279
|
+
elsif type == RAWBUTTON_PRESS
|
280
|
+
|
281
|
+
button = BUTTONS[buttoncode-1]
|
282
|
+
|
283
|
+
case button
|
284
|
+
when :scrollup
|
285
|
+
on_mouse_scrollup()
|
286
|
+
@callback.on_mouse_scrollup() if @callback
|
287
|
+
when :scrolldown
|
288
|
+
on_mouse_scrolldown()
|
289
|
+
@callback.on_mouse_scrolldown() if @callback
|
290
|
+
else
|
291
|
+
on_mousedown(button, *@mouse_pos)
|
292
|
+
@callback.on_mousedown(button, *@mouse_pos) if @callback
|
293
|
+
end
|
294
|
+
|
295
|
+
elsif type == RAWBUTTON_RELEASE
|
296
|
+
|
297
|
+
button = BUTTONS[buttoncode-1]
|
298
|
+
on_mouseup(BUTTONS[buttoncode-1], *@mouse_pos)
|
299
|
+
|
139
300
|
end
|
140
301
|
|
141
302
|
end
|
@@ -147,13 +308,54 @@ class XInputWrapper
|
|
147
308
|
puts 'ctrl key pressed'
|
148
309
|
end
|
149
310
|
|
150
|
-
def on_key_press(key, keycode, modifier)
|
311
|
+
def on_key_press(key, keycode, modifier=nil)
|
151
312
|
|
152
313
|
if @debug then
|
153
314
|
puts ('key: ' + key.inspect).debug
|
154
315
|
end
|
155
316
|
|
156
317
|
end
|
318
|
+
|
319
|
+
def on_mousedown(button, x,y)
|
320
|
+
|
321
|
+
if @debug then
|
322
|
+
puts "on_mousedown() %s click x: %s y: %s" % [button, x, y]
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
|
327
|
+
def on_mousemove(x,y)
|
328
|
+
|
329
|
+
if @debug then
|
330
|
+
puts "on_mousemove() x: %s y: %s" % [x, y]
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
def on_mouseup(button, x,y)
|
336
|
+
|
337
|
+
if @debug then
|
338
|
+
puts "on_mousedown() %s click x: %s y: %s" % [button, x, y]
|
339
|
+
end
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
def on_mouse_scrolldown()
|
344
|
+
|
345
|
+
if @debug then
|
346
|
+
puts "on_mouse_scrolldown()"
|
347
|
+
end
|
348
|
+
|
349
|
+
end
|
350
|
+
|
351
|
+
def on_mouse_scrollup()
|
352
|
+
|
353
|
+
if @debug then
|
354
|
+
puts "on_mouse_scrollup()"
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
157
359
|
|
158
360
|
def on_shift_key() end
|
159
361
|
def on_super_key() end
|
@@ -173,6 +375,13 @@ class XInputWrapper
|
|
173
375
|
|
174
376
|
private
|
175
377
|
|
378
|
+
def format_key(key, modifier=[])
|
379
|
+
|
380
|
+
modifier.any? ? "{%s}" % (modifier + [key.to_s]).join('+') \
|
381
|
+
: key.to_s
|
382
|
+
|
383
|
+
end
|
384
|
+
|
176
385
|
def on_leftcontrol_key() on_control_key() end
|
177
386
|
def on_rightcontrol_key() on_control_key() end
|
178
387
|
def on_left_alt_key() on_alt_key() end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xinput_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -11,52 +11,52 @@ cert_chain:
|
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIEXjCCAsagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFnZW1t
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMjAwODAzMjEwMTE2WhcN
|
15
|
+
MjEwODAzMjEwMTE2WjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
|
16
|
+
cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDdnN5k
|
17
|
+
jxSdi5vMTqhRRJ8yFAV3MYUs/W6NU+rMUk1uqTC/J+fFox8tg7t4VzQoQq539Onk
|
18
|
+
5iPFJhwo3jAYKIyc+LX4e3CtQMdrheyY/XkaTSu1yPR+c4lT8nhKUf4gI28hNXcx
|
19
|
+
lNekrvzzXBVZMGs5F+gKzOYUFS+i0jGPaVaison+iaGVLcjc2/t3AGIQeOHo7QYv
|
20
|
+
6Sswkj9Er4jkwJKHGAvLvh+KTcm/aImIfV4v5FUm6xJMi42lsDWbaRyACtAtNgKF
|
21
|
+
cl/pMlb3d5Si3vIcbKlktHR2K5KLtBuFqu/vWdlKygYzpnr3rWjAls8wr2fv6WiS
|
22
|
+
BqX3XVtZB4Fh/xriLY3Fj3Qo9RWuGf9S3BIGGxcnsr53bsO1zKXvbNr5UzP9d0+8
|
23
|
+
dF5lJ4bu8rw524nYypy39Is9PlHI7L6nxQjy82AmzloxEc31nYM7FF2pjkStv5H5
|
24
|
+
zfb4PVsCblnUstufNJWKrg32E2wbzXhzq8+E/U7Y7FM4zABWcyeHtt4Mv0MCAwEA
|
25
|
+
AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+hzRpZTx
|
26
|
+
g/xK+Tn1+5WHz7CK1y8wJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
|
27
27
|
c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1hc3RlckBqYW1lc3JvYmVydHNvbi5ldTAN
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
BgkqhkiG9w0BAQsFAAOCAYEAXg+9mfaTHPcbez7P0XnwGL0C4zdPwHtBUXioPwjP
|
29
|
+
okklRkFzMQnxArm8U9557g8cXY//vKp/cFBdCExE8lLxAOB9gHswJju0g99Yx7gY
|
30
|
+
iEV3TWv5qkLQ+n8zdTd8TxEyjWB6ZXOJcE+/cTq9Ly1j4bhf9QTdul02TBukEp6d
|
31
|
+
opP5/Yvt1GX0ED98olew/pm+KoKKNkcJzSgEH44O+pCfTi4h2STOFRvXVYaB3AH8
|
32
|
+
hpuUFcbxzPhBxOChGPAGZLaf7zurw8B2Q1vP75RV9gJ1M6NKU6Hlb6vMJQ3jz8qv
|
33
|
+
GIVFoKMCcJH2EImrG47doRVhQPIlxfz7d3f+FdYgnp7wtuFi/byklu1D2G8ZE8Ax
|
34
|
+
1s9Njv/guBMNkw+RV6IlpMtT0yeVvHeYTt0tPKeyrtBrSfsexA3393T7To6Ms+1s
|
35
|
+
B//EUqLB2VKtMmcrYMc2FfbLwllNLY4TRq+/lgVLoDb7oLHsiggYSLZS6lPBIQj/
|
36
|
+
YnYsDKwN5siDA79sB0fqq2ml
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date: 2020-08-04 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: c32
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "~>"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '0.1'
|
47
44
|
- - ">="
|
48
45
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.
|
46
|
+
version: 0.2.0
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.2'
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- - "~>"
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '0.1'
|
57
54
|
- - ">="
|
58
55
|
- !ruby/object:Gem::Version
|
59
|
-
version: 0.
|
56
|
+
version: 0.2.0
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0.2'
|
60
60
|
description:
|
61
61
|
email: james@jamesrobertson.eu
|
62
62
|
executables: []
|
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: '0'
|
85
85
|
requirements: []
|
86
|
-
rubygems_version: 3.0.
|
86
|
+
rubygems_version: 3.0.3
|
87
87
|
signing_key:
|
88
88
|
specification_version: 4
|
89
89
|
summary: A wrapper for the Linux utility xinput.
|
metadata.gz.sig
CHANGED
Binary file
|