Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
hid.c File Reference
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/usb/USBSpec.h>
#include <CoreFoundation/CoreFoundation.h>
#include <wchar.h>
#include <locale.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <dlfcn.h>
#include "hidapi.h"
+ Include dependency graph for hid.c:

Go to the source code of this file.

Classes

struct  pthread_barrier
 
struct  input_report
 
struct  hid_device_
 

Macros

#define BUF_LEN   256
 

Typedefs

typedef int pthread_barrierattr_t
 
typedef struct pthread_barrier pthread_barrier_t
 

Functions

static int pthread_barrier_init (pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
 
static int pthread_barrier_destroy (pthread_barrier_t *barrier)
 
static int pthread_barrier_wait (pthread_barrier_t *barrier)
 
static int return_data (hid_device *dev, unsigned char *data, size_t length)
 
static hid_devicenew_hid_device (void)
 
static void free_hid_device (hid_device *dev)
 
static int32_t get_int_property (IOHIDDeviceRef device, CFStringRef key)
 
static unsigned short get_vendor_id (IOHIDDeviceRef device)
 
static unsigned short get_product_id (IOHIDDeviceRef device)
 
static int32_t get_max_report_length (IOHIDDeviceRef device)
 
static int get_string_property (IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len)
 
static int get_serial_number (IOHIDDeviceRef device, wchar_t *buf, size_t len)
 
static int get_manufacturer_string (IOHIDDeviceRef device, wchar_t *buf, size_t len)
 
static int get_product_string (IOHIDDeviceRef device, wchar_t *buf, size_t len)
 
static wchar_t * dup_wcs (const wchar_t *s)
 
static io_service_t hidapi_IOHIDDeviceGetService (IOHIDDeviceRef device)
 
static int init_hid_manager (void)
 
int HID_API_EXPORT hid_init (void)
 Initialize the HIDAPI library.
 
int HID_API_EXPORT hid_exit (void)
 Finalize the HIDAPI library.
 
static void process_pending_events (void)
 
struct hid_device_info HID_API_EXPORThid_enumerate (unsigned short vendor_id, unsigned short product_id)
 Enumerate the HID Devices.
 
void HID_API_EXPORT hid_free_enumeration (struct hid_device_info *devs)
 Free an enumeration Linked List.
 
hid_device *HID_API_EXPORT hid_open (unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
 Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally a serial number.
 
static void hid_device_removal_callback (void *context, IOReturn result, void *sender)
 
static void hid_report_callback (void *context, IOReturn result, void *sender, IOHIDReportType report_type, uint32_t report_id, uint8_t *report, CFIndex report_length)
 
static void perform_signal_callback (void *context)
 
static voidread_thread (void *param)
 
hid_device *HID_API_EXPORT hid_open_path (const char *path)
 Open a HID device by its path name.
 
static int set_report (hid_device *dev, IOHIDReportType type, const unsigned char *data, size_t length)
 
int HID_API_EXPORT hid_write (hid_device *dev, const unsigned char *data, size_t length)
 Write an Output report to a HID device.
 
static int cond_wait (const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex)
 
static int cond_timedwait (const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
 
int HID_API_EXPORT hid_read_timeout (hid_device *dev, unsigned char *data, size_t length, int milliseconds)
 Read an Input report from a HID device with timeout.
 
int HID_API_EXPORT hid_read (hid_device *dev, unsigned char *data, size_t length)
 Read an Input report from a HID device.
 
int HID_API_EXPORT hid_set_nonblocking (hid_device *dev, int nonblock)
 Set the device handle to be non-blocking.
 
int HID_API_EXPORT hid_send_feature_report (hid_device *dev, const unsigned char *data, size_t length)
 Send a Feature report to the device.
 
int HID_API_EXPORT hid_get_feature_report (hid_device *dev, unsigned char *data, size_t length)
 Get a feature report from a HID device.
 
void HID_API_EXPORT hid_close (hid_device *dev)
 Close a HID device.
 
int HID_API_EXPORT_CALL hid_get_manufacturer_string (hid_device *dev, wchar_t *string, size_t maxlen)
 Get The Manufacturer String from a HID device.
 
int HID_API_EXPORT_CALL hid_get_product_string (hid_device *dev, wchar_t *string, size_t maxlen)
 Get The Product String from a HID device.
 
int HID_API_EXPORT_CALL hid_get_serial_number_string (hid_device *dev, wchar_t *string, size_t maxlen)
 Get The Serial Number String from a HID device.
 
int HID_API_EXPORT_CALL hid_get_indexed_string (hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
 Get a string from a HID device, based on its string index.
 
HID_API_EXPORT const wchar_t *HID_API_CALL hid_error (hid_device *dev)
 Get a string describing the last error which occurred.
 

Variables

static IOHIDManagerRef hid_mgr = 0x0
 

Class Documentation

◆ pthread_barrier

struct pthread_barrier
Class Members
pthread_cond_t cond
int count
pthread_mutex_t mutex
int trip_count

◆ input_report

struct input_report
+ Collaboration diagram for input_report:
Class Members
uint8_t * data
size_t len
struct input_report * next

◆ hid_device_

struct hid_device_
+ Collaboration diagram for hid_device_:
Class Members
pthread_barrier_t barrier
int blocking
BOOL blocking
pthread_cond_t condition
int device_handle
IOHIDDeviceRef device_handle
HANDLE device_handle
int disconnected
uint8_t * input_report_buf
size_t input_report_length
struct input_report * input_reports
DWORD last_error_num
void * last_error_str
CFIndex max_input_report_len
pthread_mutex_t mutex
OVERLAPPED ol
USHORT output_report_length
char * read_buf
BOOL read_pending
CFRunLoopRef run_loop
CFStringRef run_loop_mode
pthread_barrier_t shutdown_barrier
int shutdown_thread
CFRunLoopSourceRef source
pthread_t thread
int uses_numbered_reports

Macro Definition Documentation

◆ BUF_LEN

#define BUF_LEN   256

Typedef Documentation

◆ pthread_barrier_t

◆ pthread_barrierattr_t

typedef int pthread_barrierattr_t

Function Documentation

◆ cond_timedwait()

static int cond_timedwait ( const hid_device dev,
pthread_cond_t *  cond,
pthread_mutex_t *  mutex,
const struct timespec *  abstime 
)
static
841{
842 while (!dev->input_reports) {
843 int res = pthread_cond_timedwait(cond, mutex, abstime);
844 if (res != 0)
845 return res;
846
847 /* A res of 0 means we may have been signaled or it may
848 be a spurious wakeup. Check to see that there's acutally
849 data in the queue before returning, and if not, go back
850 to sleep. See the pthread_cond_timedwait() man page for
851 details. */
852
853 if (dev->shutdown_thread || dev->disconnected)
854 return -1;
855 }
856
857 return 0;
858
859}
struct input_report * input_reports
Definition hid.c:116
int shutdown_thread
Definition hid.c:123
int disconnected
Definition hid.c:110

References hid_device_::disconnected, hid_device_::input_reports, and hid_device_::shutdown_thread.

Referenced by hid_read_timeout().

+ Here is the caller graph for this function:

◆ cond_wait()

static int cond_wait ( const hid_device dev,
pthread_cond_t *  cond,
pthread_mutex_t *  mutex 
)
static
821{
822 while (!dev->input_reports) {
823 int res = pthread_cond_wait(cond, mutex);
824 if (res != 0)
825 return res;
826
827 /* A res of 0 means we may have been signaled or it may
828 be a spurious wakeup. Check to see that there's acutally
829 data in the queue before returning, and if not, go back
830 to sleep. See the pthread_cond_timedwait() man page for
831 details. */
832
833 if (dev->shutdown_thread || dev->disconnected)
834 return -1;
835 }
836
837 return 0;
838}

References hid_device_::disconnected, hid_device_::input_reports, and hid_device_::shutdown_thread.

Referenced by hid_read_timeout().

+ Here is the caller graph for this function:

◆ dup_wcs()

static wchar_t * dup_wcs ( const wchar_t *  s)
static
283{
284 size_t len = wcslen(s);
285 wchar_t *ret = malloc((len+1)*sizeof(wchar_t));
286 wcscpy(ret, s);
287
288 return ret;
289}
void * malloc(YYSIZE_T)

References input_report::len, and malloc().

Referenced by hid_enumerate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ free_hid_device()

static void free_hid_device ( hid_device dev)
static
150{
151 if (!dev)
152 return;
153
154 /* Delete any input reports still left over. */
155 struct input_report *rpt = dev->input_reports;
156 while (rpt) {
157 struct input_report *next = rpt->next;
158 free(rpt->data);
159 free(rpt);
160 rpt = next;
161 }
162
163 /* Free the string and the report buffer. The check for NULL
164 is necessary here as CFRelease() doesn't handle NULL like
165 free() and others do. */
166 if (dev->run_loop_mode)
167 CFRelease(dev->run_loop_mode);
168 if (dev->source)
169 CFRelease(dev->source);
171
172 /* Clean up the thread objects */
175 pthread_cond_destroy(&dev->condition);
176 pthread_mutex_destroy(&dev->mutex);
177
178 /* Free the structure itself. */
179 free(dev);
180}
void free(void *)
struct input_report * next
Definition hid.c:103
uint8_t * data
Definition hid.c:101
static int pthread_barrier_destroy(pthread_barrier_t *barrier)
Definition hid.c:71
Definition hid.c:100
pthread_barrier_t barrier
Definition hid.c:121
CFRunLoopSourceRef source
Definition hid.c:113
pthread_barrier_t shutdown_barrier
Definition hid.c:122
pthread_mutex_t mutex
Definition hid.c:119
pthread_cond_t condition
Definition hid.c:120
uint8_t * input_report_buf
Definition hid.c:114
CFStringRef run_loop_mode
Definition hid.c:111

References hid_device_::barrier, hid_device_::condition, input_report::data, free(), hid_device_::input_report_buf, hid_device_::input_reports, hid_device_::mutex, input_report::next, pthread_barrier_destroy(), hid_device_::run_loop_mode, hid_device_::shutdown_barrier, and hid_device_::source.

+ Here is the call graph for this function:

◆ get_int_property()

static int32_t get_int_property ( IOHIDDeviceRef  device,
CFStringRef  key 
)
static
194{
195 CFTypeRef ref;
196 int32_t value;
197
198 ref = IOHIDDeviceGetProperty(device, key);
199 if (ref) {
200 if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
201 CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &value);
202 return value;
203 }
204 }
205 return 0;
206}
__int32 int32_t
Definition unistd.h:75

Referenced by get_max_report_length(), get_product_id(), get_vendor_id(), and hid_enumerate().

+ Here is the caller graph for this function:

◆ get_manufacturer_string()

static int get_manufacturer_string ( IOHIDDeviceRef  device,
wchar_t *  buf,
size_t  len 
)
static
271{
272 return get_string_property(device, CFSTR(kIOHIDManufacturerKey), buf, len);
273}
static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len)
Definition hid.c:223

References get_string_property(), and input_report::len.

Referenced by hid_enumerate(), and hid_get_manufacturer_string().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_max_report_length()

static int32_t get_max_report_length ( IOHIDDeviceRef  device)
static
219{
220 return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey));
221}
static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
Definition hid.c:193

