我正在阅读StdFBShmem_t
结构中的moust光标像素图数据,如IOFrameBufferShared API中所定义。
一切正常,90%的时间。但是,我注意到Mac上的某些应用程序将游标设置为不同的格式。根据数据结构的文档,光标像素图格式应始终与帧缓冲区的格式相同。我的帧缓冲区是32 bpp。我希望pixmap数据的格式为0xAARRGGBB
,这是(大多数时候)。但是,在某些情况下,我正在读取看起来像面具的数据。具体来说,此数据中的像素将为0x00FFFFFF
或“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];
我的问题是:
如何检测光标是否为其他格式 来自framebuffer?
我在哪里可以读取实际的像素数据? bm18Cursor
结构包含一个掩码部分,但它不在
我可以使用代码阅读它
上方。
答案 0 :(得分:2)
如何检测光标是否与帧缓冲区的格式不同?
光标位于帧缓冲区中。它的格式不能与其本身不同。
没有办法说出它的格式(x-radar:// problem / 7751503)。如果你可以知道光标有多少帧,那么有一种方法可以至少判断每个像素的字节数,但是因为你不能(这个信息没有设置为10.6.1 - x-radar:/ / problem / 7751530),你只想弄清楚四因素产品的两个因素(每像素字节数×宽度×高度×帧数,你只有宽度,高度和产品)。即使你能找出那两个缺失的因素,你仍然不知道字节的顺序是什么,或者颜色分量是否被alpha分量预乘。
我在哪里可以读取实际的像素数据?
在共享游标内存结构的cursor
成员中。
在包含I / O Kit标头之前,您应该定义IOFB_ARBITRARY_SIZE_CURSOR
。游标现在可以是任何大小,而不仅仅是16×16,这是您未定义该常量时所期望的大小。例如,通常的Mac箭头光标为24×24,CrossOver中的“Windows”箭头光标为32×32,X11中的箭头光标为10×16。
但是,在某些情况下,我正在读取看起来像面具的数据。具体而言,此数据中的像素将为
0x00FFFFFF
或0x00000000
。这使我成为存储在其他地方的单独像素数据的掩码。
这听起来更像是带有8位alpha通道的16位像素。至少它更可能是5-6-5而不是5-5-5。
据我所知,唯一使用这种光标像素格式的应用程序是Qt Creator,但我需要处理所有应用程序,所以我想对此进行排序。
我可以使用my new cursor-capturing app捕获该应用中的当前光标。我应该点击应用程序的特定部分,以便向我显示特定的光标吗?
答案 1 :(得分:2)
您可以尝试使用CGSCreateRegisteredCursorImage函数,demonstrated by Karsten in a comment on my weblog。
它是一个私有函数,因此它可能随时更改或消失,因此您应该检查它是否存在并保留IOFramebuffer,但只要它确实存在,您可能会发现它比复杂更可靠并且记录在案的IOFramebuffer。