libusb 0.6.4-x86-mingw32 → 0.7.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/lib/libusb/call.rb CHANGED
@@ -228,14 +228,23 @@ module LIBUSB
228
228
  #
229
229
  # @see Bos::DeviceCapability
230
230
  BosTypes = enum :libusb_bos_type, [
231
- # Wireless USB device capability
232
- :BT_WIRELESS_USB_DEVICE_CAPABILITY, 1,
233
- # USB 2.0 extensions
234
- :BT_USB_2_0_EXTENSION, 2,
235
- # SuperSpeed USB device capability
236
- :BT_SS_USB_DEVICE_CAPABILITY, 3,
237
- # Container ID type
238
- :BT_CONTAINER_ID, 4,
231
+ :BT_WIRELESS_USB_DEVICE_CAPABILITY, 0x01, # Wireless USB device capability
232
+ :BT_USB_2_0_EXTENSION, 0x02, # USB 2.0 extensions
233
+ :BT_SS_USB_DEVICE_CAPABILITY, 0x03, # SuperSpeed USB device capability
234
+ :BT_CONTAINER_ID, 0x04, # Container ID type
235
+ :BT_PLATFORM_DESCRIPTOR, 0x05, # Platform descriptor
236
+ :BT_POWER_DELIVERY_CAPABILITY, 0x06, # Defines the various PD Capabilities of this device
237
+ :BT_BATTERY_INFO_CAPABILITY, 0x07, # Provides information on each battery supported by the device
238
+ :BT_PD_CONSUMER_PORT_CAPABILITY, 0x08, # The consumer characteristics of a port on the device
239
+ :BT_PD_PROVIDER_PORT_CAPABILITY, 0x09, # The provider characteristics of a port on the device
240
+ :BT_SUPERSPEED_PLUS, 0x0A, # Defines the set of SuperSpeed Plus USB specific device level capabilities
241
+ :BT_PRECISION_TIME_MEASUREMENT, 0x0B, # Precision Time Measurement (PTM) Capability Descriptor
242
+ :BT_Wireless_USB_Ext, 0x0C, # Defines the set of Wireless USB 1.1-specific device level capabilities
243
+ :BT_BILLBOARD, 0x0D, # Billboard capability
244
+ :BT_AUTHENTICATION, 0x0E, # Authentication Capability Descriptor
245
+ :BT_BILLBOARD_EX, 0x0F, # Billboard Ex capability
246
+ :BT_CONFIGURATION_SUMMARY, 0x10, # Summarizes configuration information for a function implemented by the device
247
+ :BT_FWStatus_Capability, 0x11, # Describes the capability to support FWStatus
239
248
  ]
240
249
 
241
250
  # Since libusb version 1.0.16.
@@ -274,6 +283,25 @@ module LIBUSB
274
283
  :LOG_LEVEL_DEBUG, 4,
275
284
  ]
276
285
 
286
+ # /** \ingroup libusb_lib
287
+ # * Log callback mode.
288
+ # *
289
+ # * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
290
+ # *
291
+ # * \see libusb_set_log_cb()
292
+ # */
293
+ # enum libusb_log_cb_mode {
294
+ # /** Callback function handling all log messages. */
295
+ # LIBUSB_LOG_CB_GLOBAL = (1 << 0),
296
+ #
297
+ # /** Callback function handling context related log messages. */
298
+ # LIBUSB_LOG_CB_CONTEXT = (1 << 1)
299
+ # };
300
+ LogCbMode = enum :libusb_log_cb_mode, [
301
+ :LOG_CB_GLOBAL, (1 << 0),
302
+ :LOG_CB_CONTEXT, (1 << 1),
303
+ ]
304
+
277
305
  # Available option values for {Context#set_option}.
