mirror of
https://github.com/samhenrigold/LidAngleSensor.git
synced 2026-01-12 17:27:44 +03:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d31e8e49e0 | ||
|
|
f608105ce7 | ||
|
|
d590174cdd | ||
|
|
82189fa0b3 | ||
|
|
1ee1d846db |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = gold.samhenri.LidAngleSensor;
|
PRODUCT_BUNDLE_IDENTIFIER = gold.samhenri.LidAngleSensor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
@@ -310,7 +310,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = gold.samhenri.LidAngleSensor;
|
PRODUCT_BUNDLE_IDENTIFIER = gold.samhenri.LidAngleSensor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
|
|||||||
@@ -48,11 +48,13 @@
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Generic Desktop + Mouse criteria to find candidate devices
|
// Match specifically for the lid angle sensor to avoid permission prompts
|
||||||
// This broader search allows us to find the lid sensor among other HID devices
|
// Target: Sensor page (0x0020), Orientation usage (0x008A)
|
||||||
NSDictionary *matchingDict = @{
|
NSDictionary *matchingDict = @{
|
||||||
@"UsagePage": @(0x0001), // Generic Desktop
|
@"VendorID": @(0x05AC), // Apple
|
||||||
@"Usage": @(0x0003), // Mouse
|
@"ProductID": @(0x8104), // Specific product
|
||||||
|
@"UsagePage": @(0x0020), // Sensor page
|
||||||
|
@"Usage": @(0x008A), // Orientation usage
|
||||||
};
|
};
|
||||||
|
|
||||||
IOHIDManagerSetDeviceMatching(manager, (__bridge CFDictionaryRef)matchingDict);
|
IOHIDManagerSetDeviceMatching(manager, (__bridge CFDictionaryRef)matchingDict);
|
||||||
@@ -60,33 +62,38 @@
|
|||||||
IOHIDDeviceRef device = NULL;
|
IOHIDDeviceRef device = NULL;
|
||||||
|
|
||||||
if (devices && CFSetGetCount(devices) > 0) {
|
if (devices && CFSetGetCount(devices) > 0) {
|
||||||
NSLog(@"[LidAngleSensor] Found %ld devices, looking for sensor...", CFSetGetCount(devices));
|
NSLog(@"[LidAngleSensor] Found %ld matching lid angle sensor device(s)", CFSetGetCount(devices));
|
||||||
|
|
||||||
const void **deviceArray = malloc(sizeof(void*) * CFSetGetCount(devices));
|
const void **deviceArray = malloc(sizeof(void*) * CFSetGetCount(devices));
|
||||||
CFSetGetValues(devices, deviceArray);
|
CFSetGetValues(devices, deviceArray);
|
||||||
|
|
||||||
// Search for the specific lid angle sensor device
|
// Test each matching device to find the one that actually works
|
||||||
// Discovered through reverse engineering: Apple device with Sensor page
|
|
||||||
for (CFIndex i = 0; i < CFSetGetCount(devices); i++) {
|
for (CFIndex i = 0; i < CFSetGetCount(devices); i++) {
|
||||||
IOHIDDeviceRef currentDevice = (IOHIDDeviceRef)deviceArray[i];
|
IOHIDDeviceRef testDevice = (IOHIDDeviceRef)deviceArray[i];
|
||||||
|
|
||||||
CFNumberRef vendorID = IOHIDDeviceGetProperty(currentDevice, CFSTR("VendorID"));
|
// Try to open and read from this device
|
||||||
CFNumberRef productID = IOHIDDeviceGetProperty(currentDevice, CFSTR("ProductID"));
|
if (IOHIDDeviceOpen(testDevice, kIOHIDOptionsTypeNone) == kIOReturnSuccess) {
|
||||||
CFNumberRef usagePage = IOHIDDeviceGetProperty(currentDevice, CFSTR("PrimaryUsagePage"));
|
uint8_t testReport[8] = {0};
|
||||||
CFNumberRef usage = IOHIDDeviceGetProperty(currentDevice, CFSTR("PrimaryUsage"));
|
CFIndex reportLength = sizeof(testReport);
|
||||||
|
|
||||||
int vid = 0, pid = 0, up = 0, u = 0;
|
IOReturn result = IOHIDDeviceGetReport(testDevice,
|
||||||
if (vendorID) CFNumberGetValue(vendorID, kCFNumberIntType, &vid);
|
kIOHIDReportTypeFeature,
|
||||||
if (productID) CFNumberGetValue(productID, kCFNumberIntType, &pid);
|
1,
|
||||||
if (usagePage) CFNumberGetValue(usagePage, kCFNumberIntType, &up);
|
testReport,
|
||||||
if (usage) CFNumberGetValue(usage, kCFNumberIntType, &u);
|
&reportLength);
|
||||||
|
|
||||||
// Target the specific lid angle sensor device
|
if (result == kIOReturnSuccess && reportLength >= 3) {
|
||||||
// VID=0x05AC (Apple), PID=0x8104, UsagePage=0x0020 (Sensor), Usage=0x008A (Orientation)
|
// This device works! Use it.
|
||||||
if (vid == 0x05AC && pid == 0x8104 && up == 0x0020 && u == 0x008A) {
|
device = (IOHIDDeviceRef)CFRetain(testDevice);
|
||||||
device = (IOHIDDeviceRef)CFRetain(currentDevice);
|
NSLog(@"[LidAngleSensor] Successfully found working lid angle sensor device (index %ld)", i);
|
||||||
NSLog(@"[LidAngleSensor] Found lid angle sensor device: VID=0x%04X, PID=0x%04X", vid, pid);
|
IOHIDDeviceClose(testDevice, kIOHIDOptionsTypeNone); // Close for now, will reopen in init
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
NSLog(@"[LidAngleSensor] Device %ld failed to read (result: %d, length: %ld)", i, result, reportLength);
|
||||||
|
IOHIDDeviceClose(testDevice, kIOHIDOptionsTypeNone);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NSLog(@"[LidAngleSensor] Failed to open device %ld", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,9 +126,9 @@
|
|||||||
|
|
||||||
if (result == kIOReturnSuccess && reportLength >= 3) {
|
if (result == kIOReturnSuccess && reportLength >= 3) {
|
||||||
// Data format: [report_id, angle_low, angle_high]
|
// Data format: [report_id, angle_low, angle_high]
|
||||||
// Example: [01 72 00] = 0x7201 centidegrees = 291.85 degrees
|
// Parse the 16-bit value from bytes 1-2 (skipping report ID)
|
||||||
uint16_t rawValue = *(uint16_t*)(report);
|
uint16_t rawValue = (report[2] << 8) | report[1]; // High byte, low byte
|
||||||
double angle = rawValue * 0.01; // Convert centidegrees to degrees
|
double angle = (double)rawValue; // Raw value is already in degrees
|
||||||
|
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user