xinput_wrapper 0.5.1 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -3
- data.tar.gz.sig +0 -0
- data/lib/xinput_wrapper.rb +247 -34
- 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: 63c289d1a4d26153d10de5a99fa22fa6ef7ca68a1c4f1173a2fc408885912031
|
4
|
+
data.tar.gz: d3cdfaccae1ecb33dd108d53cbb0ba28d64033de2c9b2f2c5d4df72c1dae524f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cc1c92283066abcd617db362b3769e384e4bce652fb937fe60a52c0d4b3f95b0435b4c5841738b1ccf959afa44a2cb81772d446ce0145e991fe537b40ac63a4
|
7
|
+
data.tar.gz: 4ef3bb300098d1f60efc6420fbe27b8769f402960a853a7fa889a8e9b084eae747bb53c122f1bbc47894b9e289568c52dd381490e27a798bf08a04f103813c19
|
checksums.yaml.gz.sig
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
3+Q�d/M��0�����07�2��~v�l�S�,��J�l��2��H��~��F$�FPAM���m���b���ցC�܁Ē�[��_��S�����H9h�;߿z�:�e��di�gZ�z_��굹�6�/�He���a} ��l:���*O�}��ZA��j�-l�����Ago��sD������.H���j6� 9��g4,����,^4ȳ�4����ۋ��
|
1
|
+
��Z��b$�y�H,���侪gk�Ҏ�N��'�]1GԔf��.Ou�5�?X:?�9�yd'"/<�MG�}ۻ�K��N)��h6�j�M7R
|
2
|
+
"�țk�O��'��-�Z�.
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/xinput_wrapper.rb
CHANGED
@@ -2,14 +2,44 @@
|
|
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
|
+
|
35
|
+
# keys - add the keys you want to be captured. If empty then
|
36
|
+
# all keys are captured.
|
37
|
+
|
38
|
+
def initialize(device: nil, verbose: true, lookup: {}, debug: false,
|
39
|
+
callback: nil, keys: [] )
|
12
40
|
|
41
|
+
@callback, @keys = callback, keys
|
42
|
+
|
13
43
|
# defaults to QWERTY keyboard layout
|
14
44
|
@modifiers = {
|
15
45
|
62 => :shift, # right control
|
@@ -74,31 +104,113 @@ class XInputWrapper
|
|
74
104
|
}.merge(@modifiers).merge(lookup)
|
75
105
|
|
76
106
|
@device, @verbose, @debug = device, verbose, debug
|
107
|
+
@mouse_pos = [0, 0]
|
77
108
|
|
78
109
|
end
|
79
110
|
|
80
111
|
def listen()
|
81
|
-
|
112
|
+
|
113
|
+
@stop = false
|
114
|
+
|
82
115
|
command = "xinput test-xi2 --root #{@device}"
|
83
116
|
|
84
117
|
type = 0
|
85
118
|
raw_keys = []
|
119
|
+
t1 = Time.now
|
120
|
+
lines = []
|
86
121
|
|
87
122
|
IO.popen(command).each_line do |x|
|
88
123
|
|
124
|
+
break if @stop
|
89
125
|
#print "GOT ", x
|
90
|
-
|
126
|
+
if x[/EVENT type \d \(Motion\)/] and (Time.now > (t1 + 0.06125)) then
|
127
|
+
|
128
|
+
type = x[/EVENT type (\d+)/,1].to_i
|
129
|
+
|
130
|
+
r = lines.join[/^\s+root: (\d+\.\d{2}\/\d+\.\d{2})/,1]
|
131
|
+
|
132
|
+
if r then
|
133
|
+
|
134
|
+
x1, y1 = r.split('/').map(&:to_f)
|
135
|
+
puts "x1: %s y1: %s" % [x1, y1] if @debug
|
136
|
+
on_mousemove(x1, y1)
|
137
|
+
@callback.on_mousemove(x1, y1) if @callback
|
138
|
+
@mouse_pos = [x1,y1]
|
139
|
+
t1 = Time.now
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
lines = [x]
|
144
|
+
|
145
|
+
elsif x[/EVENT type \d+ \(Raw(?:Key|Button)(?:Release|Press)\)/]
|
146
|
+
|
147
|
+
type = x[/EVENT type (\d+)/,1].to_i
|
91
148
|
|
92
|
-
|
93
|
-
next unless type == 13 or type == 14
|
149
|
+
lines = [x]
|
94
150
|
|
95
|
-
|
96
|
-
|
151
|
+
|
152
|
+
elsif [MOTION, RAWKEY_PRESS, RAWKEY_RELEASE, RAWBUTTON_PRESS,
|
153
|
+
RAWBUTTON_RELEASE].include? type
|
154
|
+
|
155
|
+
lines << x
|
156
|
+
|
157
|
+
if x == "\n" then
|
158
|
+
case lines.first[/(?<=EVENT type )\d+/].to_i
|
159
|
+
when RAWKEY_PRESS
|
160
|
+
|
161
|
+
r = lines.join[/detail: (\d+)/,1]
|
162
|
+
|
163
|
+
keycode = r.to_i if r
|
164
|
+
|
165
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
166
|
+
|
167
|
+
when RAWKEY_RELEASE
|
168
|
+
|
169
|
+
r = lines.join[/detail: (\d+)/,1]
|
170
|
+
|
171
|
+
keycode = r.to_i if r
|
172
|
+
|
173
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
174
|
+
|
175
|
+
|
176
|
+
when RAWBUTTON_PRESS
|
177
|
+
|
178
|
+
r = lines.join[/detail: (\d+)/,1]
|
179
|
+
|
180
|
+
buttoncode = r.to_i if r
|
181
|
+
|
182
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
183
|
+
|
184
|
+
when RAWBUTTON_RELEASE
|
185
|
+
|
186
|
+
r = lines.join[/detail: (\d+)/,1]
|
187
|
+
|
188
|
+
buttoncode = r.to_i if r
|
189
|
+
|
190
|
+
type = lines.join[/EVENT type (\d+)/,1] .to_i
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
else
|
196
|
+
next
|
197
|
+
end
|
198
|
+
|
199
|
+
else
|
200
|
+
next
|
201
|
+
end
|
202
|
+
|
203
|
+
next unless keycode or buttoncode
|
204
|
+
puts 'keycode: ' + keycode.inspect if @debug
|
205
|
+
puts 'buttoncode: ' + buttoncode.inspect if @debug
|
97
206
|
|
98
207
|
# type = 13 means a key has been pressed
|
99
|
-
if type ==
|
208
|
+
if type == RAWKEY_PRESS then
|
209
|
+
|
210
|
+
anykey_press()
|
100
211
|
|
101
|
-
if @modifiers.include? raw_keys.last or
|
212
|
+
if @modifiers.include? raw_keys.last or \
|
213
|
+
@modifiers.include? keycode then
|
102
214
|
raw_keys << keycode
|
103
215
|
end
|
104
216
|
|
@@ -120,10 +232,29 @@ class XInputWrapper
|
|
120
232
|
|
121
233
|
puts key.to_s + ' key presssed' if @verbose
|
122
234
|
name = "on_#{key}_key".to_sym
|
123
|
-
|
235
|
+
puts 'name: ' + name.inspect if @debug
|
236
|
+
|
237
|
+
if private_methods.include? name and (@keys.empty? or \
|
238
|
+
@keys.include? key.to_sym) then
|
239
|
+
puts 'before method' if @debug
|
240
|
+
method(name).call
|
241
|
+
end
|
124
242
|
|
125
243
|
keystring = ((key.length > 1 or key == ' ') ? "{%s}" % key : key)
|
126
|
-
|
244
|
+
|
245
|
+
if block_given? then
|
246
|
+
|
247
|
+
yield(keystring)
|
248
|
+
|
249
|
+
else
|
250
|
+
|
251
|
+
if @keys.empty? or @keys.include? key.to_sym then
|
252
|
+
on_key_press(keystring, keycode)
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
@callback.on_keypress(keystring, keycode) if @callback
|
127
258
|
|
128
259
|
end
|
129
260
|
|
@@ -135,8 +266,13 @@ class XInputWrapper
|
|
135
266
|
if block_given? then
|
136
267
|
yield(format_key(keys.last, keys[0..-2]))
|
137
268
|
else
|
138
|
-
|
269
|
+
|
270
|
+
if @keys.empty? or (!@keys.empty? and \
|
271
|
+
@keys.include? keys.last) then
|
272
|
+
on_key_press(keys.last, keycode, keys[0..-2])
|
273
|
+
end
|
139
274
|
end
|
275
|
+
@callback.on_keypress(keys.last, keycode, keys[0..-2]) if @callback
|
140
276
|
|
141
277
|
raw_keys = []
|
142
278
|
|
@@ -145,7 +281,7 @@ class XInputWrapper
|
|
145
281
|
|
146
282
|
|
147
283
|
# a key has been released
|
148
|
-
elsif type ==
|
284
|
+
elsif type == RAWKEY_RELEASE
|
149
285
|
|
150
286
|
# here we are only looking to detect a
|
151
287
|
# single modifier key press and release
|
@@ -160,51 +296,127 @@ class XInputWrapper
|
|
160
296
|
yield(format_key(key.to_s))
|
161
297
|
|
162
298
|
else
|
163
|
-
name = "on_#{key}_key".to_sym
|
164
|
-
method
|
299
|
+
name = "on_#{key.to_s}_key".to_sym
|
300
|
+
puts 'calling method' if @debug
|
301
|
+
|
302
|
+
if private_methods.include? name and (@keys.empty? or \
|
303
|
+
@keys.include? key.to_sym) then
|
304
|
+
method(name).call #if self.methods.include? name
|
305
|
+
end
|
306
|
+
|
165
307
|
on_key_press(key, keycode)
|
308
|
+
@callback.on_keypress(key, keycode) if @callback
|
166
309
|
end
|
167
310
|
end
|
168
311
|
|
169
312
|
index = raw_keys.rindex(keycode)
|
170
313
|
raw_keys.delete_at index if index
|
171
|
-
|
314
|
+
|
315
|
+
elsif type == RAWBUTTON_PRESS
|
316
|
+
|
317
|
+
button = BUTTONS[buttoncode-1]
|
318
|
+
|
319
|
+
case button
|
320
|
+
when :scrollup
|
321
|
+
on_mouse_scrollup()
|
322
|
+
@callback.on_mouse_scrollup() if @callback
|
323
|
+
when :scrolldown
|
324
|
+
on_mouse_scrolldown()
|
325
|
+
@callback.on_mouse_scrolldown() if @callback
|
326
|
+
else
|
327
|
+
on_mousedown(button, *@mouse_pos)
|
328
|
+
@callback.on_mousedown(button, *@mouse_pos) if @callback
|
329
|
+
end
|
330
|
+
|
331
|
+
elsif type == RAWBUTTON_RELEASE
|
332
|
+
|
333
|
+
button = BUTTONS[buttoncode-1]
|
334
|
+
on_mouseup(BUTTONS[buttoncode-1], *@mouse_pos)
|
335
|
+
|
172
336
|
end
|
173
337
|
|
174
338
|
end
|
175
339
|
end
|
176
340
|
|
177
|
-
|
341
|
+
private
|
342
|
+
|
343
|
+
def anykey_press()
|
344
|
+
# do nothing; used by xinput_wrapperplus
|
345
|
+
puts 'anykey pressed' if @debug
|
346
|
+
end
|
347
|
+
|
348
|
+
def message(s)
|
349
|
+
puts 'msg: ' + s
|
350
|
+
end
|
178
351
|
|
179
|
-
def
|
180
|
-
|
352
|
+
def on_ctrl_key()
|
353
|
+
message 'ctrl key pressed'
|
181
354
|
end
|
182
355
|
|
183
|
-
def on_key_press(key, keycode, modifier)
|
356
|
+
def on_key_press(key, keycode, modifier=nil)
|
184
357
|
|
185
358
|
if @debug then
|
186
359
|
puts ('key: ' + key.inspect).debug
|
187
360
|
end
|
188
361
|
|
189
362
|
end
|
363
|
+
|
364
|
+
def on_mousedown(button, x,y)
|
365
|
+
|
366
|
+
if @debug then
|
367
|
+
puts "on_mousedown() %s click x: %s y: %s" % [button, x, y]
|
368
|
+
end
|
369
|
+
|
370
|
+
end
|
371
|
+
|
372
|
+
def on_mousemove(x,y)
|
373
|
+
|
374
|
+
if @debug then
|
375
|
+
puts "on_mousemove() x: %s y: %s" % [x, y]
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
def on_mouseup(button, x,y)
|
381
|
+
|
382
|
+
if @debug then
|
383
|
+
puts "on_mousedown() %s click x: %s y: %s" % [button, x, y]
|
384
|
+
end
|
385
|
+
|
386
|
+
end
|
387
|
+
|
388
|
+
def on_mouse_scrolldown()
|
389
|
+
|
390
|
+
if @debug then
|
391
|
+
puts "on_mouse_scrolldown()"
|
392
|
+
end
|
393
|
+
|
394
|
+
end
|
395
|
+
|
396
|
+
def on_mouse_scrollup()
|
397
|
+
|
398
|
+
if @debug then
|
399
|
+
puts "on_mouse_scrollup()"
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
190
404
|
|
191
405
|
def on_shift_key() end
|
192
406
|
def on_super_key() end
|
193
407
|
|
194
|
-
def on_f1_key()
|
195
|
-
def on_f2_key()
|
196
|
-
def on_f3_key()
|
197
|
-
def on_f4_key()
|
198
|
-
def on_f5_key()
|
199
|
-
def on_f6_key()
|
200
|
-
def on_f7_key()
|
201
|
-
def on_f8_key()
|
202
|
-
def on_f9_key()
|
203
|
-
def on_f10_key()
|
204
|
-
def on_f11_key()
|
205
|
-
def on_f12_key()
|
206
|
-
|
207
|
-
private
|
408
|
+
def on_f1_key() message 'f1' end
|
409
|
+
def on_f2_key() message 'f2' end
|
410
|
+
def on_f3_key() message 'f3' end
|
411
|
+
def on_f4_key() message 'f4' end
|
412
|
+
def on_f5_key() message 'f5' end
|
413
|
+
def on_f6_key() message 'f6' end
|
414
|
+
def on_f7_key() message 'f7' end
|
415
|
+
def on_f8_key() message 'f8' end
|
416
|
+
def on_f9_key() message 'f9' end
|
417
|
+
def on_f10_key() message 'f10' end
|
418
|
+
def on_f11_key() message 'f11' end
|
419
|
+
def on_f12_key() message 'f12' end
|
208
420
|
|
209
421
|
def format_key(key, modifier=[])
|
210
422
|
|
@@ -213,6 +425,7 @@ class XInputWrapper
|
|
213
425
|
|
214
426
|
end
|
215
427
|
|
428
|
+
def on_alt_key() message 'alt' end
|
216
429
|
def on_leftcontrol_key() on_control_key() end
|
217
430
|
def on_rightcontrol_key() on_control_key() end
|
218
431
|
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.8.1
|
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-27 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
|