278
306
  Options = enum :libusb_option, [
279
307
  # Set the log message verbosity.
@@ -296,7 +324,7 @@ module LIBUSB
296
324
  #
297
325
  # If libusb was compiled with verbose debug message logging, this function
298
326
  # does nothing: you'll always get messages from all levels.
299
- :OPTION_LOG_LEVEL,
327
+ :OPTION_LOG_LEVEL, 0,
300
328
 
301
329
  # Use the UsbDk backend for a specific context, if available.
302
330
  #
@@ -306,7 +334,33 @@ module LIBUSB
306
334
  # Only valid on Windows.
307
335
  #
308
336
  # Available since libusb-1.0.22.
309
- :OPTION_USE_USBDK,
337
+ :OPTION_USE_USBDK, 1,
338
+
339
+ # Do not scan for devices
340
+ #
341
+ # With this option set, libusb will skip scanning devices in
342
+ # libusb_init_context().
343
+ #
344
+ # Hotplug functionality will also be deactivated.
345
+ #
346
+ # The option is useful in combination with libusb_wrap_sys_device(),
347
+ # which can access a device directly without prior device scanning.
348
+ #
349
+ # This is typically needed on Android, where access to USB devices
350
+ # is limited.
351
+ #
352
+ # Only valid on Linux. Ignored on all other platforms.
353
+ :OPTION_NO_DEVICE_DISCOVERY, 2,
354
+
355
+ # Set the context log callback functon.
356
+ #
357
+ # Set the log callback function either on a context or globally.
358
+ # This option must be provided a Proc argument or +nil+ to remove the callback.
359
+ # Using this option with a +nil+ context is equivalent to calling libusb_set_log_cb with mode :LOG_CB_GLOBAL.
360
+ # Using it with a non- +nil+ context is equivalent to calling libusb_set_log_cb with mode :LOG_CB_CONTEXT.
361
+ :OPTION_LOG_CB, 3,
362
+
363
+ :OPTION_MAX, 4,
310
364
  ]
311
365
 
312
366
  typedef :pointer, :libusb_context
@@ -315,15 +369,60 @@ module LIBUSB
315
369
  typedef :pointer, :libusb_transfer
316
370
  typedef :int, :libusb_hotplug_callback_handle
317
371
 
318
- def self.try_attach_function(method, *args)
319
- if ffi_libraries.find{|lib| lib.find_function(method) }
320
- attach_function method, *args
372
+ # /** \ingroup libusb_lib
373
+ # * Callback function for handling log messages.
374
+ # * \param ctx the context which is related to the log message, or +nil+ if it
375
+ # * is a global log message
376
+ # * \param level the log level, see \ref libusb_log_level for a description
377
+ # * \param str the log message
378
+ # *
379
+ # * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
380
+ # *
381
+ # * \see libusb_set_log_cb()
382
+ # */
383
+ # typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx,
384
+ # enum libusb_log_level level, const char *str);
385
+ callback :libusb_log_cb, [:libusb_context, :libusb_log_level, :string], :void
386
+
387
+ # @private
388
+ # /** \ingroup libusb_lib
389
+ # * Structure used for setting options through \ref libusb_init_context.
390
+ # *
391
+ # */
392
+ # struct libusb_init_option {
393
+ # /** Which option to set */
394
+ # enum libusb_option option;
395
+ # /** An integer value used by the option (if applicable). */
396
+ # union {
397
+ # int64_t ival;
398
+ # libusb_log_cb log_cbval;
399
+ # } value;
400
+ # };
401
+ class InitOptionValue < FFI::Union
402
+ layout :ival, :int64_t,
403
+ :log_cbval, :libusb_log_cb
404
+ end
405
+ class InitOption < FFI::Struct
406
+ layout :option, :libusb_option,
407
+ :value, InitOptionValue
408
+ end
409
+
410
+ class << self
411
+ private def try_attach_function(method, *args, **kwargs)
412
+ if ffi_libraries.find{|lib| lib.find_function(method) }
413
+ attach_function method, *args, **kwargs
414
+ end
321
415
  end
322
416
  end
323
417
 
324
418
  try_attach_function 'libusb_get_version', [], :pointer
325
419
 
326
420
  attach_function 'libusb_init', [ :pointer ], :int