References get_int_property().

Referenced by hid_open_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_product_id()

static unsigned short get_product_id ( IOHIDDeviceRef  device)
static
214{
215 return get_int_property(device, CFSTR(kIOHIDProductIDKey));
216}

References get_int_property().

Referenced by hid_enumerate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_product_string()

static int get_product_string ( IOHIDDeviceRef  device,
wchar_t *  buf,
size_t  len 
)
static
276{
277 return get_string_property(device, CFSTR(kIOHIDProductKey), buf, len);
278}

References get_string_property(), and input_report::len.

Referenced by hid_enumerate(), and hid_get_product_string().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_serial_number()

static int get_serial_number ( IOHIDDeviceRef  device,
wchar_t *  buf,
size_t  len 
)
static
266{
267 return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
268}

References get_string_property(), and input_report::len.

Referenced by hid_enumerate(), and hid_get_serial_number_string().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_string_property()

static int get_string_property ( IOHIDDeviceRef  device,
CFStringRef  prop,
wchar_t *  buf,
size_t  len 
)
static
224{
225 CFStringRef str;
226
227 if (!len)
228 return 0;
229
230 str = IOHIDDeviceGetProperty(device, prop);
231
232 buf[0] = 0;
233
234 if (str) {
235 CFIndex str_len = CFStringGetLength(str);
236 CFRange range;
237 CFIndex used_buf_len;
238 CFIndex chars_copied;
239
240 len --;
241
242 range.location = 0;
243 range.length = ((size_t)str_len > len)? len: (size_t)str_len;
244 chars_copied = CFStringGetBytes(str,
245 range,
246 kCFStringEncodingUTF32LE,
247 (char)'?',
248 FALSE,
249 (UInt8*)buf,
250 len * sizeof(wchar_t),
251 &used_buf_len);
252
253 if (chars_copied == len)
254 buf[len] = 0; /* len is decremented above */
255 else
256 buf[chars_copied] = 0;
257
258 return 0;
259 }
260 else
261 return -1;
262
263}
#define FALSE
Definition mesh.c:45
auto range(Cont &&cont)
Definition libslic3r.h:356

