我正在从IOFrameBufferShared APIStdFBShmem_t
中定义的结构中读取最重要的光标像素图数据。
一切正常,90% 的时间。但是,我注意到 Mac 上的某些应用程序以不同的格式设置光标。根据数据结构的文档,光标像素图格式应始终与帧缓冲区的格式相同。我的帧缓冲区是 32 bpp。我希望像素图数据的格式0xAARRGGBB
为(大多数情况下)。但是,在某些情况下,我正在读取看起来像掩码的数据。具体来说,此数据中的像素将是0x00FFFFFF
0x00000000 或 0x00000000。这在我看来是存储在其他地方的单独像素数据的掩码。
据我所知,唯一使用这种光标像素格式的应用程序是Qt Creator,但我需要使用所有应用程序,所以我想解决这个问题。
我用来读取光标像素图数据的代码是:
NSAutoreleasePool *autoReleasePool = [[NSAutoreleasePool alloc] init];
NSPoint mouseLocation = [NSEvent mouseLocation];
NSArray *allScreens = [NSScreen screens];
NSEnumerator *screensEnum = [allScreens objectEnumerator];
NSScreen *screen;
NSDictionary *screenDesc = nil;
while ((screen = [screensEnum nextObject]))
{
NSRect screenFrame = [screen frame];
screenDesc = [screen deviceDescription];
if (NSMouseInRect(mouseLocation, screenFrame, NO))
break;
}
if (screen)
{
kern_return_t err;
CGDirectDisplayID displayID = (CGDirectDisplayID) [[screenDesc objectForKey:@"NSScreenNumber"] pointerValue];
task_port_t taskPort = mach_task_self();
io_service_t displayServicePort = CGDisplayIOServicePort(displayID);
io_connect_t displayConnection =0;
err = IOFramebufferOpen(displayServicePort,
taskPort,
kIOFBSharedConnectType,
&displayConnection);
if (KERN_SUCCESS == err)
{
union
{
vm_address_t vm_ptr;
StdFBShmem_t *fbshmem;
} cursorInfo;
vm_size_t size;
err = IOConnectMapMemory(displayConnection,
kIOFBCursorMemory,
taskPort,
&cursorInfo.vm_ptr,
&size,
kIOMapAnywhere | kIOMapDefaultCache | kIOMapReadOnly);
if (KERN_SUCCESS == err)
{
// For some reason, cursor data is not always in the same format as
// the frame buffer. For this reason, we need some way to detect
// which structure we should be reading.
QByteArray pixData(
(const char*)cursorInfo.fbshmem->cursor.rgb24.image[currentFrame],
m_mouseInfo.currentSize.width() * m_mouseInfo.currentSize.height() * 4);
IOConnectUnmapMemory(displayConnection,
kIOFBCursorMemory,
taskPort,
cursorInfo.vm_ptr);
} // IOConnectMapMemory
else
qDebug() << "IOConnectMapMemory Failed:" << err;
IOServiceClose(displayConnection);
} // IOServiceOpen
else
qDebug() << "IOFramebufferOpen Failed:" << err;
}// if screen
[autoReleasePool release];
我的问题是:
如何检测光标是否与帧缓冲区的格式不同?
我在哪里可以读取实际的像素数据?该
bm18Cursor
结构包含一个掩码部分,但它不适合我使用上面的代码阅读它。