Skip to content

Commit e3a698f

Browse files
committed
Brightness (macOS): fixes detection for external monitor on Intel platform
1 parent 1631f74 commit e3a698f

File tree

1 file changed

+47
-18
lines changed

1 file changed

+47
-18
lines changed

src/detection/brightness/brightness_apple.c

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -123,38 +123,70 @@ static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult*
123123
return NULL;
124124
}
125125
#else
126+
static IOOptionBits getSupportedTransactionType(void) {
127+
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
128+
129+
if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceNameMatching("IOFramebufferI2CInterface"), &iterator) != KERN_SUCCESS)
130+
return 0;
131+
132+
io_registry_entry_t registryEntry;
133+
while ((registryEntry = IOIteratorNext(iterator)) != MACH_PORT_NULL)
134+
{
135+
FF_IOOBJECT_AUTO_RELEASE io_service_t io_service = registryEntry;
136+
FF_CFTYPE_AUTO_RELEASE CFNumberRef IOI2CTransactionTypes = IORegistryEntryCreateCFProperty(io_service, CFSTR(kIOI2CTransactionTypesKey), kCFAllocatorDefault, kNilOptions);
137+
138+
if (IOI2CTransactionTypes)
139+
{
140+
int64_t types = 0;
141+
ffCfNumGetInt64(IOI2CTransactionTypes, &types);
142+
143+
/*
144+
We want DDCciReply but Simple is better than No-thing.
145+
Combined and DisplayPortNative are not useful in our case.
146+
*/
147+
if (types) {
148+
if ((1 << kIOI2CSimpleTransactionType) & (uint64_t) types)
149+
return kIOI2CSimpleTransactionType;
150+
if ((1 << kIOI2CDDCciReplyTransactionType) & (uint64_t) types)
151+
return kIOI2CDDCciReplyTransactionType;
152+
if ((1 << kIOI2CCombinedTransactionType) & (uint64_t) types)
153+
return kIOI2CCombinedTransactionType;
154+
if ((1 << kIOI2CDisplayPortNativeTransactionType) & (uint64_t) types)
155+
return kIOI2CDisplayPortNativeTransactionType;
156+
}
157+
}
158+
break;
159+
}
160+
161+
return 0;
162+
}
163+
126164
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
127165
{
128166
if (!CGSServiceForDisplayNumber) return "CGSServiceForDisplayNumber is not available";
167+
IOOptionBits transactionType = getSupportedTransactionType();
129168

130169
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
131170
{
132171
if (display->type == FF_DISPLAY_TYPE_EXTERNAL)
133172
{
134-
io_service_t framebuffer = 0;
173+
FF_IOOBJECT_AUTO_RELEASE io_service_t framebuffer = IO_OBJECT_NULL;
135174
CGSServiceForDisplayNumber((CGDirectDisplayID)display->id, &framebuffer);
136-
if (framebuffer == 0) continue;
175+
if (framebuffer == IO_OBJECT_NULL) continue;
137176

138177
IOItemCount count;
139178
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0)
140-
{
141-
IOObjectRelease(framebuffer);
142179
continue;
143-
}
144180

145-
bool found = false;
146-
for (IOItemCount bus = 0; bus < count && !found; ++bus)
181+
for (IOItemCount bus = 0; bus < count; ++bus)
147182
{
148-
io_service_t interface = 0;
149-
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
183+
FF_IOOBJECT_AUTO_RELEASE io_service_t interface = IO_OBJECT_NULL;
184+
if (IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface) != KERN_SUCCESS) continue;
150185

151186
uint8_t i2cOut[12] = {};
152-
IOI2CConnectRef connect;
187+
IOI2CConnectRef connect = NULL;
153188
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
154-
{
155-
IOObjectRelease(interface);
156189
continue;
157-
}
158190

159191
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
160192
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
@@ -168,13 +200,12 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
168200
.minReplyDelay = options->ddcciSleep * 1000ULL,
169201
.replyAddress = 0x6F,
170202
.replySubAddress = 0x51,
171-
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
203+
.replyTransactionType = transactionType,
172204
.replyBytes = ARRAY_SIZE(i2cOut),
173205
.replyBuffer = (vm_address_t) i2cOut,
174206
};
175207
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
176208
IOI2CInterfaceClose(connect, kNilOptions);
177-
IOObjectRelease(interface);
178209

179210
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess || request.replyBytes < 10) continue;
180211
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
@@ -189,10 +220,8 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
189220
ffStrbufInitCopy(&brightness->name, &display->name);
190221
brightness->builtin = false;
191222

192-
found = true;
223+
break;
193224
}
194-
195-
IOObjectRelease(framebuffer);
196225
}
197226
}
198227

0 commit comments

Comments
 (0)