Mac OS X Window Server против X11: безумная задача - PullRequest
4 голосов
/ 24 июня 2010

Предназначено для всех, кто любит низкоуровневый Windows Server (CoreGraphicsPrivate.h и т. Д.), X11 на Mac, SIMBL и другие сумасшедшие вещи:)

На Mac есть простое эмулированное приложение X11 (например, xtermхы и тд) с одним окном.Во время работы X11 каким-то образом создает собственное окно Quartz для представления этого эмулированного приложения, и это окно доступно через Quartz Window Services, так что я могу получить его CSWindowID, заголовок, положение, размер и PID владельца (PID X11.app).Но он не поддерживает Accessibility API, поэтому нет никакого способа управлять им (кроме, может быть, частных функций Core Graphichs из того же процесса).


Теперь вот задача:

Мне нужно разместить дополнительный NSView (или просто нарисовать что-то) на таком окне.Я имею в виду родное окно Quartz, которое появилось в результате эмуляции приложения X11.Я знаю, что для управления окнами на Mac я должен быть в том же процессе, то есть X11.app.


Я написал плагин SIMBL, который внедряется в процесс X11.app.

Там я могу позвонить [NSApp windows], но все время получаю ровно 2 NSWindows, которые не имеют ничего общего с окнами реальных приложений.Они даже не видны на экране.

Тем не менее, когда я вызываю NSWindowList (), я получаю все, что мне нужно (идентификаторы окон для окон X11) и даже больше (идентификаторы окон из других приложений).

Когда у меня есть CSWindowID для окон, эмулируемых X11, я вызываю [NSApp windowWithWindowNumber:] (Какао) и HIWindowFromCGWindowID () (Carbon), но они оба возвращают ноль!Из того же самого процесса!

Кстати, все эти действия прекрасно работают, когда я вторгаюсь в процесс Safari и другие ...


Итак, вопросы:

  • Как X11 создал такие окна, которые недоступны из того же процесса?

  • Как получить указатели на окна X11 (NSWindow *, CGContextRef или, по крайней мере, что-нибудь ...) и разместить мою графику (я даже не говорю о NSViews) на них?


Большое спасибо заранее!

Ответы [ 2 ]

5 голосов
/ 24 июня 2010

Все исходники X11.app и другие материалы (Xquartz) доступны на официальный сайт Apple (текущая версия 2.3.5 (сервер 85.2)).Ядро создания окон лежит в подкаталоге xpr .

. Для работы с окнами Xquartz использует библиотеку Xplugin (/usr/lib/libXplugin.dylib).Его заголовок /usr/include/Xplugin.h определяет функции, такие как xp_create_surface () и другие, которые создают окна с использованием частного API CoreGraphics, например CGSNewWindowWithOpaqueShape ().Недокументированный CoreGraphicsPrivate.h или CSGPrivate.h, результат обратного инжиниринга, можно найти через Интернет .Xplugin запоминает идентификаторы таких окон Quartz в своем собственном хэше и возвращает для них непрозрачное целое число (то есть xp_resource_id).Затем Xquartz связывает определенный XID с этим xp_resource_id и возвращает его клиенту.

Xplugin является закрытым исходным кодом и не имеет API для возврата собственного кварца, который можно отрисовать с помощью xp_resource_id или XID.

Чтобы нарисовать окно, которое было создано с помощью частного API CoreGraphics, вы должны использовать этот частный API.Есть функция с именем CGWindowContextCreate (), которая возвращает CGContextRef для определенного собственного окна по его идентификатору Quartz.Можно нарисовать на окне, используя этот контекст.Но чтобы получить реальный контекст вместо NULL, вы должны быть в процессе, который создал окно.

5 голосов
/ 24 июня 2010

Насколько я понимаю, X11 использует свой собственный сервер Windows и общий стек. Вот почему он может запускать приложения X11 без специальных портов.

Он имеет только тот уровень ответов, который имитирует отклик окон Какао, так что он может взаимодействовать с общим интерфейсом. Это не замаскированный стек Какао, а стек X11, внешне замаскированный под Какао. Как таковой, он отвечает только на подмножество сообщений, связанных с Какао.

Я думаю, чтобы сделать что-то серьезное в X11, вы должны использовать X11 API с самого начала. Другими словами, пишите так, как будто он не предназначен для работы поверх Mac OS.

...