References FALSE, and input_report::len.

Referenced by get_manufacturer_string(), get_product_string(), and get_serial_number().

+ Here is the caller graph for this function:

◆ get_vendor_id()

static unsigned short get_vendor_id ( IOHIDDeviceRef  device)
static
209{
210 return get_int_property(device, CFSTR(kIOHIDVendorIDKey));
211}

References get_int_property().

Referenced by hid_enumerate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hid_device_removal_callback()

static void hid_device_removal_callback ( void context,
IOReturn  result,
void sender 
)
static
556{
557 /* Stop the Run Loop for this device. */
558 hid_device *d = context;
559
560 d->disconnected = 1;
561 CFRunLoopStop(d->run_loop);
562}
Definition hid.c:201

Referenced by hid_open_path().

+ Here is the caller graph for this function:

◆ hid_report_callback()

static void hid_report_callback ( void context,
IOReturn  result,
void sender,
IOHIDReportType  report_type,
uint32_t  report_id,
uint8_t report,
CFIndex  report_length 
)
static
570{
571 struct input_report *rpt;
572 hid_device *dev = context;
573
574 /* Make a new Input Report object */
575 rpt = calloc(1, sizeof(struct input_report));
576 rpt->data = calloc(1, report_length);
577 memcpy(rpt->data, report, report_length);
578 rpt->len = report_length;
579 rpt->next = NULL;
580
581 /* Lock this section */
582 pthread_mutex_lock(&dev->mutex);
583
584 /* Attach the new report object to the end of the list. */
585 if (dev->input_reports == NULL) {
586 /* The list is empty. Put it at the root. */
587 dev->input_reports = rpt;
588 }
589 else {
590 /* Find the end of the list and attach. */
591 struct input_report *cur = dev->input_reports;
592 int num_queued = 0;
593 while (cur->next != NULL) {
594 cur = cur->next;
595 num_queued++;
596 }
597 cur->next = rpt;
598
599 /* Pop one off if we've reached 30 in the queue. This
600 way we don't grow forever if the user never reads
601 anything from the device. */
602 if (num_queued > 30) {
603 return_data(dev, NULL, 0);
604 }
605 }
606
607 /* Signal a waiting thread that there is data. */
608 pthread_cond_signal(&dev->condition);
609
610 /* Unlock */
611 pthread_mutex_unlock(&dev->mutex);
612
613}
static int return_data(hid_device *dev, unsigned char *data, size_t length)
Definition hid.c:807
size_t len
Definition hid.c:102