421
+ # int LIBUSB_CALL libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options);
422
+ try_attach_function 'libusb_init_context', [:pointer, :pointer, :int], :int
423
+ # may be deprecated in the future in favor of libusb_init_context()+libusb_set_option()
424
+ # void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode);
425
+ try_attach_function 'libusb_set_log_cb', [:libusb_context, :libusb_log_cb, :int], :void
327
426
  attach_function 'libusb_exit', [ :pointer ], :void
328
427
  attach_function 'libusb_set_debug', [:pointer, :libusb_log_level], :void
329
428
  try_attach_function 'libusb_set_option', [:libusb_context, :libusb_option, :varargs], :int
@@ -348,6 +447,8 @@ module LIBUSB
348
447
  try_attach_function 'libusb_get_device_speed', [:pointer], :libusb_speed
349
448
  attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
350
449
  attach_function 'libusb_get_max_iso_packet_size', [:pointer, :uint8], :int
450
+ # int API_EXPORTED libusb_get_max_alt_packet_size(libusb_device *dev, int interface_number, int alternate_setting, unsigned char endpoint)
451
+ try_attach_function 'libusb_get_max_alt_packet_size', [:pointer, :int, :int, :uchar], :int
351
452
 
352
453
  try_attach_function 'libusb_get_ss_endpoint_companion_descriptor', [:pointer, :pointer, :pointer], :int
353
454
  try_attach_function 'libusb_free_ss_endpoint_companion_descriptor', [:pointer], :void
@@ -360,7 +461,11 @@ module LIBUSB
360
461
  try_attach_function 'libusb_free_ss_usb_device_capability_descriptor', [:pointer], :void
361
462
  try_attach_function 'libusb_get_container_id_descriptor', [:libusb_context, :pointer, :pointer], :int
362
463
  try_attach_function 'libusb_free_container_id_descriptor', [:pointer], :void
464
+ try_attach_function 'libusb_get_platform_descriptor', [:libusb_context, :pointer, :pointer], :int
465
+ try_attach_function 'libusb_free_platform_descriptor', [:pointer], :void
363
466
 
467
+ # int LIBUSB_CALL libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle);
468
+ try_attach_function 'libusb_wrap_sys_device', [:libusb_context, :intptr_t, :pointer], :int
364
469
  attach_function 'libusb_open', [:pointer, :pointer], :int
365
470
  attach_function 'libusb_close', [:pointer], :void
366
471
  attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
@@ -431,7 +536,7 @@ module LIBUSB
431
536
  :wLength, :uint16
432
537
  end
433
538
 
434
- class Transfer < FFI::ManagedStruct
539
+ class Transfer < FFI::Struct
435
540
  layout :dev_handle, :libusb_device_handle,
436
541
  :flags, :uint8,
437
542
  :endpoint, :uchar,
@@ -445,8 +550,19 @@ module LIBUSB
445
550
  :buffer, :pointer,
446
551
  :num_iso_packets, :int
447
552
 
448
- def self.release(ptr)
449
- Call.libusb_free_transfer(ptr)
553
+ def initialize(*)
554
+ super
555
+
556
+ ptr = pointer
557
+ def ptr.free_struct(id)
558
+ Call.libusb_free_transfer(self)
559
+ return unless @ctx
560
+ @ctx.unref_context
561
+ end
562
+ # The ctx pointer is not yet assigned.
563
+ # It happens at LIBUSB::Transfer#dev_handle= later on.
564
+ ptr.instance_variable_set(:@ctx, nil)
565
+ ObjectSpace.define_finalizer(self, ptr.method(:free_struct))
450
566
  end
451
567
  end
452
568
 
@@ -16,8 +16,9 @@
16
16
  require 'libusb/call'
17
17
 
18
18
  module LIBUSB
19
- class Configuration < FFI::ManagedStruct
19
+ class Configuration < FFI::Struct
20
20
  include Comparable
21
+ include ContextReference
21
22
 
22
23
  layout :bLength, :uint8,
23
24
  :bDescriptorType, :uint8,
@@ -108,10 +109,8 @@ module LIBUSB
108
109
  def initialize(device, *args)
109
110
  @device = device
110
111
  super(*args)
