vigilem-win32_api 0.0.10

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/lib/vigilem/win32_api/console_input_events.rb +78 -0
  4. data/lib/vigilem/win32_api/constants.rb +97 -0
  5. data/lib/vigilem/win32_api/dom/adapter.rb +59 -0
  6. data/lib/vigilem/win32_api/dom/code_values_tables.rb +136 -0
  7. data/lib/vigilem/win32_api/dom/input_record_utils.rb +259 -0
  8. data/lib/vigilem/win32_api/dom/key_values_tables.rb +123 -0
  9. data/lib/vigilem/win32_api/dom.rb +5 -0
  10. data/lib/vigilem/win32_api/eventable.rb +41 -0
  11. data/lib/vigilem/win32_api/input__record.rb +53 -0
  12. data/lib/vigilem/win32_api/input_system_handler.rb +124 -0
  13. data/lib/vigilem/win32_api/p_input__record.rb +55 -0
  14. data/lib/vigilem/win32_api/rubyized.rb +114 -0
  15. data/lib/vigilem/win32_api/types.rb +153 -0
  16. data/lib/vigilem/win32_api/utils/keyboard.rb +120 -0
  17. data/lib/vigilem/win32_api/version.rb +5 -0
  18. data/lib/vigilem/win32_api/virtual_keys/map.rb +211 -0
  19. data/lib/vigilem/win32_api/virtual_keys.rb +9 -0
  20. data/lib/vigilem/win32_api.rb +61 -0
  21. data/spec/acceptance/custom_input_system.feature +3 -0
  22. data/spec/acceptance/dom_adapter.feature +7 -0
  23. data/spec/acceptance/rubyized.feature +6 -0
  24. data/spec/acceptance/steps/custom_input_system_steps.rb +37 -0
  25. data/spec/acceptance/steps/dom_adapter_steps.rb +7 -0
  26. data/spec/acceptance/steps/rubyized_steps.rb +20 -0
  27. data/spec/attributes_and_size_test.rb +10 -0
  28. data/spec/input_helper.rb +41 -0
  29. data/spec/spec_helper.rb +28 -0
  30. data/spec/turnip_helper.rb +1 -0
  31. data/spec/vigilem/api_spec.rb +139 -0
  32. data/spec/vigilem/win32_api/console_input_events_spec.rb +67 -0
  33. data/spec/vigilem/win32_api/dom/adapter_spec.rb +164 -0
  34. data/spec/vigilem/win32_api/dom/code_values_tables_spec.rb +5 -0
  35. data/spec/vigilem/win32_api/dom/input_record_utils_spec.rb +255 -0
  36. data/spec/vigilem/win32_api/dom/key_values_tables_spec.rb +5 -0
  37. data/spec/vigilem/win32_api/eventable_spec.rb +96 -0
  38. data/spec/vigilem/win32_api/input__record_spec.rb +113 -0
  39. data/spec/vigilem/win32_api/input_system_handler_spec.rb +164 -0
  40. data/spec/vigilem/win32_api/p_input__record_spec.rb +43 -0
  41. data/spec/vigilem/win32_api/rubyized_spec.rb +134 -0
  42. data/spec/vigilem/win32_api/types_spec.rb +139 -0
  43. data/spec/vigilem/win32_api/utils/keyboard_spec.rb +126 -0
  44. data/spec/vigilem/win32_api/virtual_keys/map_spec.rb +10 -0
  45. data/spec/vigilem/win32_api/virtual_keys_spec.rb +28 -0
  46. metadata +225 -0