References hid_device_::condition, input_report::data, hid_device_::input_reports, input_report::len, hid_device_::mutex, input_report::next, and return_data().

Referenced by hid_open_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hidapi_IOHIDDeviceGetService()

static io_service_t hidapi_IOHIDDeviceGetService ( IOHIDDeviceRef  device)
static
298{
299 static void *iokit_framework = NULL;
300 static io_service_t (*dynamic_IOHIDDeviceGetService)(IOHIDDeviceRef device) = NULL;
301
302 /* Use dlopen()/dlsym() to get a pointer to IOHIDDeviceGetService() if it exists.
303 * If any of these steps fail, dynamic_IOHIDDeviceGetService will be left NULL
304 * and the fallback method will be used.
305 */
306 if (iokit_framework == NULL) {
307 iokit_framework = dlopen("/System/Library/IOKit.framework/IOKit", RTLD_LAZY);
308
309 if (iokit_framework != NULL)
310 dynamic_IOHIDDeviceGetService = dlsym(iokit_framework, "IOHIDDeviceGetService");
311 }
312
313 if (dynamic_IOHIDDeviceGetService != NULL) {
314 /* Running on OS X 10.6 and above: IOHIDDeviceGetService() exists */
315 return dynamic_IOHIDDeviceGetService(device);
316 }
317 else
318 {
319 /* Running on OS X 10.5: IOHIDDeviceGetService() doesn't exist.
320 *
321 * Be naughty and pull the service out of the IOHIDDevice.
322 * IOHIDDevice is an opaque struct not exposed to applications, but its
323 * layout is stable through all available versions of OS X.
324 * Tested and working on OS X 10.5.8 i386, x86_64, and ppc.
325 */
326 struct IOHIDDevice_internal {
327 /* The first field of the IOHIDDevice struct is a
328 * CFRuntimeBase (which is a private CF struct).
329 *
330 * a, b, and c are the 3 fields that make up a CFRuntimeBase.
331 * See http://opensource.apple.com/source/CF/CF-476.18/CFRuntime.h
332 *
333 * The second field of the IOHIDDevice is the io_service_t we're looking for.
334 */
335 uintptr_t a;
336 uint8_t b[4];
337#if __LP64__
338 uint32_t c;
339#endif
340 io_service_t service;
341 };
342 struct IOHIDDevice_internal *tmp = (struct IOHIDDevice_internal *)device;
343
344 return tmp->service;
345 }
346}
unsigned __int32 uint32_t
Definition unistd.h:79
unsigned __int8 uint8_t
Definition unistd.h:77

