@@ -7,7 +7,7 @@ use std::{
7
7
8
8
use libc:: { c_int, size_t, wchar_t} ;
9
9
10
- use crate :: { ffi, DeviceInfo , HidDeviceBackendBase , HidError , HidResult , WcharString } ;
10
+ use crate :: { ffi, DeviceInfo , Event , HidDeviceBackendBase , HidError , HidResult , WcharString } ;
11
11
12
12
#[ cfg( target_os = "macos" ) ]
13
13
mod macos;
@@ -39,6 +39,75 @@ impl HidApiBackend {
39
39
Ok ( device_vector)
40
40
}
41
41
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
+
42
111
pub fn open ( vid : u16 , pid : u16 ) -> HidResult < HidDevice > {
43
112
let device = unsafe { ffi:: hid_open ( vid, pid, std:: ptr:: null ( ) ) } ;
44
113
0 commit comments