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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f4e856f73b9e7dd55af1a5b49118539aa67816d22efedb6e0a413628d7eef55
4
- data.tar.gz: d38a486aca20bfe0a41f20236f0ec998d7216c4dc78c00fda115f03a85247029
3
+ metadata.gz: 63c289d1a4d26153d10de5a99fa22fa6ef7ca68a1c4f1173a2fc408885912031
4
+ data.tar.gz: d3cdfaccae1ecb33dd108d53cbb0ba28d64033de2c9b2f2c5d4df72c1dae524f
5
5
  SHA512:
6
- metadata.gz: 4df624c748de48612aebc920ad2e9788159570ba294f70113dfe6fcc528db7716cdbafa11230e4e087bde2e4cee1d71e68ae426f48c1b486c1ba7cf491e03742
7
- data.tar.gz: 5edec0ee6f3df041053db4a1289ea032b8094da8541b997c1758dcb81cc14d1973521c7f2d1c67b77e8ee72ed6927b96f5c740932cf7d6cedec499ba23c7b791
6
+ metadata.gz: 7cc1c92283066abcd617db362b3769e384e4bce652fb937fe60a52c0d4b3f95b0435b4c5841738b1ccf959afa44a2cb81772d446ce0145e991fe537b40ac63a4
7
+ data.tar.gz: 4ef3bb300098d1f60efc6420fbe27b8769f402960a853a7fa889a8e9b084eae747bb53c122f1bbc47894b9e289568c52dd381490e27a798bf08a04f103813c19
@@ -1,3 +1,2 @@
1
- I��A&e���|���8yf�i3Ȏ@�X5�� �4I%#��n��ŋmA�Z�a��?��i�[RK˄�N�h�`.�F?i�����I��i��>]�X�_
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$�yH,���侪gk�Ҏ�N��'�]1GԔf��.Ou5�?X:?�9yd'"/<�MG}ۻ�K��N)��h6�j�M7R
2
+ "�țk�O��'��-�Z�.
data.tar.gz.sig CHANGED
Binary file
@@ -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
- def initialize(device: '3', verbose: true, lookup: {}, debug: false )
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
- raw_type = x[/EVENT type (\d+)/,1]
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
- type = raw_type.to_i unless raw_type.nil?
93
- next unless type == 13 or type == 14
149
+ lines = [x]
94
150
 
95
- keycode = x[/detail: (\d+)/,1].to_i
96
- next if keycode == 0
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 == 13 then
208
+ if type == RAWKEY_PRESS then
209
+
210
+ anykey_press()
100
211
 
101
- if @modifiers.include? raw_keys.last or @modifiers.include? keycode then
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
- method(name).call if self.protected_methods.include? name
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
- block_given? ? yield(keystring) : on_key_press(keystring, keycode)
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
- on_key_press(keys.last, keycode, keys[0..-2])
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 == 14
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(name).call if self.protected_methods.include? name
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
- protected
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 on_control_key()
180
- puts 'ctrl key pressed'
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() end
195
- def on_f2_key() end
196
- def on_f3_key() end
197
- def on_f4_key() end
198
- def on_f5_key() end
199
- def on_f6_key() end
200
- def on_f7_key() end
201
- def on_f8_key() end
202
- def on_f9_key() end
203
- def on_f10_key() end
204
- def on_f11_key() end
205
- def on_f12_key() end
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.5.1
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
- YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMTkwMjEwMTU1NTM1WhcN
15
- MjAwMjEwMTU1NTM1WjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
16
- cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQD2pELS
17
- hfHN+He5s77qpnUO4j6GDr1B9PDIKqJDBz+kJCUGXsLzyHnKK8iIblXtETyIJn9F
18
- euzS6ohPh64xfBcKrnF7bSUAXsdC/PZIsNgvSp4Vuguxpe6wDHfaqBhV2KcOjGrP
19
- tnZRvJJHWBczBzMw+BAj0d5Zp5QZaVXDx3mN13t2j6tUncwLF3NYIlaFA7lN4uuV
20
- hiFyqlkk+ELO8eptDF5Wkel5ZjtALo9jOq04KAlImZ7cnFLD1zbAXWiKPyEvSAeL
21
- fGONgtYGEBwIKKeisGTucndYa1iwQOnFLjCixclGH+6+YInlbHUzl/JrFHSEXIYb
22
- 0jU2pHEu+xQlB2xdKiJF6Z/JWWabJ+hyMifxnyPYLW53QGV5fu2uAHDVUCplwhBW
23
- hOBeqmV8SCjX7aYytN7TiqO4Th2kP2tPLQqynFQ3ceNiTcjk1fkliXlv+lc8IFiS
24
- 25oy9Th0M3O7+rs11i1eeaAlvrZ0TWv5qFpJUrMB53UpndLxeroiPw/AzocCAwEA
25
- AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUQLWJJ/fU
26
- p6suCssS39/w2O9MQhUwJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
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
- BgkqhkiG9w0BAQsFAAOCAYEAAuFxNNh+nIt4Ba3bWUilYAVhEYROr32uTWFmyL8w
29
- T4bMAe8OC9PzuIAg3C4jzks008Fbfi7Hcm4Pqc548kbavWtLquzdNwNqasywcweb
30
- FIIGeYpRy2BmHeP8+RK66T+HfdAGGmy60L/q5kTJtV1g9wDTg5glxv7OvlShgKTM
31
- ZgaJi9JerKv6dsB6r1OnnVy73BfQ0eiN2/vwDHCB9Op2E5JKFqUlklGaKvbEsMoV
32
- Ou4ilgqq7OROhrul809YLlc0VHRfAiaOqeO5l1Ccfq9Q2LUZwGhtw+EIKSrgWQZA
33
- 1aSaQX/s+LpAVRGJlWrVa+uQ21aUdItSdkKaRNK4MxQHPu8s/9sgeZRMEO5wJc7i
34
- bvgBqmvgsZwFmSRWE1K/PusL86uaYCw5pTWA+BquQ7taMwhGKqdDlHLp+SQ1Wd82
35
- rryowfoo6nLmegcIZjm+zz/gkT/0udwMMVm2gwo0bIRQuQOLmd7IUNzYQKZQOGMA
36
- g4ETbI8IEC3VCaoECdunsS3t
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: 2019-04-08 00:00:00.000000000 Z
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.1.2
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.1.2
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.1
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