gpt4 book ai didi

c++ - IOFrameBufferShared 中的不同游标格式

转载 作者:太空狗 更新时间:2023-10-29 21:08:48 26 4
gpt4 key购买 nike

我正在从 StdFBShmem_t 结构中读取大多数光标像素图数据,如 IOFrameBufferShared API 中定义的那样.

一切正常,90% 的时间。但是,我注意到 Mac 上的一些应用程序以不同的格式设置了光标。根据数据结构的文档,光标像素图格式应始终与帧缓冲区的格式相同。我的帧缓冲区是 32 bpp .我希望像素图数据采用 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];

我的问题是:

  1. 如何检测光标是否为不同格式来自帧缓冲区?

  2. 我在哪里可以读取实际的像素数据? bm18Cursor结构包含一个掩码部分,但它不在我可以使用代码阅读它的正确位置以上。

最佳答案

How can I detect if the cursor is a different format from the framebuffer?

光标在帧缓冲区中。它不能采用与自身不同的格式。

无法判断它的格式 (x-radar://problem/7751503)。如果您可以知道光标有多少帧,那么至少有一种方法可以预测每个像素的字节数,但由于您不能(该信息未设置为 10.6.1 — x-radar://problem/7751530),您需要尝试找出四因素乘积的两个因素(每像素字节数 × 宽度 × 高度 × 帧数,其中您只有宽度、高度和乘积)。即使您可以找出那两个缺失的因素,您仍然不知道字节的顺序是什么,或者颜色分量是否预乘了 alpha 分量。

Where can I read the actual pixel data?

在 shared-cursor-memory 结构的 cursor 成员中。

您应该在包含 I/O 套件 header 之前定义 IOFB_ARBITRARY_SIZE_CURSOR。游标现在可以是任何大小,而不仅仅是 16×16,这是您在未定义常量时所期望的大小。例如,通常的Mac箭头光标为24×24,CrossOver中的“Windows”箭头光标为32×32,X11中的箭头光标为10×16。

However, in some cases, I'm reading data that looks like a mask. Specifically, the pixels in this data will either be 0x00FFFFFF or 0x00000000. This looks to me to be a mask for separate pixel data stored somewhere else.

在我看来,这更像是带有 8 位 alpha channel 的 16 位像素。至少 5-6-5 比 5-5-5 更有可能。

As far as I can tell, the only application that uses this cursor pixel format is Qt Creator, but I need to work with all applications, so I'd like to sort this out.

我可以使用 my new cursor-capturing app 捕获该应用程序中的当前光标。 .我应该点击应用程序的特定部分以使其显示特定光标吗?

关于c++ - IOFrameBufferShared 中的不同游标格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2433207/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com