@@ -7,7 +7,7 @@ use std::{
77
88use libc:: { c_int, size_t, wchar_t} ;
99
10- use crate :: { ffi, DeviceInfo , HidDeviceBackendBase , HidError , HidResult , WcharString } ;
10+ use crate :: { ffi, DeviceInfo , Event , HidDeviceBackendBase , HidError , HidResult , WcharString } ;
1111
1212#[ cfg( target_os = "macos" ) ]
1313mod macos;
@@ -39,6 +39,75 @@ impl HidApiBackend {
3939 Ok ( device_vector)
4040 }
4141
42+ pub fn monitor_hid_device_info ( ) -> HidResult < impl Iterator < Item = Event > > {
43+ type Sender = std:: sync:: mpsc:: Sender :: < ( ffi:: HidHotplugEvent , HidResult < DeviceInfo > ) > ;
44+ type Receiver = std:: sync:: mpsc:: Receiver :: < ( ffi:: HidHotplugEvent , HidResult < DeviceInfo > ) > ;
45+
46+ struct Iter {
47+ handle : ffi:: HidHotplugCallbackHandle ,
48+ tx : * mut Sender ,
49+ rx : Receiver ,
50+ }
51+
52+ impl Iterator for Iter {
53+ type Item = Event ;
54+
55+ fn next ( & mut self ) -> Option < Self :: Item > {
56+ loop {
57+ break Some ( match self . rx . recv ( ) . expect ( "the sender shouldn't be dropped" ) {
58+ ( ffi:: HID_API_HOTPLUG_EVENT_DEVICE_ARRIVED , Ok ( info) ) => Event :: Add ( info) ,
59+ _ => continue ,
60+ } )
61+ }
62+ }
63+ }
64+
65+ impl Drop for Iter {
66+ fn drop ( & mut self ) {
67+ unsafe { ffi:: hid_hotplug_deregister_callback ( self . handle ) } ;
68+ unsafe { drop ( Box :: from_raw ( self . tx ) ) } ;
69+ }
70+ }
71+
72+ let mut handle: ffi:: HidHotplugCallbackHandle = 0 ;
73+
74+ let ( tx, mut rx) = std:: sync:: mpsc:: channel ( ) ;
75+ let tx = Box :: into_raw ( Box :: new ( tx) ) ;
76+
77+ let vendor_id = 0 ;
78+ let product_id = 0 ;
79+ let events = ffi:: HID_API_HOTPLUG_EVENT_DEVICE_ARRIVED ;
80+ let flags = 0 ;
81+
82+ extern "C" fn callback ( _handle : ffi:: HidHotplugCallbackHandle , info : * mut ffi:: HidDeviceInfo , event : ffi:: HidHotplugEvent , user_data : * mut libc:: c_void ) -> libc:: c_int {
83+ let tx = user_data. cast :: < Sender > ( ) ;
84+ let _ = unsafe { & * tx } . send ( ( event, unsafe { conv_hid_device_info ( info) } ) ) ;
85+ 0
86+ }
87+
88+ let user_data = tx. cast :: < libc:: c_void > ( ) ;
89+ let handle_ptr = std:: ptr:: addr_of_mut!( handle) ;
90+
91+ let result = unsafe { ffi:: hid_hotplug_register_callback (
92+ vendor_id,
93+ product_id,
94+ events,
95+ flags,
96+ callback,
97+ user_data,
98+ handle_ptr,
99+ ) } ;
100+
101+ if result == 0 {
102+ Ok ( Iter { handle, tx, rx } )
103+ } else {
104+ match Self :: check_error ( ) {
105+ Ok ( err) => Err ( err) ,
106+ Err ( e) => Err ( e) ,
107+ }
108+ }
109+ }
110+
42111 pub fn open ( vid : u16 , pid : u16 ) -> HidResult < HidDevice > {
43112 let device = unsafe { ffi:: hid_open ( vid, pid, std:: ptr:: null ( ) ) } ;
44113
0 commit comments