Cocoa MacOSX窗口服务器与X11:疯狂的任务

Cocoa MacOSX窗口服务器与X11:疯狂的任务,cocoa,core-graphics,x11,macos-carbon,simbl,Cocoa,Core Graphics,X11,Macos Carbon,Simbl,献给所有喜欢低级窗口服务器(CoreGraphicsPrivate.h等)、Mac上的X11、SIMBL和其他疯狂东西的人:) Mac上有一个简单的X11模拟应用程序(如xterm、xeyes等),只有一个窗口。在运行时,X11以某种方式创建了一个本机Quartz窗口来表示此模拟应用程序,并且可以通过Quartz窗口服务访问此窗口,以便我可以获取其CSWindowID、标题、位置、大小和所有者的PID(X11.app的PID)。但它不支持可访问性API,因此无法控制它(除了同一进程中的核心Gra

献给所有喜欢低级窗口服务器(CoreGraphicsPrivate.h等)、Mac上的X11、SIMBL和其他疯狂东西的人:)

Mac上有一个简单的X11模拟应用程序(如xterm、xeyes等),只有一个窗口。在运行时,X11以某种方式创建了一个本机Quartz窗口来表示此模拟应用程序,并且可以通过Quartz窗口服务访问此窗口,以便我可以获取其CSWindowID、标题、位置、大小和所有者的PID(X11.app的PID)。但它不支持可访问性API,因此无法控制它(除了同一进程中的核心Graphichs私有函数)


现在,任务如下:

我需要在这样一个窗口上承载一个额外的NSView(或者只是绘制一些东西)。我指的是原生石英窗口,它是X11模拟某些应用程序的结果。我知道,要在Mac上操作windows,我必须在同一个过程中,即X11.app


我编写了一个SIMBL插件,它侵入了X11.app进程

在那里,我可以调用[NSApp windows],但一直以来,我只得到2个NSWindows,它们与实际应用程序的窗口没有任何共同之处。它们甚至在屏幕上都不可见

然而,当我调用NSWindowList()时,我得到了我需要的任何东西(X11窗口的窗口ID),甚至更多(来自其他应用程序的窗口ID)

当我为X11模拟窗口获得CSWindowID时,我调用[NSApp windowWithWindowNumber:](Cocoa)和HIWindowFromCGWindowID()(Carbon),但它们都返回nil!同样的过程

顺便说一句,当我闯入Safari程序和其他程序时,所有这些操作都能完美工作


因此,问题是:

  • X11是如何创建无法从同一进程访问的窗口的

  • 我如何获得指向X11窗口(NSWindow*、CGContextRef或至少是任何东西)的指针,并在其上承载我的图形(我甚至不谈论NSView)



提前多谢

据我所知,X11使用自己的windows服务器和通用堆栈。这就是为什么它可以在没有特殊端口的情况下运行X11应用程序

它只有一层模仿Cocoa窗口的响应,这样它就可以与通用接口通信。它不是伪装的可可堆栈,而是表面上伪装成可可的X11堆栈。因此,它只响应可可相关消息的一个子集


我认为要在X11中做任何严肃的事情,必须从一开始就使用X11API。换句话说,写的时候就好像它不打算在Mac OS上运行一样。

所有X11.app源代码和其他东西(Xquartz)都可以在(当前版本2.3.5(服务器85.2))上获得。windows创建的核心在于

要操作windows Xquartz,请使用Xplugin库(/usr/lib/libXplugin.dylib)。它的头文件/usr/include/Xplugin.h定义了xp_create_surface()等函数,这些函数使用私有CoreGraphics API(如cgsnewIndowWithOpaqueShape())创建窗口。可以找到未记录的Coregraphics Sprivate.h或CSGPrivate.h,这是逆向工程的结果。Xplugin在自己的散列中记住此类石英窗口的id,并为它们返回一个不透明的整数(即xp_resource_id)。然后,Xquartz将特定的XID与此xp\u资源\u id关联,并将其返回给客户端

Xplugin是封闭源代码,没有API返回可由xp\u资源\u id或XID绘制的原生石英


为了利用使用私有CoreGraphics API创建的窗口,您必须使用这些私有API。有一个名为CGWindowContextCreate()的函数,它通过石英id返回特定本机窗口的CGContextRef。可以使用此上下文在窗口上绘制。但是要接收真实的上下文而不是NULL,您必须处于创建窗口的进程中。

那么,可以创建真实的Quartz窗口,但甚至没有WindowRef?那么X11在获取N事件、折叠它们等等时如何移动其窗口?你是说它在代码的某个深处存储了WindowsRef?似乎有专用API来创建windows。。。X11使用libXplugin,反过来又使用CGSNewWindow()等函数。
CGSNewWindow()是SDL(简单DirectMedia Library)库的一部分,SDL库是一个跨平台媒体/游戏库。比如,我说,它不是真正的Cocoa。好吧,然后看看:CGError cGsnewindowWithopaqueshape(CGSConnectionID cid,int always2,float x,float y y,CGSRegionRef shape,CGSRegionRef opaqueShape,int unknown1,void*unknownPtr,int always32,CGSWindowID*outWID);我应该看什么?相反,我应该从这段代码中推断出什么?如果这是你问题的答案,你应该打勾,让系统知道它已经得到了回答。