111
- end
112
112
 
113
- def self.release(ptr)
114
- Call.libusb_free_config_descriptor(ptr)
113
+ register_context(device.context.instance_variable_get(:@ctx), :libusb_free_config_descriptor)
115
114
  end
116
115
 
117
116
  # @return [Device] the device this configuration belongs to.
@@ -34,6 +34,7 @@ module LIBUSB
34
34
  Call::HotplugEvents,
35
35
  Call::HotplugFlags,
36
36
  Call::LogLevels,
37
+ Call::LogCbMode,
37
38
  Call::Options,
38
39
  ].each do |enum|
39
40
  enum.to_h.each{|k,v| const_set(k,v) }
@@ -52,6 +53,9 @@ module LIBUSB
52
53
  end
53
54
  end
54
55
 
56
+ class RemainingReferencesError < Error
57
+ end
58
+
55
59
  # @private
56
60
  ErrorClassForResult = {}
57
61
 
@@ -95,23 +95,87 @@ module LIBUSB
95
95
  end
96
96
  end
97
97
 
98
-
99
98
  # Initialize libusb context.
100
- def initialize
99
+ #
100
+ # @param [Hash{Call::Options => Object}] options Options are available since libusb-1.0.27
101
+ # @option options [Integer, Symbol] :OPTION_LOG_LEVEL The log Level as a Integer or Symbol. See Call::LogLevels
102
+ # @option options [nil] :OPTION_USE_USBDK Enable the use of USBDK driver. Pass a +nil+ as value like so: +OPTION_USE_USBDK: nil+
103
+ # @option options [nil] :OPTION_NO_DEVICE_DISCOVERY Disable device discovery for use with libusb_wrap_sys_device(). Pass a +nil+ as value like so: +OPTION_NO_DEVICE_DISCOVERY: nil+
104
+ # @option options [Proc] :OPTION_LOG_CB Set a context related log callback Proc. It is called with parameters (context, level, logstring).
105
+ def initialize(options={})
101
106
  m = FFI::MemoryPointer.new :pointer
102
- res = Call.libusb_init(m)
103
- LIBUSB.raise_error res, "in libusb_init" if res!=0
107
+ if options.empty?
108
+ res = Call.libusb_init(m)
109
+ LIBUSB.raise_error res, "in libusb_init" if res!=0
110
+ else
111
+ raise ArgumentError, "options require libusb-1.0.27+" unless Call.respond_to?(:libusb_init_context)
112
+ i_opts = options.size
113
+ p_opts = FFI::MemoryPointer.new(Call::InitOption, i_opts)
114
+ options.each_with_index do |(k, v), i|
115
+ opt = Call::InitOption.new(p_opts + i * Call::InitOption.size)
116
+ opt[:option] = k
117
+
118
+ ffitype, ffival = LIBUSB.send(:option_args_to_ffi, k, Array(v), self)
119
+ case ffitype
120
+ when NilClass then nil
121
+ when :libusb_log_level then
122
+ opt[:value][:ival] = ffival
123
+ when :libusb_log_cb then
124
+ opt[:value][:log_cbval] = ffival
125
+ else raise ArgumentError, "internal error: unexpected ffitype: #{ffitype.inspect}"
126
+ end
127
+ end
128
+ res = Call.libusb_init_context(m, p_opts, i_opts)
129
+ LIBUSB.raise_error res, "in libusb_init_context" if res!=0
130
+ end
104
131
  @ctx = m.read_pointer
105
132
  @on_pollfd_added = nil
106
133
  @on_pollfd_removed = nil
107
134
  @hotplug_callbacks = {}
