xinput_wrapper 0.5.1 → 0.8.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: 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