IOFrameBufferShared APIStdFBShmem_t
で定義されているように、構造体からマウス カーソルのピックスマップ データを読み取っています。
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];
私の質問は次のとおりです。
カーソルがフレームバッファとは異なるフォーマットであるかどうかを検出するにはどうすればよいですか?
実際のピクセル データはどこで読み取ることができますか? 構造にはマスク セクションが含まれていますが、上記
bm18Cursor
のコードを使用してそれを読み取るには適切な場所ではありません。