Referenced by hid_enumerate().

+ Here is the caller graph for this function:

◆ init_hid_manager()

static int init_hid_manager ( void  )
static
350{
351 /* Initialize all the HID Manager Objects */
352 hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
353 if (hid_mgr) {
354 IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
355 IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
356 return 0;
357 }
358
359 return -1;
360}
static IOHIDManagerRef hid_mgr
Definition hid.c:182

References hid_mgr.

Referenced by hid_init().

+ Here is the caller graph for this function:

◆ new_hid_device()

static hid_device * new_hid_device ( void  )
static
127{
128 hid_device *dev = calloc(1, sizeof(hid_device));
129 dev->device_handle = NULL;
130 dev->blocking = 1;
131 dev->uses_numbered_reports = 0;
132 dev->disconnected = 0;
133 dev->run_loop_mode = NULL;
134 dev->run_loop = NULL;
135 dev->source = NULL;
136 dev->input_report_buf = NULL;
137 dev->input_reports = NULL;
138 dev->shutdown_thread = 0;
139
140 /* Thread objects */
141 pthread_mutex_init(&dev->mutex, NULL);
142 pthread_cond_init(&dev->condition, NULL);
143 pthread_barrier_init(&dev->barrier, NULL, 2);
145
146 return dev;
147}
static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
Definition hid.c:51
CFRunLoopRef run_loop
Definition hid.c:112
int uses_numbered_reports
Definition hid.c:204
int device_handle
Definition hid.c:202
int blocking
Definition hid.c:203

