Commit | Line | Data |
---|---|---|
7630ec39 AR |
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. One area for exploration is the | |
68 | NO_SOCK_SIGIO define. When it is defined, ctrl-g seems to be picked up more | |
69 | often, but there are some annoying side effects. Currently it is left off by | |
70 | default, unless the --enable-cocoa-experimental-ctrl-g option is passed to | |
71 | configure. (Has no effect under GNUstep.) This is an area for improvement. | |
72 | Also, see the article here and its containing thread: | |
73 | ||
74 | http://article.gmane.org/gmane.emacs.devel/92021/match=handling%5fsignal | |
75 | ||
76 | ||
77 | ||
78 | ||
79 | Text Rendering and Font Handling | |
80 | -------------------------------- | |
81 | ||
82 | nsfont.m implements the font driver, responsible for managing fonts and | |
83 | rendering text. Fonts are obtained through NSFontManager. Rendering must be | |
84 | done at a low level due to emacs' fine control over this process, therefore | |
85 | there are different approachs under Cocoa and GNUstep. Under GNUstep, the | |
86 | original NeXT Display PostScript (DPS) APIs are available and used. Under | |
87 | Cocoa, these were removed and Quartz drawing functions replaced them. | |
88 | ||
89 | In both cases, font glyphs are accessed through UTF8 character | |
90 | representations. It would be preferable to use unicode indices, but prior | |
91 | attempts at this have failed. | |
92 | ||
93 | Multi-script fontsets are auto-created in nsfont_make_fontset_for_font() using | |
94 | the facilities of NSTextStorage and NSLayoutManager. | |
95 | ||
96 | ||
97 | Object Architecture | |
98 | ------------------- | |
99 | ||
100 | Unlike the other GUIs, the NS interface is based on a high-level and | |
101 | object-oriented API. This creates some tension in the code because emacs | |
102 | itself has been architected around the low-level Xlib and Xt APIs. The NS | |
103 | port tries to strike a balance between simplifying code on its side using OO | |
104 | features, and keeping code as similar as possible to other ports to ease | |
105 | maintenance. The following are the main classes (see nsterm.h): | |
106 | ||
107 | EmacsApp : NSApplication | |
108 | - event loop integration, interapp comms point for Finder (NSWorkspace) msgs, | |
109 | Services | |
110 | - one global instance (NSApp) | |
111 | - nsterm.m | |
112 | ||
113 | EmacsView : NSView <TextInput> | |
114 | - handles rendering of text and fringe, interapp comms for drag/drop | |
115 | - instance for each frame | |
116 | - child of window's content view | |
117 | - nsterm.m | |
118 | ||
119 | EmacsWindow : NSWindow | |
120 | - utility override for resize handling | |
121 | ||
122 | EmacsScroller : NSScroller | |
123 | - instance for each emacs window, renders scrollbar | |
124 | - child of window's content view | |
125 | - nsterm.m | |
126 | ||
127 | EmacsImage : NSImage | |
128 | - image rendering, toolbar icons, stippling, fringe bitmaps | |
129 | - instance for each image | |
130 | - nsimage.m | |
131 | ||
132 | EmacsMenu : NSMenu | |
133 | - menu management | |
134 | - one tree of instances for menubar, one instance for each popup menu | |
135 | - nsmenu.m | |
136 | ||
137 | EmacsToolbar : NSToolbar | |
138 | - toolbar management, one instance for each frame | |
139 | - nsmenu.m | |
140 | ||
141 | ||
142 | EmacsDialogPanel : NSPanel | |
143 | - popup dialogs, one instance for each | |
144 | - nsmenu.m | |
145 | ||
146 | EmacsTooltip : NSObject | |
147 | - tooltip popups, one instance for each | |
148 | - nsmenu.m | |
149 | ||
150 | EmacsGlyphStorage : NSObject <NSGlyphStorage> | |
151 | - utility for text rendering | |
152 | - nsfont.m | |
153 | ||
154 | EmacsPrefsController : NSObject | |
155 | - utility for preferences panel management, one global instance | |
156 | - nsterm.m | |
157 | - nextstep/Cocoa/Emacs.base/Contents/Resources/preferences.nib | |
158 | - nextstep/GNUstep/Emacs.base/Resources/preferences.gorm | |
159 | ||
160 | EmacsSavePanel : NSSavePanel | |
161 | EmacsOpenPanel : NSOpenPanel | |
162 | - utility override for panel notifications | |
163 |