MacOS X internals
Захотелось разобраться как работает оконная система MacOS X изнутри. В Windows все понятно и документировано - цикл сообщений, API для создания окон и манипуляции их состоянием. В замечательной OS X все спрятано за красивым фреймворком Cocoa. Годы хардфакинга в MFC/WinAPI подсказывают, что принципы построения графической оболочки везде одинаковы. Потратил время, докопался до места откуда растут ноги.
Механизм взаимодействия графической подсистемы с пользовательским кодом
Если создать в XCode простейшее AppKit приложение и запустить его - получим пустое окно на экране. Чудес, как обычно, не бывает - окно должно быть создано неким API. За композицию окон в OS X отвечает подсистема с замысловатым названием Quartz. В списке процессов можно обнаружить WindowServer, это собственно ядро Quartz. Именно там происходит формирование картинки для устройства отображения (монитора). Гугление на тему создания окон в OS X привело меня на страничку Header file for undocumented CoreGraphics SPI. Изучив контент я сделал вывод, что существует библиотека Core Graphics с низкоуровневым API для взаимодействия с WindowServer. Дабы убедиться, что Cocoa использует этот API, я поставил точку останова на функцию _CGSCreateWindowInline
и запустил приложение. В результате получил такой стек вызовов:
#1 0x00007fff8fc8d64b in _CGSCreateWindowInline () #2 0x00007fff8fc8cd0b in CGSNewWindowWithOpaqueShape () #3 0x00007fff8be708e8 in _NSCreateWindowWithOpaqueShape2 () #4 0x00007fff8be6ed70 in -[NSWindow _commonAwake] () #5 0x00007fff8bf271c9 in -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] () #6 0x00007fff8bf26a18 in -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] () #7 0x00007fff8bf265ff in -[NSWindow orderWindow:relativeTo:] () #8 0x00007fff8be27c96 in -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] () #9 0x00007fff8be06b7d in loadNib () #10 0x00007fff8be060a9 in +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] () #11 0x00007fff8be05ede in -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] () #12 0x00007fff8be05cbe in +[NSBundle(NSNibLoading) loadNibNamed:owner:] () #13 0x00007fff8be0247f in NSApplicationMain () #14 0x00000001000011b2 in main at /Users/admin/Development/CocoaInspector/CocoaInspector/main.m:13 #15 0x00007fff932127e1 in start ()
OK, это то, что нам нужно. Осталось выяснить как Core Graphics взаимодействует с процессом WindowServer. Ассемблерный листинг функции _CGSCreateWindowInline
содержит инструкцию вызова системной процедуры mach_msg
, которая является основным способом межпроцессного взаимодействия в операционной системе OS X.
Выводы: Core Graphics является закрытой недокументированной библиотекой для взаимодействия с графическим сервером средствами ядра путем отправки и получения сообщений.
0 коммент.:
Отправить комментарий