vigilem-evdev 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/ext/Rakefile +31 -0
- data/ext/rake_helper.rb +10 -0
- data/lib/vigilem/_evdev.rb +24 -0
- data/lib/vigilem/evdev.rb +14 -0
- data/lib/vigilem/evdev/at_exit.rb +8 -0
- data/lib/vigilem/evdev/context_filter.rb +92 -0
- data/lib/vigilem/evdev/demultiplexer.rb +26 -0
- data/lib/vigilem/evdev/device.rb +182 -0
- data/lib/vigilem/evdev/device_capabilities.rb +53 -0
- data/lib/vigilem/evdev/dom.rb +8 -0
- data/lib/vigilem/evdev/dom/adapter.rb +87 -0
- data/lib/vigilem/evdev/dom/code_values_tables.rb +172 -0
- data/lib/vigilem/evdev/dom/input_event_converter.rb +329 -0
- data/lib/vigilem/evdev/dom/input_event_utils.rb +48 -0
- data/lib/vigilem/evdev/dom/key_values_tables.rb +248 -0
- data/lib/vigilem/evdev/dom/kp_table.rb +52 -0
- data/lib/vigilem/evdev/focus_context_filter.rb +124 -0
- data/lib/vigilem/evdev/input_system_handler.rb +69 -0
- data/lib/vigilem/evdev/key_map_cache.rb +64 -0
- data/lib/vigilem/evdev/multiplexer.rb +73 -0
- data/lib/vigilem/evdev/system.rb +17 -0
- data/lib/vigilem/evdev/system/input.rb +1053 -0
- data/lib/vigilem/evdev/system/input/event.rb +4 -0
- data/lib/vigilem/evdev/system/input/input_event.rb +33 -0
- data/lib/vigilem/evdev/system/int.rb +9 -0
- data/lib/vigilem/evdev/system/ioctl.rb +143 -0
- data/lib/vigilem/evdev/system/keymap_loaders.rb +89 -0
- data/lib/vigilem/evdev/system/keymap_loaders/dumpkeys_loader.rb +98 -0
- data/lib/vigilem/evdev/system/keymap_loaders/kmap_loader.rb +74 -0
- data/lib/vigilem/evdev/system/posix_types.rb +5 -0
- data/lib/vigilem/evdev/system/time.rb +21 -0
- data/lib/vigilem/evdev/transfer_agent.rb +40 -0
- data/lib/vigilem/evdev/version.rb +5 -0
- data/lib/vigilem/evdev/vty_context_filter.rb +216 -0
- data/spec/after_each_example_group.rb +29 -0
- data/spec/delete_test_cache_after_group.rb +26 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/vigilem/_evdev_spec.rb +11 -0
- data/spec/vigilem/evdev/context_filter_spec.rb +114 -0
- data/spec/vigilem/evdev/demultiplexer_spec.rb +44 -0
- data/spec/vigilem/evdev/device_capabilities_spec.rb +0 -0
- data/spec/vigilem/evdev/device_spec.rb +97 -0
- data/spec/vigilem/evdev/dom/adapter_spec.rb +5 -0
- data/spec/vigilem/evdev/dom/input_event_converter_spec.rb +253 -0
- data/spec/vigilem/evdev/dom/input_event_utils_spec.rb +23 -0
- data/spec/vigilem/evdev/focus_context_filter_spec.rb +112 -0
- data/spec/vigilem/evdev/input_system_handler_spec.rb +146 -0
- data/spec/vigilem/evdev/key_map_cache_spec.rb +65 -0
- data/spec/vigilem/evdev/multiplexer_spec.rb +55 -0
- data/spec/vigilem/evdev/system/input/input_event_spec.rb +33 -0
- data/spec/vigilem/evdev/system/input_spec.rb +274 -0
- data/spec/vigilem/evdev/system/int_spec.rb +30 -0
- data/spec/vigilem/evdev/system/ioctl_spec.rb +206 -0
- data/spec/vigilem/evdev/system/keymap_loaders/dumpkeys_loader_spec.rb +5 -0
- data/spec/vigilem/evdev/system/keymap_loaders/kmap_loader_spec.rb +24 -0
- data/spec/vigilem/evdev/system/keymap_loaders_spec.rb +22 -0
- data/spec/vigilem/evdev/system/posix_types_spec.rb +15 -0
- data/spec/vigilem/evdev/system/time_spec.rb +18 -0
- data/spec/vigilem/evdev/transfer_agent_spec.rb +57 -0
- data/spec/vigilem/evdev/vty_context_filter_spec.rb +282 -0
- metadata +286 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
module Vigilem
|
2
|
+
module Evdev
|
3
|
+
module DOM
|
4
|
+
#
|
5
|
+
module InputEventUtils
|
6
|
+
|
7
|
+
include Vigilem::DOM::Utils
|
8
|
+
|
9
|
+
# takes a InputEvent#code and returns a String
|
10
|
+
# representing the keycode value
|
11
|
+
# @param [Integer] event_code, the number to convert
|
12
|
+
# @return [String] i.e. "keycode30"
|
13
|
+
def event_code_to_keycode_str(event_code)
|
14
|
+
"keycode#{event_code}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# takes a keycode_name and returns a common location string
|
18
|
+
# if available
|
19
|
+
# @param [String || Symbol] keycode_name, i.e. KEY_RIGTHCTRL
|
20
|
+
# @return [String || NilClass] a common locaiton string i.e. 'Right'
|
21
|
+
def location_str_from_keycode_name(keycode_name)
|
22
|
+
if loc = keycode_name.to_s.gsub('KP', 'NUMPAD').scan(/LEFT|RIGHT|NUMPAD/i).first
|
23
|
+
loc.downcase.tap {|obj| obj[0] = obj[0].upcase }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# takes a keycode name and returns the keymap modifier name
|
28
|
+
# @todo meta
|
29
|
+
# @param [String ||Symbol] keycode_name, i.e. KEY_RIGHTCTRL
|
30
|
+
# @return [String] keymap_name of the modifier
|
31
|
+
def modifier_keymap_name(keycode_name)
|
32
|
+
if (keycode_name) =~ /caps|shift|alt|c(on)?tro?l/i
|
33
|
+
if keycode_name == :KEY_CAPSLOCK
|
34
|
+
'capsshift'
|
35
|
+
else
|
36
|
+
keycode_name.to_s.gsub(/KEY_/, '').split(/ight|eft/i).reverse.join.downcase
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
extend self
|
42
|
+
|
43
|
+
extend Support::Utils
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require 'vigilem/support/key_map'
|
2
|
+
|
3
|
+
require 'vigilem/evdev/system'
|
4
|
+
|
5
|
+
module Vigilem
|
6
|
+
module Evdev::DOM
|
7
|
+
module KeyValuesTables
|
8
|
+
|
9
|
+
include Evdev::System::Input::KeysAndButtons
|
10
|
+
|
11
|
+
SpecialKeyValues = Support::KeyMap.new({'Unidentified' => nil })
|
12
|
+
ModifierKeys = Support::KeyMap.new.fuse!({
|
13
|
+
:'?' => 'Accel',
|
14
|
+
KEY_LEFTALT => 'Alt',
|
15
|
+
KEY_RIGHTALT => 'Alt'}, {
|
16
|
+
:'?' => 'AltGraph',
|
17
|
+
KEY_CAPSLOCK => 'CapsLock',
|
18
|
+
'CtrlL_Lock' => 'CapsLock',
|
19
|
+
KEY_LEFTCTRL => 'Control',
|
20
|
+
KEY_RIGHTCTRL => 'Control',
|
21
|
+
'Control' => 'Control'}, {
|
22
|
+
:'?' => ['Fn', 'FnLock', 'Hyper'],
|
23
|
+
KEY_LEFTMETA => 'Meta',
|
24
|
+
KEY_RIGHTMETA => 'Meta',
|
25
|
+
KEY_NUMLOCK => 'NumLock',
|
26
|
+
KEY_LEFTMETA => 'OS',
|
27
|
+
KEY_SCROLLLOCK => 'ScrollLock',
|
28
|
+
KEY_LEFTSHIFT => 'Shift',
|
29
|
+
KEY_RIGHTSHIFT => 'Shift'}, {
|
30
|
+
:'?' => ['Super', 'Symbol', 'SymbolLock']
|
31
|
+
})
|
32
|
+
|
33
|
+
WhitespaceKeys = Support::KeyMap.new({
|
34
|
+
KEY_ENTER => 'Enter',
|
35
|
+
'KP_Enter' => 'Enter',
|
36
|
+
:'?' => 'Separator',
|
37
|
+
'Tab' => 'Tab',
|
38
|
+
KEY_TAB => 'Tab'
|
39
|
+
})
|
40
|
+
# Space
|
41
|
+
|
42
|
+
NavigationKeys = Support::KeyMap.new({
|
43
|
+
KEY_DOWN => 'ArrowDown',
|
44
|
+
'Down' => 'ArrowDown',
|
45
|
+
'KP_2' => 'ArrowDown',
|
46
|
+
KEY_LEFT => 'ArrowLeft',
|
47
|
+
'Left' => 'ArrowLeft',
|
48
|
+
'KP_4' => 'ArrowLeft',
|
49
|
+
KEY_RIGHT => 'ArrowRight',
|
50
|
+
'Right' => 'ArrowRight',
|
51
|
+
'KP_6' => 'ArrowRight',
|
52
|
+
KEY_UP => 'ArrowUp',
|
53
|
+
'Up' => 'ArrowUp',
|
54
|
+
'KP_8' => 'ArrowUp',
|
55
|
+
KEY_END => 'End',
|
56
|
+
'KP_1' => 'End',
|
57
|
+
KEY_HOME => 'Home',
|
58
|
+
'KP_7' => 'Home',
|
59
|
+
KEY_PAGEDOWN => 'PageDown',
|
60
|
+
'KP_3' => 'PageDown',
|
61
|
+
KEY_PAGEUP => 'PageUp',
|
62
|
+
'KP_9' => 'PageUp'
|
63
|
+
})
|
64
|
+
|
65
|
+
EditingKeys = Support::KeyMap.new.fuse!({
|
66
|
+
KEY_BACKSPACE => 'Backspace',
|
67
|
+
KEY_CLEAR => 'Clear',
|
68
|
+
KEY_COPY => 'Copy',
|
69
|
+
:'?' => 'CrSel',
|
70
|
+
KEY_CUT => 'Cut',
|
71
|
+
KEY_DELETE => 'Delete'}, {
|
72
|
+
:'?' => ['EraseEof', 'ExSel'],
|
73
|
+
KEY_INSERT => 'Insert',
|
74
|
+
KEY_PASTE => 'Paste',
|
75
|
+
KEY_REDO => 'Redo',
|
76
|
+
KEY_UNDO => 'Undo'
|
77
|
+
})
|
78
|
+
UIKeys = Support::KeyMap.new.fuse!({
|
79
|
+
:'?' => 'Accept',
|
80
|
+
KEY_AGAIN => 'Again'}, {
|
81
|
+
:'?' => 'Attn',
|
82
|
+
KEY_CANCEL => 'Cancel',
|
83
|
+
KEY_COMPOSE => 'ContextMenu',
|
84
|
+
KEY_ESC => 'Escape'}, {
|
85
|
+
:'?' => 'Execute',
|
86
|
+
KEY_FIND => 'Find',
|
87
|
+
KEY_HELP => 'Help',
|
88
|
+
KEY_PAUSE => 'Pause',
|
89
|
+
KEY_PLAY => 'Play',
|
90
|
+
KEY_PROPS => 'Props',
|
91
|
+
KEY_SELECT => 'Select',
|
92
|
+
KEY_ZOOMIN => 'ZoomIn',
|
93
|
+
KEY_ZOOMOUT => 'ZoomOut'
|
94
|
+
})
|
95
|
+
|
96
|
+
DeviceKeys = Support::KeyMap.new.fuse!({
|
97
|
+
:'?' => ['BrightnessDown', 'BrightnessUp'],
|
98
|
+
KEY_CAMERA => 'Camera',
|
99
|
+
KEY_EJECTCD => 'Eject',
|
100
|
+
KEY_EJECTCLOSECD => 'Eject'}, {
|
101
|
+
:'?' => ['LogOff', 'Power', 'PowerOff'],
|
102
|
+
KEY_PRINT => 'PrintScreen'}, {
|
103
|
+
:'?' => ['Hibernate', 'Standby', 'WakeUp']
|
104
|
+
})
|
105
|
+
IMEandCompositionKeys = Support::KeyMap.new.fuse!({
|
106
|
+
:'?' => ['AllCandidates', 'Alphanumeric',
|
107
|
+
'CodeInput'],
|
108
|
+
KEY_COMPOSE => 'Compose'}, {
|
109
|
+
:'?' => ['Convert', 'Dead', 'FinalMode',
|
110
|
+
'GroupFirst', 'GroupLast'],
|
111
|
+
KEY_KBDINPUTASSIST_NEXTGROUP => 'GroupNext',
|
112
|
+
KEY_KBDINPUTASSIST_PREVGROUP => 'GroupPrevious',
|
113
|
+
KEY_MODE => 'ModeChange'}, {
|
114
|
+
:'?' => ['NextCandidate', 'NonConvert',
|
115
|
+
'PreviousCandidate', 'Process',
|
116
|
+
'SingleCandidate']
|
117
|
+
})
|
118
|
+
KeysspecifictoKoreankeyboards = Support::KeyMap.new.fuse!({
|
119
|
+
KEY_HANGEUL => 'HangulMode',
|
120
|
+
KEY_HANJA => 'HanjaMode',
|
121
|
+
:'?' => 'JunjaMode'
|
122
|
+
})
|
123
|
+
KeysspecifictoJapanesekeyboards = Support::KeyMap.new.fuse!({
|
124
|
+
:'?' => ['Eisu', 'Hankaku'],
|
125
|
+
KEY_HIRAGANA => 'Hiragana',
|
126
|
+
KEY_KATAKANAHIRAGANA => 'HiraganaKatakana'}, {
|
127
|
+
:'?' => ['KanaMode', 'KanjiMode'],
|
128
|
+
KEY_KATAKANA => 'Katakana'}, {
|
129
|
+
:'?' => ['Romaji', 'Zenkaku'],
|
130
|
+
KEY_ZENKAKUHANKAKU => 'ZenkakuHankaku'
|
131
|
+
})
|
132
|
+
General_PurposeFunctionKeys = Support::KeyMap.new({
|
133
|
+
KEY_F1 => 'F1',
|
134
|
+
KEY_F2 => 'F2',
|
135
|
+
KEY_F3 => 'F3',
|
136
|
+
KEY_F4 => 'F4',
|
137
|
+
KEY_F5 => 'F5',
|
138
|
+
KEY_F6 => 'F6',
|
139
|
+
KEY_F7 => 'F7',
|
140
|
+
KEY_F8 => 'F8',
|
141
|
+
KEY_F9 => 'F9',
|
142
|
+
KEY_F10 => 'F10',
|
143
|
+
KEY_F11 => 'F11',
|
144
|
+
KEY_F12 => 'F12',
|
145
|
+
:'?' => ['Soft1', 'Soft2', 'Soft3', 'Soft4']
|
146
|
+
})
|
147
|
+
|
148
|
+
MultimediaKeys = Support::KeyMap.new.fuse!({
|
149
|
+
KEY_CLOSECD => 'Close',
|
150
|
+
KEY_EJECTCLOSECD => 'Close',
|
151
|
+
KEY_FORWARDMAIL => 'MailForward',
|
152
|
+
KEY_REPLY => 'MailReply',
|
153
|
+
:'?' => 'MailSend'}, {
|
154
|
+
KEY_PLAYPAUSE => 'MediaPlayPause',
|
155
|
+
:'?' => 'MediaSelect', #too many option need to test
|
156
|
+
KEY_STOPCD => 'MediaStop',
|
157
|
+
KEY_NEXTSONG => 'MediaTrackNext',
|
158
|
+
KEY_PREVIOUSSONG => 'MediaTrackPrevious',
|
159
|
+
KEY_NEW => 'New',
|
160
|
+
KEY_OPEN => 'Open',
|
161
|
+
KEY_PRINT => 'Print',
|
162
|
+
KEY_SAVE => 'Save',
|
163
|
+
KEY_SPELLCHECK => 'SpellCheck',
|
164
|
+
KEY_VOLUMEDOWN => 'VolumeDown',
|
165
|
+
KEY_VOLUMEUP => 'VolumeUp',
|
166
|
+
KEY_MUTE => 'VolumeMute'
|
167
|
+
})
|
168
|
+
|
169
|
+
ApplicationKeys = Support::KeyMap.new({
|
170
|
+
KEY_CALC => 'LaunchCalculator',
|
171
|
+
KEY_CALENDAR => 'LaunchCalendar',
|
172
|
+
KEY_MAIL => 'LaunchMail',
|
173
|
+
KEY_PLAYER => ['LaunchMediaPlayer', 'LaunchMusicPlayer'],
|
174
|
+
KEY_PC => 'LaunchMyComputer',
|
175
|
+
KEY_COFFEE => 'LaunchScreenSaver',
|
176
|
+
KEY_SPREADSHEET => 'LaunchSpreadsheet',
|
177
|
+
KEY_WWW => 'LaunchWebBrowser',
|
178
|
+
:'?' => 'LaunchWebCam', #how's this differ from KEY_CAMERA?
|
179
|
+
KEY_WORDPROCESSOR => 'LaunchWordProcessor'
|
180
|
+
})
|
181
|
+
|
182
|
+
BrowserKeys = Support::KeyMap.new({
|
183
|
+
:'?' => ['BrowserBack','BrowserFavorites', 'BrowserForward',
|
184
|
+
'BrowserHome', 'BrowserRefresh', 'BrowserSearch',
|
185
|
+
'BrowserStop']
|
186
|
+
})
|
187
|
+
|
188
|
+
MediaControllerKeys = Support::KeyMap.new().fuse!({
|
189
|
+
:'?' => ['AudioBalanceLeft', 'AudioBalanceRight']}, {
|
190
|
+
KEY_BASSBOOST => ['AudioBassBoostDown', 'AudioBassBoostUp'],
|
191
|
+
:'?' => ['AudioFaderFront', 'AudioFaderRear',
|
192
|
+
'AudioSurroundModeNext', 'AVRInput', 'AVRPower'],
|
193
|
+
KEY_CHANNELDOWN => 'ChannelDown',
|
194
|
+
KEY_CHANNELUP => 'ChannelUp',
|
195
|
+
KEY_RED => 'ColorF0Red',
|
196
|
+
KEY_GREEN => 'ColorF1Green',
|
197
|
+
KEY_YELLOW => 'ColorF2Yellow',
|
198
|
+
KEY_BLUE => 'ColorF3Blue'}, {
|
199
|
+
:'?' => ['ColorF4Grey', 'ColorF5Brown', 'ClosedCaptionToggle',
|
200
|
+
'Dimmer', 'DisplaySwap', 'Exit',
|
201
|
+
'FavoriteClear0', 'FavoriteClear1',
|
202
|
+
'FavoriteClear2', 'FavoriteClear3',
|
203
|
+
'FavoriteRecall0', 'FavoriteRecall1',
|
204
|
+
'FavoriteRecall2', 'FavoriteRecall3',
|
205
|
+
'FavoriteStore0', 'FavoriteStore1',
|
206
|
+
'FavoriteStore2', 'FavoriteStore3',
|
207
|
+
'Guide', 'GuideNextDay', 'GuidePreviousDay',
|
208
|
+
'Info', 'InstantReplay', 'Link',
|
209
|
+
'ListProgram', 'LiveContent', 'Lock',
|
210
|
+
'MediaApps', 'MediaFastForward', 'MediaLast',
|
211
|
+
'pMediaPause', 'MediaPlay', 'MediaRecord'],
|
212
|
+
KEY_REWIND => 'MediaRewind'}, {
|
213
|
+
:'?' => ['MediaSkip', 'NextFavoriteChannel',
|
214
|
+
'NextUserProfile', 'OnDemand', 'PinPDown',
|
215
|
+
'PinPMove', 'PinPToggle', 'PinPUp',
|
216
|
+
'PlaySpeedDown', 'PlaySpeedReset',
|
217
|
+
'PlaySpeedUp', 'RandomToggle', 'RcLowBattery',
|
218
|
+
'RecordSpeedNext', 'RfBypass',
|
219
|
+
'ScanChannelsToggle', 'ScreenModeNext',
|
220
|
+
'Settings', 'SplitScreenToggle', 'STBInput',
|
221
|
+
'STBPower', 'Subtitle', 'Teletext', 'TV',
|
222
|
+
'TVInput', 'TVPower', 'VideoModeNext',
|
223
|
+
'Wink', 'ZoomToggle', 'BrowserBack',
|
224
|
+
'BrowserForward', 'ContextMenu', 'Eject',
|
225
|
+
'End', 'Enter', 'Home', 'MediaPlayPause',
|
226
|
+
'MediaStop', 'MediaNextTrack', 'MediaPreviousTrack',
|
227
|
+
'Power', 'VolumeDown', 'VolumeUp', 'VolumeMute']
|
228
|
+
})
|
229
|
+
end
|
230
|
+
|
231
|
+
KeyTable = KeyValuesTables.constants.each_with_object(Support::KeyMap.new) do |table_name, memo|
|
232
|
+
if (key_map = KeyValuesTables.const_get(table_name)).is_a? Hash
|
233
|
+
key_map.right_side_alias(:dom_code)
|
234
|
+
key_map.right_side_alias(:dom_codes)
|
235
|
+
key_map.left_side_alias(:keycode)
|
236
|
+
key_map.left_side_alias(:keycodes)
|
237
|
+
key_map.left_side_alias(:keysym)
|
238
|
+
key_map.left_side_alias(:keysyms)
|
239
|
+
memo.merge! key_map
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
KeyTable.right_side_alias(:dom_code)
|
244
|
+
KeyTable.right_side_alias(:dom_codes)
|
245
|
+
KeyTable.left_side_alias(:keycode)
|
246
|
+
KeyTable.left_side_alias(:keycodes)
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'vigilem/support/key_map'
|
2
|
+
|
3
|
+
require 'vigilem/evdev/system/input'
|
4
|
+
|
5
|
+
module Vigilem
|
6
|
+
module Evdev
|
7
|
+
module DOM
|
8
|
+
# keycode or sym...
|
9
|
+
KPTable = Support::KeyMap.new({
|
10
|
+
'KP_Space' => "\u0020",
|
11
|
+
'KP_Tab' => "\u0009",
|
12
|
+
'KP_Enter' => "\u000d",
|
13
|
+
'KP_F1' => "\u0000",
|
14
|
+
'KP_F2' => "\u0000",
|
15
|
+
'KP_F3' => "\u0000",
|
16
|
+
'KP_F4' => "\u0000",
|
17
|
+
'KP_Home' => "\u0000",
|
18
|
+
'KP_Left' => "\u0000",
|
19
|
+
'KP_Up' => "\u0000",
|
20
|
+
'KP_Right' => "\u0000",
|
21
|
+
'KP_Down' => "\u0000",
|
22
|
+
'KP_Prior' => "\u0000",
|
23
|
+
'KP_Next' => "\u0000",
|
24
|
+
'KP_End' => "\u0000",
|
25
|
+
'KP_Begin' => "\u0000",
|
26
|
+
'KP_Insert' => "\u0000",
|
27
|
+
'KP_Delete' => "\u0000",
|
28
|
+
'KP_Multiply' => "\u002a",
|
29
|
+
'KP_Add' => "\u002b",
|
30
|
+
'KP_Separator' => "\u002c",
|
31
|
+
'KP_Subtract' => "\u002d",
|
32
|
+
'KP_Decimal' => "\u002e",
|
33
|
+
'KP_Period' => "\u002e",
|
34
|
+
'KP_Divide' => "\u002f",
|
35
|
+
'KP_0' => "\u0030",
|
36
|
+
'KP_1' => "\u0031",
|
37
|
+
'KP_2' => "\u0032",
|
38
|
+
'KP_3' => "\u0033",
|
39
|
+
'KP_4' => "\u0034",
|
40
|
+
'KP_5' => "\u0035",
|
41
|
+
'KP_6' => "\u0036",
|
42
|
+
'KP_7' => "\u0037",
|
43
|
+
'KP_8' => "\u0038",
|
44
|
+
'KP_9' => "\u0039",
|
45
|
+
'KP_Equal' => "\u003d",
|
46
|
+
})
|
47
|
+
KPTable.right_side_alias(:char)
|
48
|
+
KPTable.left_side_alias(:sym)
|
49
|
+
KPTable.left_side_alias(:keysym)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'vigilem/_evdev'
|
2
|
+
|
3
|
+
require 'vigilem/evdev/context_filter'
|
4
|
+
|
5
|
+
require 'vigilem/x11/stat'
|
6
|
+
|
7
|
+
module Vigilem
|
8
|
+
module Evdev
|
9
|
+
#
|
10
|
+
# allows input_events through when the window has focus
|
11
|
+
class FocusContextFilter
|
12
|
+
|
13
|
+
include Evdev::ContextFilter
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
#
|
18
|
+
# @return [String || NilClass]
|
19
|
+
def env_display
|
20
|
+
ENV['DISPLAY']
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
#
|
25
|
+
def lazy_require
|
26
|
+
require 'vigilem/x11/terminal_window_utils'
|
27
|
+
require 'vigilem/x11/input_system_handler'
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# @param [String] display
|
32
|
+
# @param [Integer ||NilClass] xwindow_id
|
33
|
+
# @param [FocusContextFilter || NilClass]
|
34
|
+
# @return [NilClass || self]
|
35
|
+
def new_if_installed(display=env_display, xwindow_id=nil)
|
36
|
+
if X11::Stat.default.installed?
|
37
|
+
new(display, xwindow_id)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# @param [String] display
|
43
|
+
# @param [Integer || NilClass] xwindow_id
|
44
|
+
# @raise [RuntimeError]
|
45
|
+
# @return [NilClass || self]
|
46
|
+
def new_if_installed!(display=env_display, xwindow_id=nil)
|
47
|
+
new_if_installed(display, xwindow_id) || raise('InputSystem unavailable')
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_accessor :input_system_handler
|
53
|
+
|
54
|
+
def_delegators :input_system_handler, :display, :window_xid
|
55
|
+
|
56
|
+
#
|
57
|
+
# @param [String]
|
58
|
+
# @param [Integer || NilClass]
|
59
|
+
def initialize(display=self.class.env_display, xwindow_id=nil)
|
60
|
+
self.class.lazy_require
|
61
|
+
window_xid = xwindow_id || X11::TerminalWindowUtils.window_id
|
62
|
+
|
63
|
+
@input_system_handler = X11::InputSystemHandler.new(window_xid, display, Xlib::FocusChangeMask)
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# @return [TrueClass || FalseClass]
|
68
|
+
def has_focus?
|
69
|
+
with_focus = X11.get_input_focus(self.display, window_xid)[1]
|
70
|
+
with_focus == self.window_xid or
|
71
|
+
self.window_xid == X11.query_tree(self.display, with_focus)[:parent_return]
|
72
|
+
end
|
73
|
+
|
74
|
+
alias_method :had_focus?, :was_off?
|
75
|
+
|
76
|
+
#
|
77
|
+
# @return [TrueClass || FalseClass]
|
78
|
+
def on?
|
79
|
+
if gained_focus?
|
80
|
+
on_change(OFF)
|
81
|
+
elsif lost_focus?
|
82
|
+
on_change(ON)
|
83
|
+
end
|
84
|
+
was_on?
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# @return [TrueClass || FalseClass]
|
89
|
+
def off?
|
90
|
+
not on?
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# @return [TrueClass || FalseClass]
|
95
|
+
def gained_focus?
|
96
|
+
(not had_focus?) and has_focus?
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# @return [TrueClass || FalseClass]
|
101
|
+
def lost_focus?
|
102
|
+
had_focus? and not has_focus?
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# @param [Array] events
|
107
|
+
# @return [Array]
|
108
|
+
def process(*events)
|
109
|
+
if on?
|
110
|
+
[]
|
111
|
+
else
|
112
|
+
events
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
#
|
118
|
+
# @param [TrueClass || FalseClass] bool
|
119
|
+
# @return
|
120
|
+
alias_method :had_focus= ,:was_off=
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|