135
+
136
+ def @ctx.free_context(id)
137
+ @free_context = true
138
+ if @refs == 0
139
+ # puts "final libusb_exit #{to_i} #{id} #{caller[0]}"
140
+ if id # Is Context is about to be garbage collected?
141
+ # In GC mode there's no way to call the registered collbacks, since they are GC'ed as well.
142
+ # So disable callbacks now.
143
+ Call.libusb_set_log_cb(self, nil, LOG_CB_CONTEXT)
144
+ Call.libusb_set_pollfd_notifiers(self, nil, nil, nil)
145
+ end
146
+ Call.libusb_exit(self)
147
+ @refs = nil
148
+ end
149
+ end
150
+ def @ctx.ref_context
151
+ @refs += 1
152
+ # puts "ref_context #{to_i} #{@refs} #{caller[1]}"
153
+ self
154
+ end
155
+ def @ctx.unref_context
156
+ @refs -= 1
157
+ # puts "unref_context #{to_i} #{@refs}"
158
+ raise "more unref_context than ref_context" if @refs < 0
159
+ free_context(true) if @refs == 0 && @free_context
160
+ self
161
+ end
162
+ def @ctx.setref_context
163
+ @refs = 0
164
+ @free_context = false
165
+ end
166
+ def @ctx.refs
167
+ @refs
168
+ end
169
+ @ctx.setref_context
170
+ ObjectSpace.define_finalizer(self, @ctx.method(:free_context))
108
171
  end
109
172
 
110
173
  # Deinitialize libusb.
111
174
  #
112
175
  # Should be called after closing all open devices and before your application terminates.
113
176
  def exit
114
- Call.libusb_exit(@ctx)
177
+ raise RemainingReferencesError, "#{@ctx.refs} remaining references to LIBUSB::Context" if @ctx.refs.to_i > 0
178
+ @ctx.free_context nil
115
179
  end
116
180
 
117
181
  # @deprecated Use {Context#set_option} instead using the +:OPTION_LOG_LEVEL+ option.
@@ -119,30 +183,37 @@ module LIBUSB
119
183
  Call.libusb_set_debug(@ctx, level)
120
184
  end
121
185
 
122
- def expect_option_args(exp, is)
123
- raise ArgumentError, "wrong number of arguments (given #{is+1}, expected #{exp+1})" if is != exp
186
+ private def wrap_log_cb(block, mode)
187
+ if block
188
+ cb_proc = proc do |p_ctx, lev, str|
189
+ ctx = case p_ctx
190
+ when FFI::Pointer::NULL then nil
191
+ when @ctx then self
192
+ else p_ctx.to_i
193
+ end
194
+ block.call(ctx, lev, str)
195
+ end
196
+ end
197
+
198
+ # Avoid garbage collection of the proc, since only the function pointer is given to libusb
199
+ if Call::LogCbMode.to_native(mode, nil) & LOG_CB_GLOBAL != 0
200
+ @@log_cb_proc = cb_proc
201
+ end
202
+ if Call::LogCbMode.to_native(mode, nil) & LOG_CB_CONTEXT != 0
203
+ @log_cb_proc = cb_proc
204
+ end
205
+ cb_proc
124
206
  end
125
- private :expect_option_args
126
207
 
127
- # Set a libusb option from the {Call::Options option list}.
208
+ # Set a context related libusb option from the {Call::Options option list}.
128
209
  #
129
210
  # @param [Symbol, Fixnum] option
130
211
  # @param args Zero or more arguments depending on +option+
212
+ # @see set_options
131
213
  def set_option(option, *args)
132
214
  if Call.respond_to?(:libusb_set_option)
133
215
  # Available since libusb-1.0.22
134
-
135
- ffi_args = case option
136
- when :OPTION_LOG_LEVEL, LIBUSB::OPTION_LOG_LEVEL
137
- expect_option_args(1, args.length)
138
- [:libusb_log_level, args[0]]
139
- when :OPTION_USE_USBDK, LIBUSB::OPTION_USE_USBDK
140
- expect_option_args(0, args.length)
141
- []
142
- else
143
- raise ArgumentError, "unknown option #{option.inspect}"
144
- end
145
-
216
+ ffi_args = LIBUSB.send(:option_args_to_ffi, option, args, self)
146
217
  res = Call.libusb_set_option(@ctx, option, *ffi_args)
147
218
  LIBUSB.raise_error res, "in libusb_set_option" if res<0
148
219
 
@@ -154,6 +225,69 @@ module LIBUSB
154
225
  end
155
226
  end