References hid_device_::barrier, hid_device_::blocking, hid_device_::condition, hid_device_::device_handle, hid_device_::disconnected, hid_device_::input_report_buf, hid_device_::input_reports, hid_device_::mutex, pthread_barrier_init(), hid_device_::run_loop, hid_device_::run_loop_mode, hid_device_::shutdown_barrier, hid_device_::shutdown_thread, hid_device_::source, and hid_device_::uses_numbered_reports.

+ Here is the call graph for this function:

◆ perform_signal_callback()

static void perform_signal_callback ( void context)
static
618{
619 hid_device *dev = context;
620 CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/
621}

References hid_device_::run_loop.

Referenced by read_thread().

+ Here is the caller graph for this function:

◆ process_pending_events()

static void process_pending_events ( void  )
static
387 {
388 SInt32 res;
389 do {
390 res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE);
391 } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut);
392}

References FALSE.

Referenced by hid_enumerate().

+ Here is the caller graph for this function:

◆ pthread_barrier_destroy()

static int pthread_barrier_destroy ( pthread_barrier_t barrier)
static
72{
73 pthread_cond_destroy(&barrier->cond);
74 pthread_mutex_destroy(&barrier->mutex);
75 return 0;
76}
pthread_cond_t cond
Definition hid.c:46
pthread_mutex_t mutex
Definition hid.c:45

References pthread_barrier::cond, and pthread_barrier::mutex.

Referenced by free_hid_device().

+ Here is the caller graph for this function:

◆ pthread_barrier_init()

static int pthread_barrier_init ( pthread_barrier_t barrier,
const pthread_barrierattr_t attr,
unsigned int  count 
)
static
52{
53 if(count == 0) {
54 errno = EINVAL;
55 return -1;
56 }
57
58 if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
59 return -1;
60 }
61 if(pthread_cond_init(&barrier->cond, 0) < 0) {
62 pthread_mutex_destroy(&barrier->mutex);
63 return -1;
64 }
65 barrier->trip_count = count;
66 barrier->count = 0;
67
68 return 0;
69}
int trip_count
Definition hid.c:48
int count
Definition hid.c:47
IGL_INLINE void count(const Eigen::SparseMatrix< XType > &X, const int dim, Eigen::SparseVector< SType > &S)
Definition count.cpp:12

References pthread_barrier::cond, pthread_barrier::count, pthread_barrier::mutex, and pthread_barrier::trip_count.

Referenced by new_hid_device().

+ Here is the caller graph for this function:

◆ pthread_barrier_wait()

static int pthread_barrier_wait ( pthread_barrier_t barrier)
static
79{
80 pthread_mutex_lock(&barrier->mutex);
81 ++(barrier->count);
82 if(barrier->count >= barrier->trip_count)
83 {
84 barrier->count = 0;
85 pthread_cond_broadcast(&barrier->cond);
86 pthread_mutex_unlock(&barrier->mutex);
87 return 1;
88 }
89 else
90 {
91 pthread_cond_wait(&barrier->cond, &(barrier->mutex));
92 pthread_mutex_unlock(&barrier->mutex);
93 return 0;
94 }
95}

References pthread_barrier::cond, pthread_barrier::count, pthread_barrier::mutex, and pthread_barrier::trip_count.

Referenced by hid_close(), hid_open_path(), and read_thread().

+ Here is the caller graph for this function:

◆ read_thread()

