| 1 | This file summarizes primary aspects of the NS port architecture. If |
| 2 | possible, it should be updated for changes. |
| 3 | |
| 4 | Currently it summarizes the state as of: |
| 5 | |
| 6 | summer 2008 shortly after merging to trunk |
| 7 | |
| 8 | |
| 9 | |
| 10 | Startup |
| 11 | ------- |
| 12 | |
| 13 | Init sequence: |
| 14 | emacs.c: ns_alloc_autorelease_pool() nsterm.m |
| 15 | emacs.c: ns_init_paths() nsterm.m |
| 16 | - override EMACSLOADPATH, etc. so resources can be found in-bundle |
| 17 | emacs.c: init_display() dispnew.c |
| 18 | - sets Vwindow_system (window-system) to 'ns |
| 19 | emacs.c: loadup.el -> startup.el -> ns-initialize-window-system |
| 20 | -> x-open-connection (nsfns.m) |
| 21 | - ns-list-services |
| 22 | -> nsterm.m: ns_term_init() |
| 23 | - EmacsApp sharedApplication |
| 24 | - read NS defaults (org.gnu.Emacs.plist) |
| 25 | - init X-style color list |
| 26 | - ns_create_terminal() |
| 27 | - NSApp run (goes to applicationDidFinishLaunching which terminates |
| 28 | event loop -- see below) |
| 29 | |
| 30 | |
| 31 | |
| 32 | Event Loop |
| 33 | ---------- |
| 34 | |
| 35 | In an NS application, the event loop is normally managed by system and all |
| 36 | user code is event-driven. [NSApp run] is called by user and never returns. |
| 37 | |
| 38 | In Emacs, the event loop is managed by emacs itself. |
| 39 | |
| 40 | The NS port mediates between these two styles by intercepting the NS event |
| 41 | dispatch at [NSApp sendEvent]. If a special event is detected, the event loop |
| 42 | is broken, and control returned to Emacs. This special event is sent by |
| 43 | ns_send_appdefined, which is called under these circumstances: |
| 44 | |
| 45 | - if a user input event is received |
| 46 | - when a timeout fires |
| 47 | |
| 48 | NS event processing is instigated from Emacs through ns_select() and |
| 49 | ns_read_socket() in nsterm.m. Parts of the codepaths leading to these |
| 50 | functions are: |
| 51 | |
| 52 | |
| 53 | keyboard.c:read_avail_input() |
| 54 | -> ns_read_socket (ns_send_appdefined) -> [NSApp run] |
| 55 | |
| 56 | process.c:wait_reading_process_output() |
| 57 | -> ns_select -> gobble_input (global inNsSelect=1) |
| 58 | -> ns_read_socket (ns_send_appdefined if !expected) -> [NSApp run] |
| 59 | |
| 60 | sysdep.c:sys_select() -> read_input_waiting() |
| 61 | -> ns_read_socket (send_appdefined) -> [NSApp run] |
| 62 | [this codepath may not be used] |
| 63 | |
| 64 | |
| 65 | Currently ctrl-g is not detected in as many circumstances as other emacsen. |
| 66 | It is not certain whether this is due to the means of event loop integration, |
| 67 | or errors of omission in the NS code. This is an area for improvement. |
| 68 | Also, see the article here and its containing thread: |
| 69 | |
| 70 | http://article.gmane.org/gmane.emacs.devel/92021/match=handling%5fsignal |
| 71 | |
| 72 | |
| 73 | |
| 74 | |
| 75 | Text Rendering and Font Handling |
| 76 | -------------------------------- |
| 77 | |
| 78 | nsfont.m implements the font driver, responsible for managing fonts and |
| 79 | rendering text. Fonts are obtained through NSFontManager. Rendering must be |
| 80 | done at a low level due to emacs' fine control over this process, therefore |
| 81 | there are different approaches under Cocoa and GNUstep. Under GNUstep, the |
| 82 | original NeXT Display PostScript (DPS) APIs are available and used. Under |
| 83 | Cocoa, these were removed and Quartz drawing functions replaced them. |
| 84 | |
| 85 | In both cases, font glyphs are accessed through UTF8 character |
| 86 | representations. It would be preferable to use Unicode indices, but prior |
| 87 | attempts at this have failed. |
| 88 | |
| 89 | Multi-script fontsets are auto-created in nsfont_make_fontset_for_font() using |
| 90 | the facilities of NSTextStorage and NSLayoutManager. |
| 91 | |
| 92 | |
| 93 | Object Architecture |
| 94 | ------------------- |
| 95 | |
| 96 | Unlike the other GUIs, the NS interface is based on a high-level and |
| 97 | object-oriented API. This creates some tension in the code because emacs |
| 98 | itself has been architected around the low-level Xlib and Xt APIs. The NS |
| 99 | port tries to strike a balance between simplifying code on its side using OO |
| 100 | features, and keeping code as similar as possible to other ports to ease |
| 101 | maintenance. The following are the main classes (see nsterm.h): |
| 102 | |
| 103 | EmacsApp : NSApplication |
| 104 | - event loop integration, interapp comms point for Finder (NSWorkspace) msgs, |
| 105 | Services |
| 106 | - one global instance (NSApp) |
| 107 | - nsterm.m |
| 108 | |
| 109 | EmacsView : NSView <TextInput> |
| 110 | - handles rendering of text and fringe, interapp comms for drag/drop |
| 111 | - instance for each frame |
| 112 | - child of window's content view |
| 113 | - nsterm.m |
| 114 | |
| 115 | EmacsWindow : NSWindow |
| 116 | - utility override for resize handling |
| 117 | |
| 118 | EmacsScroller : NSScroller |
| 119 | - instance for each emacs window, renders scrollbar |
| 120 | - child of window's content view |
| 121 | - nsterm.m |
| 122 | |
| 123 | EmacsImage : NSImage |
| 124 | - image rendering, toolbar icons, stippling, fringe bitmaps |
| 125 | - instance for each image |
| 126 | - nsimage.m |
| 127 | |
| 128 | EmacsMenu : NSMenu |
| 129 | - menu management |
| 130 | - one tree of instances for menubar, one instance for each popup menu |
| 131 | - nsmenu.m |
| 132 | |
| 133 | EmacsToolbar : NSToolbar |
| 134 | - toolbar management, one instance for each frame |
| 135 | - nsmenu.m |
| 136 | |
| 137 | |
| 138 | EmacsDialogPanel : NSPanel |
| 139 | - popup dialogs, one instance for each |
| 140 | - nsmenu.m |
| 141 | |
| 142 | EmacsTooltip : NSObject |
| 143 | - tooltip popups, one instance for each |
| 144 | - nsmenu.m |
| 145 | |
| 146 | EmacsGlyphStorage : NSObject <NSGlyphStorage> |
| 147 | - utility for text rendering |
| 148 | - nsfont.m |
| 149 | |
| 150 | EmacsPrefsController : NSObject |
| 151 | - utility for preferences panel management, one global instance |
| 152 | - nsterm.m |
| 153 | - nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib |
| 154 | - nextstep/GNUstep/Emacs.base/Resources/preferences.gorm |
| 155 | |
| 156 | EmacsSavePanel : NSSavePanel |
| 157 | EmacsOpenPanel : NSOpenPanel |
| 158 | - utility override for panel notifications |