156
227
 
228
+ # Convenience function to set context related options in the libusb library.
229
+ #
230
+ # Use this function to configure any number of options within the library.
231
+ # It takes a Hash the same way as given to {Context.initialize}.
232
+ # See also {Call::Options option list}.
233
+ #
234
+ # @param [Hash{Call::Options => Object}] options Option hash
235
+ # @see set_option
236
+ def set_options(options={})
237
+ options.each do |k, v|
238
+ set_option(k, *Array(v))
239
+ end
240
+ end
241
+
242
+ if Call.respond_to?(:libusb_set_log_cb)
243
+ # Set log handler.
244
+ #
245
+ # libusb will redirect its log messages to the provided method block.
246
+ # libusb supports redirection of per context and global log messages.
247
+ # Log messages sent to the context will be sent to the global log handler too.
248
+ #
249
+ # If libusb is compiled without message logging or USE_SYSTEM_LOGGING_FACILITY
250
+ # is defined then global callback function will never be called.
251
+ # If ENABLE_DEBUG_LOGGING is defined then per context callback function will
252
+ # never be called.
253
+ #
254
+ # To disable the log callback, execute set_log_cb without a block.
255
+ #
256
+ # Available since libusb-1.0.23, LIBUSB_API_VERSION >= 0x01000107
257
+ #
258
+ # @param [Symbol, Integer] mode mode of callback function operation.
259
+ # Several modes can be selected for a single callback function, see Call::LogCbMode for a description.
260
+ #
261
+ # @yieldparam [Context, nil] context The context which is related to the log message, or +nil+ if it is a global log message.
262
+ # @yieldparam [Symbol] level The log level, see Call::LogLevels for a description.
263
+ # @yieldparam [String] str The log message.
264
+ #
265
+ # @see Call::LogCbMode
266
+ #
267
+ def set_log_cb(mode, &block)
268
+ cb_proc = wrap_log_cb(block, mode)
269
+ Call.libusb_set_log_cb(@ctx, cb_proc, mode)
270
+ self
271
+ end
272
+ end
273
+
274
+ if Call.respond_to?(:libusb_wrap_sys_device)
275
+ def wrap_sys_device(dev_io)
276
+ dev_io = dev_io.is_a?(IO) ? dev_io.fileno : dev_io
277
+
278
+ ppHandle = FFI::MemoryPointer.new :pointer
279
+ res = Call.libusb_wrap_sys_device(@ctx, dev_io, ppHandle)
280
+ LIBUSB.raise_error res, "in libusb_wrap_sys_device" if res!=0
281
+ handle = DevHandle.new self, ppHandle.read_pointer
282
+ return handle unless block_given?
283
+ begin
284
+ yield handle
285
+ ensure
286
+ handle.close
287
+ end
288
+ end
289
+ end
290
+
157
291
  def device_list
158
292
  pppDevs = FFI::MemoryPointer.new :pointer
159
293
  size = Call.libusb_get_device_list(@ctx, pppDevs)
@@ -327,14 +461,18 @@ module LIBUSB
327
461
  # This block will be invoked for every new file descriptor that
328
462
  # libusb uses as an event source.
329
463
  #
464
+ # To disable the notification callback, execute on_pollfd_added without a block.
465
+ #
330
466
  # Note that file descriptors may have been added even before you register these
331
467
  # notifiers (e.g. at {Context#initialize} time).
332
468
  #
333
469
  # @yieldparam [Pollfd] pollfd The added file descriptor is yielded to the block
334
470
  def on_pollfd_added &block
335
- @on_pollfd_added = proc do |fd, events, _|
336
- pollfd = Pollfd.new fd, events
337
- block.call pollfd
471
+ @on_pollfd_added = if block
472
+ proc do |fd, events, _|
473
+ pollfd = Pollfd.new fd, events
474
+ block.call pollfd
475
+ end
338
476
  end
339
477
  Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
340
478
  end
@@ -344,6 +482,8 @@ module LIBUSB
344
482
  # This block will be invoked for every removed file descriptor that
345
483
  # libusb uses as an event source.