static void * read_thread ( void param)
static
624{
625 hid_device *dev = param;
626 SInt32 code;
627
628 /* Move the device's run loop to this thread. */
629 IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);
630
631 /* Create the RunLoopSource which is used to signal the
632 event loop to stop when hid_close() is called. */
633 CFRunLoopSourceContext ctx;
634 memset(&ctx, 0, sizeof(ctx));
635 ctx.version = 0;
636 ctx.info = dev;
637 ctx.perform = &perform_signal_callback;
638 dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx);
639 CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode);
640
641 /* Store off the Run Loop so it can be stopped from hid_close()
642 and on device disconnection. */
643 dev->run_loop = CFRunLoopGetCurrent();
644
645 /* Notify the main thread that the read thread is up and running. */
647
648 /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
649 reports into the hid_report_callback(). */
650 while (!dev->shutdown_thread && !dev->disconnected) {
651 code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
652 /* Return if the device has been disconnected */
653 if (code == kCFRunLoopRunFinished) {
654 dev->disconnected = 1;
655 break;
656 }
657
658
659 /* Break if The Run Loop returns Finished or Stopped. */
660 if (code != kCFRunLoopRunTimedOut &&
661 code != kCFRunLoopRunHandledSource) {
662 /* There was some kind of error. Setting
663 shutdown seems to make sense, but
664 there may be something else more appropriate */
665 dev->shutdown_thread = 1;
666 break;
667 }
668 }
669
670 /* Now that the read thread is stopping, Wake any threads which are
671 waiting on data (in hid_read_timeout()). Do this under a mutex to
672 make sure that a thread which is about to go to sleep waiting on
673 the condition actually will go to sleep before the condition is
674 signaled. */
675 pthread_mutex_lock(&dev->mutex);
676 pthread_cond_broadcast(&dev->condition);
677 pthread_mutex_unlock(&dev->mutex);
678
679 /* Wait here until hid_close() is called and makes it past
680 the call to CFRunLoopWakeUp(). This thread still needs to
681 be valid when that function is called on the other thread. */
683
684 return NULL;
685}
static int pthread_barrier_wait(pthread_barrier_t *barrier)
Definition hid.c:78
static void perform_signal_callback(void *context)
Definition hid.c:617

References hid_device_::barrier, hid_device_::condition, hid_device_::device_handle, hid_device_::disconnected, FALSE, hid_device_::mutex, perform_signal_callback(), pthread_barrier_wait(), hid_device_::run_loop, hid_device_::run_loop_mode, hid_device_::shutdown_barrier, hid_device_::shutdown_thread, and hid_device_::source.

Referenced by hid_open_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ return_data()

static int return_data ( hid_device dev,
unsigned char *  data,
size_t  length 
)
static
808{
809 /* Copy the data out of the linked list item (rpt) into the
810 return buffer (data), and delete the liked list item. */
811 struct input_report *rpt = dev->input_reports;
812 size_t len = (length < rpt->len)? length: rpt->len;
813 memcpy(data, rpt->data, len);
814 dev->input_reports = rpt->next;
815 free(rpt->data);
816 free(rpt);
817 return len;
818}
double length(std::vector< SurfacePoint > &path)
Definition exact_geodesic.cpp:1682

References input_report::data, free(), hid_device_::input_reports, input_report::len, and input_report::next.

Referenced by hid_close(), hid_read_timeout(), and hid_report_callback().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_report()

static int set_report ( hid_device dev,
IOHIDReportType  type,
const unsigned char *  data,
size_t  length 
)
static
763{
764 const unsigned char *data_to_send;
765 size_t length_to_send;
766 IOReturn res;
767
768 /* Return if the device has been disconnected. */
769 if (dev->disconnected)
770 return -1;
771
772 if (data[0] == 0x0) {
773 /* Not using numbered Reports.
774 Don't send the report number. */
775 data_to_send = data+1;
776 length_to_send = length-1;
777 }
778 else {
779 /* Using numbered Reports.
780 Send the Report Number */
781 data_to_send = data;
782 length_to_send = length;
783 }
784
785 if (!dev->disconnected) {
786 res = IOHIDDeviceSetReport(dev->device_handle,
787 type,
788 data[0], /* Report ID*/
789 data_to_send, length_to_send);
790
791 if (res == kIOReturnSuccess) {
792 return length;
793 }
794 else
795 return -1;
796 }
797
798 return -1;
799}
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195

References input_report::data, hid_device_::device_handle, and hid_device_::disconnected.

Referenced by hid_send_feature_report(), and hid_write().

+ Here is the caller graph for this function:

Variable Documentation

◆ hid_mgr

IOHIDManagerRef hid_mgr = 0x0
static