@@ -0,0 +1,123 @@
1
+ module Vigilem
2
+ module Win32API::DOM
3
+
4
+ # converts Windows VK if available or VK
5
+ # https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.code
6
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=865649
7
+ module KeyValuesTables
8
+ key_values = Vigilem::DOM::KeyValues
9
+
10
+ ModifierKeys = Support::KeyMap.new({
11
+ :'' => 'Accel',
12
+ :VK_MENU => 'Alt',
13
+ :VK_LMENU => 'Alt',
14
+ :'' => 'AltGraph',
15
+ :VK_CAPITAL => 'CapsLock',
16
+ :VK_CONTROL => 'Control',
17
+ :VK_LCONTROL => 'Control',
18
+ :VK_RCONTROL => 'Control',
19
+ :'' => 'Fn',
20
+ :'' => 'FnLock',
21
+ :'' => 'Hyper',
22
+ :VK_RMENU => 'Meta',
23
+ :VK_NUMLOCK => 'NumLock',
24
+ :VK_LWIN => 'OS', #The operating system key (e.g. the "Windows Logo" key).
25
+ :VK_SCROLL => 'ScrollLock',
26
+ :VK_SHIFT => 'Shift',
27
+ :VK_LSHIFT => 'Shift',
28
+ :VK_RSHIFT => 'Shift',
29
+ :'' => 'Super',
30
+ :'' => 'Symbol',
31
+ :VK_SYMBOL => 'SymbolLock' #0x7A:VK_F11:VK_SYMBOL:Symbol (SYM) key.
32
+ })
33
+
34
+ WhitespaceKeys = Support::KeyMap[[:VK_RETURN, :VK_SEPARATOR, :VK_TAB].zip(key_values::WhitespaceKeys)]
35
+ #The space or spacebar key is encoded as ' '.
36
+
37
+ NavigationKeys = Support::KeyMap[[:VK_DOWN, :VK_LEFT, :VK_RIGHT, :VK_UP,
38
+ :VK_END, :VK_HOME,:VK_NEXT, :VK_PRIOR].zip(key_values::NavigationKeys)]
39
+ EditingKeys = Support::KeyMap[[:VK_BACK, :VK_CLEAR, :'', :VK_CRSEL, :'', :VK_DELETE, :VK_EREOF,
40
+ :VK_EXSEL, :VK_INSERT, :'', :'', :''].zip(key_values::EditingKeys)]
41
+ UIKeys = Support::KeyMap[[:VK_ACCEPT, #IME accept?
42
+ :'', :VK_ATTN, :VK_CANCEL, :VK_APPS, :VK_ESCAPE, :VK_EXECUTE,
43
+ :'', :VK_HELP, :VK_PAUSE, :'', :'',
44
+ :VK_SCROLL, :VK_ZOOM, :VK_ZOOM].zip(key_values::UIKeys)]
45
+ DeviceKeys = Support::KeyMap.new({
46
+ :'' => ['BrightnessDown', 'BrightnessUp', 'Camera', 'Eject', 'LogOff', 'Power', 'PowerOff', 'Hibernate', 'Standby', 'WakeUp'],
47
+ :VK_SNAPSHOT => 'PrintScreen' #doesn;t work with readconsoleinput
48
+ })
49
+ IMEandCompositionKeys = Support::KeyMap.new({
50
+ :'' => ['AllCandidates', 'Alphanumeric', 'CodeInput', 'Compose', 'GroupFirst', 'GroupLast', 'GroupNext', 'GroupPrevious',
51
+ 'NextCandidate', 'PreviousCandidate', 'SingleCandidate'],
52
+ :VK_CONVERT => 'Convert',
53
+ :VK_FINAL => 'FinalMode',
54
+ :VK_MODECHANGE => 'ModeChange',
55
+ :VK_NONCONVERT => 'NonConvert',
56
+ :VK_PROCESSKEY => 'Process'
57
+ })
58
+ KeysspecifictoKoreankeyboards = Support::KeyMap.new({
59
+ :VK_OEM_BACKTAB => 'RomanCharacters', #"RomanCharacters" for Japanese keyboard layout, "Unidentified" for the others.
60
+ :VK_HANGUEL => 'HangulMode',
61
+ :VK_HANGUEL => 'HangulMode',
62
+ :VK_HANJA => 'HanjaMode',
63
+ :VK_JUNJA => 'JunjaMode'
64
+ })
65
+ KeysspecifictoJapanesekeyboards = Support::KeyMap.new({
66
+ :VK_OEM_ENLW => 'Zenkaku',
67
+ :VK_OEM_AUTO => 'Hankaku',
68
+ :'' => ['ZenkakuHankaku', 'Katakana', 'HiraganaKatakana', 'Eisu'],
69
+ :VK_KANA => 'KanaMode',
70
+ :VK_KANJI => 'KanjiMode',
71
+ :VK_OEM_COPY => 'Hiragana' #"Hiragana" for Japanese keyboard layout, "Unidentified" for the others.
72
+ })
73
+ General_PurposeFunctionKeys = Support::KeyMap.new({
74
+ :VK_F1 => 'F1',
75
+ :VK_F2 => 'F2',
76
+ :VK_F3 => 'F3',
77
+ :VK_F4 => 'F4',
78
+ :VK_F5 => 'F5',
79
+ :VK_F6 => 'F6',
80
+ :VK_F7 => 'F7',
81
+ :VK_F8 => 'F8',
82
+ :VK_F9 => 'F9',
83
+ :VK_F10 => 'F10',
84
+ :VK_F11 => 'F11',
85
+ :VK_F12 => 'F12',
86
+ :'' => ['Soft1', 'Soft2', 'Soft3', 'Soft4']
87
+ })
88
+ #Mediamedia
89
+ MultimediaKeys = Support::KeyMap.new({
90
+ #These are extra keys found on "multimedia" keyboards.
91
+ :'' => ['Close', 'MailForward', 'MailReply', 'MailSend', 'New', 'Open', 'Save', 'SpellCheck'],
92
+ :VK_MEDIA_PLAY_PAUSE => 'MediaPlayPause',
93
+ :VK_LAUNCH_MEDIA_SELECT => 'MediaSelect',
94
+ :VK_MEDIA_STOP => 'MediaStop',
95
+ :VK_MEDIA_NEXT_TRACK => 'MediaTrackNext',
96
+ :VK_MEDIA_PREV_TRACK => 'MediaTrackPrevious',
97
+ :VK_PRINT => 'Print',
98
+ :VK_VOLUME_DOWN => 'VolumeDown',
99
+ :VK_VOLUME_UP => 'VolumeUp',
100
+ :VK_VOLUME_MUTE => 'VolumeMute'
101
+ })
102
+ ApplicationKeys = Support::KeyMap.new({
103
+ :'' => ['LaunchCalculator', 'LaunchCalendar', 'LaunchMediaPlayer', 'LaunchMusicPlayer',
104
+ 'LaunchMyComputer', 'LaunchScreenSaver', 'LaunchSpreadsheet', 'LaunchWebBrowser',
105
+ 'LaunchWebCam', 'LaunchWordProcessor'],
106
+ :VK_LAUNCH_MAIL => 'LaunchMail'
107
+ })
108
+ BrowserKeys = Support::KeyMap[key_values::BrowserKeys.zip([:VK_BROWSER_BACK, :VK_BROWSER_FAVORITES, :VK_BROWSER_FORWARD, :VK_BROWSER_HOME, :VK_BROWSER_REFRESH, :VK_BROWSER_SEARCH, :VK_BROWSER_STOP])]
109
+ #The key values for media controllers (e.g. remote controls for
110
+ #television, audio systems, and set-top boxes) are
111
+ #derived in part from the consumer electronics technical specifications:
112
+ MediaControllerKeys = Support::KeyMap[key_values::MediaControllerKeys.zip([:'']).reverse]
113
+
114
+ SpecialKeyValues = Support::KeyMap.new({ :'' => 'Unidentified' })
115
+
116
+ end
117
+ KeyTable = KeyValuesTables.constants.each_with_object(Support::KeyMap.new()) {|table_name, memo| memo.merge! KeyValuesTables.const_get(table_name) }
118
+ KeyTable.default = 'Unidentified'
119
+
120
+ KeyTable.right_side_alias(:dom_key)
121
+ KeyTable.left_side_alias(:win_vk)
122
+ end
123
+ end
@@ -0,0 +1,5 @@
1
+ require 'vigilem/dom'
2
+
3
+ require 'vigilem/win32_api/dom/input_record_utils'
4
+
5
+ require 'vigilem/win32_api/dom/adapter'
@@ -0,0 +1,41 @@
1
+ module Vigilem::Win32API
2
+ #
3
+ # @abstract included into the same module as RubyizedAPI
4
+ # or respond_to? [:read_console_input, :peek_console_input]
5
+ module Eventable
6
+
7
+ # @param [Integer] limit
8
+ # @return [Array]
9
+ def read_many_nonblock(limit=1)
10
+ [*(read_console_input({:nLength => limit, :blocking => false }) if has_any?)]
11
+ end
12
+
13
+ # blocks until the specified number of events are read
14
+ # @param [Integer] number_of_events=1
15
+ # @return [Array]
16
+ def read_many(number_of_events=1)
17
+ read_console_input({:nLength => number_of_events, :blocking => true })
18
+ end
19
+
20
+ # non_blocking
21
+ # commonly used with event processing
22
+ # @param [Integer]
23
+ # @return [InputRecord]
24
+ def read_one_nonblock
25
+ read_one if has_any?
26
+ end
27
+
28
+ # blocking
29
+ # reads one event from the input buffer
30
+ # @return [Array]
31
+ def read_one
32
+ read_console_input.shift
33
+ end
34
+
35
+ # checks whether the input buffer has events
36
+ # @return [TrueClass || FalseClass]
37
+ def has_any?
38
+ peek_console_input.size > 0
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,53 @@
1
+ module Vigilem
2
+
3
+ #
4
+ module Win32API
5
+
6
+
7
+ #
8
+ class INPUT_RECORD < ::VFFIStruct
9
+
10
+ # @!attr [Integer] the ID type of this record
11
+ layout_with_methods :EventType, :WORD,
12
+ *(union(:Event) do
13
+ ConsoleInputEvents.vk_names.map do |event|
14
+ event.to_s.downcase.titlecase.split(/\s+/).join.to_sym
15
+ end.sort.zip(ConsoleInputEvents.structs.sort {|klass, other_klass| klass.name <=> other_klass.name }).flatten
16
+ end)
17
+
18
+ #
19
+ # @return [Hash]
20
+ def to_h
21
+ FFIUtils.struct_to_h(self)
22
+ end
23
+
24
+ #
25
+ # @return [Integer]
26
+ def type
27
+ self.EventType
28
+ end
29
+
30
+ #
31
+ # @return [INPUT_RECORD::Union::*_EVENT_RECORD]
32
+ def event_record
33
+ self.class.event_record(self)
34
+ end
35
+
36
+ #
37
+ # @param input_record [EventUnion?]
38
+ # @return [INPUT_RECORD::Union::*_EVENT_RECORD]
39
+ def self.event_record(input_record)
40
+ sym = ConsoleInputEvents.vk_hash[input_record.EventType].to_s.downcase.titlecase.gsub(/\s+/, '').to_sym
41
+ input_record.Event[sym] unless sym.nil? or sym.empty?
42
+ end
43
+
44
+ #
45
+ # @return [String]
46
+ def inspect
47
+ head, tail = super.split(' ', 2)
48
+ "#{head} event_record=#{event_record.inspect} #{tail}"
49
+ end
50
+ end
51
+ InputRecord = INPUT_RECORD
52
+ end
53
+ end
@@ -0,0 +1,124 @@
1
+ require 'vigilem/core/input_system_handler'
2
+
3
+ require 'vigilem/core/hub'
4
+
5
+ require 'vigilem/core/adapters/buffered_adapter'
6
+
7
+ require 'vigilem/win32_api'
8
+
9
+ require 'vigilem/win32_api/rubyized'
10
+
11
+ require 'vigilem/win32_api/eventable'
12
+
13
+ module Vigilem
14
+ module Win32API
15
+
16
+ #
17
+ class InputSystemHandler
18
+
19
+ include Core::InputSystemHandler
20
+
21
+ include Core::Adapters::BufferedAdapter
22
+
23
+ include Rubyized
24
+
25
+ include Eventable
26
+
27
+ #
28
+ # @param lnk
29
+ def initialize(lnk=nil)
30
+ initialize_buffered(lnk || Vigilem::Win32API)
31
+ end
32
+
33
+ def win32_api_rubyized_source
34
+ self
35
+ end
36
+
37
+ def_delegator :link, :GetStdHandle
38
+
39
+ #
40
+ # @param [Finum] hConsoleInput
41
+ # @param [PINPUT_RECORD] lpBuffer, out, this item will be updated
42
+ # @param [Integer] nLength
43
+ # @param [::FFI::Pointer] lpNumberOfEventsRead, out, this item will be updated
44
+ # @return [Integer] 1 or 0
45
+ def PeekConsoleInput(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead)
46
+ semaphore.synchronize {
47
+ events = buffered(nLength) do |len_remainder|
48
+ ret = link.PeekConsoleInputW(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead)
49
+ lpBuffer
50
+ end
51
+ _update_out_args(lpBuffer, lpNumberOfEventsRead, events)
52
+ ret ||= 1
53
+ }
54
+ end
55
+
56
+ #
57
+ # @param [Finum] hConsoleInput
58
+ # @param [PINPUT_RECORD] lpBuffer, out, this item will be updated
59
+ # @param [Integer] nLength
60
+ # @param [::FFI::Pointer] lpNumberOfEventsRead, out, this item will be updated
61
+ # @return [Integer] 1 or 0
62
+ def ReadConsoleInput(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead)
63
+ semaphore.synchronize {
64
+ events = buffered!(nLength) do |still_to_get|
65
+ ret = link.ReadConsoleInputW(hConsoleInput, lpBuffer, still_to_get, lpNumberOfEventsRead)
66
+ demux(*lpBuffer) unless lpBuffer.empty?
67
+ lpBuffer
68
+ end
69
+ _update_out_args(lpBuffer, lpNumberOfEventsRead, events)
70
+ ret ||= 1
71
+ }
72
+ end
73
+
74
+ #
75
+ # @see
76
+ # @param [Integer] uCode
77
+ # @param [Integer] uMapType
78
+ # @return
79
+ def MapVirtualKey(uCode, uMapType)
80
+ # without this it could fail silently
81
+ raise ArgumentError, "uCode has to be a Integer not #{uCode.class}:`#{uCode}'" unless uCode.is_a? Integer
82
+ raise ArgumentError, "uMapType has to be a Integer not #{uMapType.class}:`#{uMapType}'" unless uMapType.is_a? Integer
83
+ link.MapVirtualKeyW(uCode, uMapType)
84
+ end
85
+
86
+ # the hub that sends and receives messages for
87
+ # this buffer
88
+ # @raise RuntimeError
89
+ # @return
90
+ def hub
91
+ @hub ||= (Core::Hub.aquire(link()) << self.buffer)
92
+ end
93
+
94
+ #
95
+ # @see Hub#demux
96
+ # @param [Array] msgs
97
+ # @return
98
+ def demux(*msgs)
99
+ hub.demux(self, *msgs)
100
+ end
101
+ private
102
+
103
+ #
104
+ # @param [PINPUT_RECORD] lpBuffer
105
+ # @param [::FFI::Pointer] lpNumberOfEventsRead
106
+ # @param [Array] events
107
+ # @return [Array]
108
+ def _update_out_args(lpBuffer, lpNumberOfEventsRead, events)
109
+ FFIUtils.add_int_typedef(lpNumberOfEventsRead, :dword, evnt_sze = events.size)
110
+ begin
111
+ lpBuffer.replace(events + [*lpBuffer[evnt_sze..-1]])
112
+ rescue ArgumentError => e
113
+ if e.message =~ /bad value for range/
114
+ e.message.replace("#{e.message}, #{evnt_sze.inspect}..-1")
115
+ raise e
116
+ else
117
+ raise
118
+ end
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,55 @@
1
+ require 'vigilem/ffi'
2
+
3
+ module Vigilem
4
+ module Win32API
5
+
6
+ #
7
+ class PINPUT_RECORD
8
+
9
+ include FFI::ArrayPointerSync
10
+
11
+ # @see ArrayPointerSync#initialize_array_sync
12
+ # @param [Integer || FFI::Pointer] max_len_or_ptr
13
+ # @param [Array]
14
+ def initialize(max_len_or_ptr, *init_values)
15
+ initialize_ary_ptr_sync(max_len_or_ptr, *init_values)
16
+ end
17
+
18
+ class << self
19
+
20
+ #
21
+ # @param [FFI::Pointer]
22
+ # @return [self]
23
+ def from_pointer(pointer)
24
+ new(pointer)
25
+ end
26
+
27
+ #
28
+ # @return [Class || Symbol]
29
+ def ary_type
30
+ INPUT_RECORD
31
+ end
32
+
33
+ # Converts the specified value from the native type.
34
+ # @param value
35
+ # @param ctx
36
+ # @return [PINPUT_RECORD]
37
+ def from_native(value, ctx)
38
+ new(value)
39
+ end
40
+
41
+ # Converts the specified value to the native type.
42
+ # @param value
43
+ # @param ctx
44
+ # @return [FFI::Pointer]
45
+ def to_native(value, ctx)
46
+ value.ptr
47
+ end
48
+ end
49
+
50
+ end
51
+ PInputRecord = PINPUT_RECORD
52
+ ::FFI.typedef(PINPUT_RECORD, :pinput_record)
53
+ ::FFI.typedef(PINPUT_RECORD, :PINPUT_RECORD)
54
+ end
55
+ end
@@ -0,0 +1,114 @@
1
+ require 'vigilem/win32_api'
2
+
3
+ module Vigilem::Win32API
4
+ # @abstract
5
+ # @see http://msdn.microsoft.com
6
+ module Rubyized
7
+
8
+ include Vigilem::Win32API::Constants
9
+
10
+ #
11
+ # @param [Integer] handle defaults to Vigilem::Win32API::STD_INPUT_HANDLE
12
+ # @return [Integer]
13
+ def get_std_handle(handle=Vigilem::Win32API::STD_INPUT_HANDLE)
14
+ win32_api_rubyized_src.GetStdHandle(handle)
15
+ end
16
+
17
+ #
18
+ # @param [Hash]
19
+ # @option opts [Integer] :hConsoleInput
20
+ # @option opts [PINPUT_RECORD || Array] :lpBuffer
21
+ # @option opts [Integer] :nLength
22
+ # @option opts [Integer] :lpNumberOfEventsRead
23
+ # @return [PINPUT_RECORD]
24
+ def peek_console_input(opts={})
25
+ _options(opts)
26
+ win32_api_rubyized_src.PeekConsoleInput(opts[:hConsoleInput], opts[:lpBuffer], opts[:nLength], opts[:lpNumberOfEventsRead])
27
+ opts[:lpBuffer]
28
+ end
29
+
30
+ # default behaviour is that of read_console_input (block if no msgs in the buffer,
31
+ # if opts[:blocking] == true, the method will block until lpBuffer full
32
+ # if opts[:blocking] == false, there will be no blocking
33
+ # @param [Hash]
34
+ # @option opts [Integer] :hConsoleInput
35
+ # @option opts [PINPUT_RECORD || Array] :lpBuffer
36
+ # @option opts [Integer] :nLength
37
+ # @option opts [Integer] :lpNumberOfEventsRead
38
+ # @return [PINPUT_RECORD]
39
+ def read_console_input(opts={})
40
+ _options(opts)
41
+
42
+ lp_buffer = []
43
+
44
+ if (default = (blocking = opts[:blocking]).nil?) or blocking
45
+ begin
46
+ win32_api_rubyized_src.ReadConsoleInput(opts[:hConsoleInput], opts[:lpBuffer], opts[:nLength], opts[:lpNumberOfEventsRead])
47
+ lp_buffer += opts[:lpBuffer]
48
+ end while (not default) and lp_buffer.size < opts[:nLength]
49
+ opts[:lpBuffer].replace(lp_buffer)
50
+ elsif not peek_console_input.empty?
51
+ win32_api_rubyized_src.ReadConsoleInput(opts[:hConsoleInput], opts[:lpBuffer], opts[:nLength], opts[:lpNumberOfEventsRead])
52
+ opts[:lpBuffer]
53
+ end
54
+ end
55
+
56
+ # Translates (maps) a virtual-key code into a scan code or character
57
+ # value, or translates a scan code into a virtual-key code.
58
+ # @param [Integer] code, the uCode
59
+ # @param [Symbol || Integer] conversion, the uMapType, Vigilem::Win32API::Constants::MapType
60
+ # @raise ArgumentError when conversion is a Symbol and not a valid uMapType name
61
+ # @raise ArgumentError when conversion is a Integer and not a valid uMapType code
62
+ # @return [Integer]
63
+ def map_virtual_key(code, conversion)
64
+ conversion_value = if conversion.is_a? Symbol
65
+ raise ArgumentError, "`#{conversion}' is not an available uMapType name" unless MapType.constants.include? conversion
66
+ API::Rubyized.const_get(conversion)
67
+ elsif not (@uMapeTypes ||= MapType.constants.map {|const| Vigilem::Win32API::Rubyized.const_get(const) }).include? conversion
68
+ raise ArgumentError, "`#{conversion}' is not an available uMapType"
69
+ end
70
+ win32_api_rubyized_src.MapVirtualKey(code, conversion_value || conversion)
71
+ end
72
+
73
+ private
74
+
75
+ # sets up default options for peek and read based
76
+ # on user input
77
+ # @note default nLength is 1
78
+ # @param [Hash] opts
79
+ # @option opts [Integer] :hConsoleInput
80
+ # @option opts [Integer] :nLength
81
+ # @option opts [Win32API::PINPUT_RECORD || Array] :lpBuffer
82
+ # @option opts [NilClass || Integer] :lpNumberOfEventsRead
83
+ # @option opts [NilClass || TrueClass || FalseClass] :blocking
84
+ # @return [Hash]
85
+ def _options(opts={})
86
+ opts[:hConsoleInput] ||= get_std_handle()
87
+
88
+ if opts[:lpBuffer].is_a? Array
89
+ opts[:nLength] = opts[:lpBuffer].size
90
+ opts[:lpBuffer] = Vigilem::Win32API::PINPUT_RECORD.new(opts[:nLength], *opts[:lpBuffer])
91
+ else
92
+ opts[:nLength] ||= 1
93
+ opts[:lpBuffer] ||= Vigilem::Win32API::PINPUT_RECORD.new(opts[:nLength])
94
+ end
95
+ opts[:lpNumberOfEventsRead] ||= FFI::MemoryPointer.new(:DWORD, 1)
96
+
97
+ opts
98
+ end
99
+
100
+ attr_writer :win32_api_rubyized_source
101
+
102
+ alias_method :win32_api_rubyized_src=, :win32_api_rubyized_source=
103
+
104
+ #
105
+ # @raise [NotImplementedError]
106
+ # @return
107
+ def win32_api_rubyized_source
108
+ @win32_api_rubyized_source ||= self
109
+ end
110
+
111
+ alias_method :win32_api_rubyized_src, :win32_api_rubyized_source
112
+
113
+ end
114
+ end
@@ -0,0 +1,153 @@
1
+ require 'ffi'
2
+
3
+ require 'vigilem/core'
4
+
5
+ module Vigilem
6
+ module Win32API
7
+
8
+ #
9
+ module Types
10
+
11
+ extend ::FFI::Library
12
+
13
+ # Check for 64b operating systems.
14
+ if Vigilem::Core::System.x64bit?
15
+ ::FFI.typedef(:uint64, :ulong_ptr)
16
+ ::FFI.typedef(:int64, :long_ptr)
17
+ else
18
+ ::FFI.typedef(:ulong, :ulong_ptr)
19
+ ::FFI.typedef(:long, :long_ptr)
20
+ end
21
+
22
+
23
+ #
24
+ module PVOID
25
+ extend ::FFI::DataConverter
26
+ native_type ::FFI::Type::POINTER
27
+
28
+ class << self
29
+ # Converts the specified value from the native type.
30
+ # @return [Bignum, Integer]
31
+ def from_native(value, ctx)
32
+ value.address
33
+ end
34
+
35
+ # Converts the specified value to the native type.
36
+ # @return [::FFI::Pointer]
37
+ def to_native(value, ctx)
38
+ case
39
+ when value.kind_of?(::FFI::Pointer)
40
+ value
41
+ when value.kind_of?(::FFI::Struct)
42
+ value.to_ptr
43
+ else
44
+ ::FFI::Pointer.new(value.to_i)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+ #
52
+ class PBYTE
53
+
54
+ include ::Vigilem::FFI::ArrayPointerSync
55
+
56
+ # @see ArrayPointerSync#initialize_array_sync
57
+ # @param [Integer || ::FFI::Pointer] max_len_or_ptr
58
+ # @param [Array]
59
+ def initialize(max_len_or_ptr, *init_values)
60
+ initialize_array_sync(max_len_or_ptr, *init_values)
61
+ end
62
+
63
+ class << self
64
+
65
+ #
66
+ # [Class || Symbol]
67
+ def array_type
68
+ :BYTE
69
+ end
70
+
71
+ # Converts the specified value from the native type.
72
+ # @return [Integer]
73
+ def from_native(value, ctx)
74
+ new(value)
75
+ end
76
+
77
+ # Converts the specified value to the native type.
78
+ # @return [::FFI::Pointer]
79
+ def to_native(value, ctx)
80
+ case
81
+ when value.is_a?(::FFI::Pointer)
82
+ value
83
+ when value.is_a?(self)
84
+ value.ptr
85
+ else
86
+ raise "#{value} is an Unsupported Type"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ ::FFI.typedef(PVOID, :p_void)
93
+ ::FFI.typedef(PVOID, :PVOID)
94
+
95
+ ::FFI.typedef(PBYTE, :PBYTE)
96
+
97
+ ::FFI.typedef(:p_void, :handle)
98
+ ::FFI.typedef(:PVOID, :HANDLE)
99
+
100
+ ::FFI.typedef(:handle, :h_wnd)
101
+ ::FFI.typedef(:h_wnd, :HWND)
102
+
103
+ ::FFI.typedef(:ushort, :word)
104
+ ::FFI.typedef(:word, :WORD)
105
+
106
+ ::FFI.typedef(:ushort, :wchar)
107
+ ::FFI.typedef(:wchar, :WCHAR)
108
+
109
+ ::FFI.typedef(:ushort, :char)
110
+ ::FFI.typedef(:char, :CHAR)
111
+
112
+ ::FFI.typedef(:uint, :dword)
113
+ ::FFI.typedef(:uint, :DWORD)
114
+
115
+ ::FFI.typedef(:uint, :UINT)
116
+
117
+ ::FFI.typedef(:int, :BOOL)
118
+
119
+ ::FFI.typedef(:uchar, :BYTE)
120
+
121
+ ::FFI.typedef(:ulong_ptr, :WPARAM)
122
+ ::FFI.typedef(:long_ptr, :LPARAM)
123
+
124
+
125
+ #
126
+ class POINT < ::VFFIStruct
127
+ layout_with_methods :x, :long,
128
+ :y, :long
129
+ end
130
+
131
+
132
+ #
133
+ class MSG < ::VFFIStruct
134
+ layout_with_methods :hwnd, :HWND,
135
+ :message, :uint,
136
+ :wParam, :WPARAM,
137
+ :lParam, :LPARAM,
138
+ :time, :DWORD,
139
+ :pt, POINT
140
+ end
141
+
142
+
143
+ #
144
+ class COORD < ::VFFIStruct
145
+ layout_with_methods :x, :short,
146
+ :y, :short
147
+ end
148
+
149
+ end
150
+
151
+ include Types
152
+ end
153
+ end