346
484
  #
485
+ # To disable the notification callback, execute on_pollfd_removed without a block.
486
+ #
347
487
  # Note that the removal notifier may be called during {Context#exit}
348
488
  # (e.g. when it is closing file descriptors that were opened and added to the poll
349
489
  # set at {Context#initialize} time). If you don't want this, overwrite the notifier
@@ -351,9 +491,11 @@ module LIBUSB
351
491
  #
352
492
  # @yieldparam [Pollfd] pollfd The removed file descriptor is yielded to the block
353
493
  def on_pollfd_removed &block
354
- @on_pollfd_removed = proc do |fd, _|
355
- pollfd = Pollfd.new fd
356
- block.call pollfd
494
+ @on_pollfd_removed = if block
495
+ proc do |fd, _|
496
+ pollfd = Pollfd.new fd
497
+ block.call pollfd
498
+ end
357
499
  end
358
500
  Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
359
501
  end
@@ -393,19 +535,18 @@ module LIBUSB
393
535
  # @yieldparam [Symbol] event a {Call::HotplugEvents HotplugEvents} symbol
394
536
  # @yieldreturn [Symbol] +:finish+ to deregister the callback, +:repeat+ to receive additional events
395
537
  # @raise [ArgumentError, LIBUSB::Error] in case of failure
396
- def on_hotplug_event(args={}, &block)
397
- events = args.delete(:events) || (HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT)
398
- flags = args.delete(:flags) || 0
399
- vendor_id = args.delete(:vendor_id) || HOTPLUG_MATCH_ANY
400
- product_id = args.delete(:product_id) || HOTPLUG_MATCH_ANY
401
- dev_class = args.delete(:dev_class) || HOTPLUG_MATCH_ANY
402
- raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
538
+ def on_hotplug_event(events: HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT,
539
+ flags: 0,
540
+ vendor_id: HOTPLUG_MATCH_ANY,
541
+ product_id: HOTPLUG_MATCH_ANY,
542
+ dev_class: HOTPLUG_MATCH_ANY,
543
+ &block)
403
544
 
404
545
  handle = HotplugCallback.new self, @ctx, @hotplug_callbacks
405
546
 
406
547
  block2 = proc do |ctx, pDevice, event, _user_data|
407
548
  raise "internal error: unexpected context" unless @ctx==ctx
408
- dev = Device.new @ctx, pDevice
549
+ dev = Device.new self, pDevice
409
550
 
410
551
  blres = block.call(dev, event)
411
552
 
@@ -0,0 +1,38 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module LIBUSB
17
+ module ContextReference
18
+ def register_context(ctx, free_sym)
19
+ ptr = pointer
20
+ def ptr.free_struct(id)
21
+ return unless @ctx
22
+ Call.send(@free_sym, self)
23
+ @ctx.unref_context
24
+ end
25
+ ptr.instance_variable_set(:@free_sym, free_sym)
26
+ ptr.instance_variable_set(:@ctx, ctx.ref_context)
27
+ ObjectSpace.define_finalizer(self, ptr.method(:free_struct))
28
+ end
29
+
30
+ def free
31
+ ptr = pointer
32
+ ptr.free_struct nil
33
+ ptr.instance_variable_set(:@ctx, nil)
34
+ end
35
+ end
36
+
37
+ private_constant :ContextReference
38
+ end
@@ -1,7 +1,7 @@
1
1
  module LIBUSB
2
- LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.22'
2
+ LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.27'
3
3
  LIBUSB_SOURCE_URI = "https://github.com/libusb/libusb/releases/download/v#{LIBUSB_VERSION}/libusb-#{LIBUSB_VERSION}.tar.bz2"
4
- LIBUSB_SOURCE_SHA1 = '10116aa265aac4273a0c894faa089370262ec0dc'
4
+ LIBUSB_SOURCE_SHA256 = 'ffaa41d741a8a3bee244ac8e54a72ea05bf2879663c098c82fc5757853441575'
5
5
 
6
6
  MINI_PORTILE_VERSION = '~> 2.1'
7
7
  end