Commit | Line | Data |
---|---|---|
ff11dfa1 | 1 | /* Define frame-object for GNU Emacs. |
e5d77022 | 2 | Copyright (C) 1988, 1992 Free Software Foundation, Inc. |
efa4ce8b JB |
3 | |
4 | This file is part of GNU Emacs. | |
5 | ||
6 | GNU Emacs is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
e5d77022 | 8 | the Free Software Foundation; either version 2, or (at your option) |
efa4ce8b JB |
9 | any later version. |
10 | ||
11 | GNU Emacs is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU Emacs; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | ||
20 | ||
ff11dfa1 | 21 | /* The structure representing a frame. |
e5d77022 | 22 | |
ff11dfa1 JB |
23 | We declare this even if MULTI_FRAME is not defined, because when |
24 | we lack multi-frame support, we use one instance of this structure | |
25 | to represent the one frame we support. This is cleaner than | |
e5d77022 | 26 | having miscellaneous random variables scattered about. */ |
efa4ce8b JB |
27 | |
28 | enum output_method | |
29 | { output_termcap, output_x_window }; | |
30 | ||
ff11dfa1 | 31 | struct frame |
efa4ce8b JB |
32 | { |
33 | int size; | |
34 | struct Lisp_Vector *next; | |
35 | ||
ff11dfa1 JB |
36 | /* glyphs as they appear on the frame */ |
37 | struct frame_glyphs *current_glyphs; | |
efa4ce8b | 38 | |
ff11dfa1 JB |
39 | /* glyphs we'd like to appear on the frame */ |
40 | struct frame_glyphs *desired_glyphs; | |
efa4ce8b | 41 | |
e5d77022 | 42 | /* See do_line_insertion_deletion_costs for info on these arrays. */ |
ff11dfa1 | 43 | /* Cost of inserting 1 line on this frame */ |
efa4ce8b | 44 | int *insert_line_cost; |
ff11dfa1 | 45 | /* Cost of deleting 1 line on this frame */ |
efa4ce8b | 46 | int *delete_line_cost; |
ff11dfa1 | 47 | /* Cost of inserting n lines on this frame */ |
efa4ce8b | 48 | int *insert_n_lines_cost; |
ff11dfa1 | 49 | /* Cost of deleting n lines on this frame */ |
efa4ce8b JB |
50 | int *delete_n_lines_cost; |
51 | ||
52 | /* glyphs for the mode line */ | |
ff11dfa1 | 53 | struct frame_glyphs *temp_glyphs; |
efa4ce8b | 54 | |
ff11dfa1 | 55 | /* Intended cursor position of this frame. |
efa4ce8b | 56 | Measured in characters, counting from upper left corner |
ff11dfa1 | 57 | within the frame. */ |
efa4ce8b JB |
58 | int cursor_x; |
59 | int cursor_y; | |
60 | ||
ff11dfa1 JB |
61 | /* Actual cursor position of this frame, and the character under it. |
62 | (Not used for terminal frames.) */ | |
efa4ce8b JB |
63 | int phys_cursor_x; |
64 | int phys_cursor_y; | |
265a9e55 JB |
65 | /* This is handy for undrawing the cursor, because current_glyphs is |
66 | not always accurate when in do_scrolling. */ | |
67 | GLYPH phys_cursor_glyph; | |
efa4ce8b | 68 | |
ff11dfa1 | 69 | /* Size of this frame, in units of characters. */ |
efa4ce8b JB |
70 | int height; |
71 | int width; | |
72 | ||
73 | /* New height and width for pending size change. 0 if no change pending. */ | |
74 | int new_height, new_width; | |
75 | ||
fbfed6f0 | 76 | /* Name of this frame: a Lisp string. See also `explicit_name'. */ |
efa4ce8b JB |
77 | Lisp_Object name; |
78 | ||
ff11dfa1 JB |
79 | /* The frame which should recieve keystrokes that occur in this |
80 | frame. This is usually the frame itself, but if the frame is | |
81 | minibufferless, this points to the minibuffer frame when it is | |
0f79a4ae | 82 | active. */ |
ff11dfa1 | 83 | Lisp_Object focus_frame; |
0f79a4ae | 84 | |
ff11dfa1 JB |
85 | /* This frame's root window. Every frame has one. |
86 | If the frame has only a minibuffer window, this is it. | |
87 | Otherwise, if the frame has a minibuffer window, this is its sibling. */ | |
efa4ce8b JB |
88 | Lisp_Object root_window; |
89 | ||
ff11dfa1 JB |
90 | /* This frame's selected window. |
91 | Each frame has its own window hierarchy | |
92 | and one of the windows in it is selected within the frame. | |
93 | The selected window of the selected frame is Emacs's selected window. */ | |
efa4ce8b JB |
94 | Lisp_Object selected_window; |
95 | ||
ff11dfa1 JB |
96 | /* This frame's minibuffer window. |
97 | Most frames have their own minibuffer windows, | |
98 | but only the selected frame's minibuffer window | |
efa4ce8b JB |
99 | can actually appear to exist. */ |
100 | Lisp_Object minibuffer_window; | |
101 | ||
ff11dfa1 JB |
102 | /* Parameter alist of this frame. |
103 | These are the parameters specified when creating the frame | |
104 | or modified with modify-frame-parameters. */ | |
efa4ce8b JB |
105 | Lisp_Object param_alist; |
106 | ||
ff11dfa1 | 107 | /* The output method says how the contents of this frame |
efa4ce8b JB |
108 | are displayed. It could be using termcap, or using an X window. */ |
109 | enum output_method output_method; | |
110 | ||
111 | /* A structure of auxiliary data used for displaying the contents. | |
ff11dfa1 | 112 | struct x_display is used for X window frames; |
efa4ce8b JB |
113 | it is defined in xterm.h. */ |
114 | union display { struct x_display *x; int nothing; } display; | |
115 | ||
ff11dfa1 | 116 | /* Nonzero if last attempt at redisplay on this frame was preempted. */ |
efa4ce8b JB |
117 | char display_preempted; |
118 | ||
ff11dfa1 | 119 | /* Nonzero if frame is currently displayed. */ |
efa4ce8b JB |
120 | char visible; |
121 | ||
122 | /* Nonzero if window is currently iconified. | |
123 | This and visible are mutually exclusive. */ | |
124 | char iconified; | |
125 | ||
ff11dfa1 | 126 | /* Nonzero if this frame should be redrawn. */ |
efa4ce8b JB |
127 | char garbaged; |
128 | ||
ff11dfa1 JB |
129 | /* True if frame actually has a minibuffer window on it. |
130 | 0 if using a minibuffer window that isn't on this frame. */ | |
efa4ce8b JB |
131 | char has_minibuffer; |
132 | ||
ff11dfa1 | 133 | /* 0 means, if this frame has just one window, |
efa4ce8b JB |
134 | show no modeline for that window. */ |
135 | char wants_modeline; | |
136 | ||
ff11dfa1 | 137 | /* Non-0 means raise this frame to the top of the heap when selected. */ |
efa4ce8b JB |
138 | char auto_raise; |
139 | ||
ff11dfa1 | 140 | /* Non-0 means lower this frame to the bottom of the stack when left. */ |
efa4ce8b JB |
141 | char auto_lower; |
142 | ||
ff11dfa1 | 143 | /* True if frame's root window can't be split. */ |
efa4ce8b JB |
144 | char no_split; |
145 | ||
fbfed6f0 JB |
146 | /* If this is set, then Emacs won't change the frame name to indicate |
147 | the current buffer, etcetera. If the user explicitly sets the frame | |
148 | name, this gets set. If the user sets the name to Qnil, this is | |
149 | cleared. */ | |
150 | char explicit_name; | |
151 | ||
ff11dfa1 | 152 | /* Storage for messages to this frame. */ |
efa4ce8b JB |
153 | char *message_buf; |
154 | ||
155 | /* Nonnegative if current redisplay should not do scroll computation | |
156 | for lines beyond a certain vpos. This is the vpos. */ | |
157 | int scroll_bottom_vpos; | |
158 | }; | |
159 | ||
ff11dfa1 JB |
160 | #ifdef MULTI_FRAME |
161 | ||
162 | typedef struct frame *FRAME_PTR; | |
163 | ||
164 | #define XFRAME(p) ((struct frame *) XPNTR (p)) | |
165 | #define XSETFRAME(p, v) ((struct frame *) XSETPNTR (p, v)) | |
166 | ||
167 | #define WINDOW_FRAME(w) (w)->frame | |
168 | ||
169 | #define FRAMEP(f) (XTYPE(f) == Lisp_Frame) | |
170 | #define FRAME_LIVE_P(f) ((f)->display.nothing != 0) | |
10a4cc63 JB |
171 | #define FRAME_TERMCAP_P(f) ((f)->output_method == output_termcap) |
172 | #define FRAME_X_P(f) ((f)->output_method == output_x_window) | |
ff11dfa1 JB |
173 | #define FRAME_MINIBUF_ONLY_P(f) \ |
174 | EQ (FRAME_ROOT_WINDOW (f), FRAME_MINIBUF_WINDOW (f)) | |
10a4cc63 | 175 | #define FRAME_HAS_MINIBUF_P(f) ((f)->has_minibuffer) |
ff11dfa1 JB |
176 | #define FRAME_CURRENT_GLYPHS(f) (f)->current_glyphs |
177 | #define FRAME_DESIRED_GLYPHS(f) (f)->desired_glyphs | |
178 | #define FRAME_TEMP_GLYPHS(f) (f)->temp_glyphs | |
179 | #define FRAME_HEIGHT(f) (f)->height | |
180 | #define FRAME_WIDTH(f) (f)->width | |
181 | #define FRAME_NEW_HEIGHT(f) (f)->new_height | |
182 | #define FRAME_NEW_WIDTH(f) (f)->new_width | |
183 | #define FRAME_CURSOR_X(f) (f)->cursor_x | |
184 | #define FRAME_CURSOR_Y(f) (f)->cursor_y | |
185 | #define FRAME_VISIBLE_P(f) (f)->visible | |
186 | #define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1) | |
187 | #define FRAME_GARBAGED_P(f) (f)->garbaged | |
188 | #define FRAME_NO_SPLIT_P(f) (f)->no_split | |
189 | #define FRAME_WANTS_MODELINE_P(f) (f)->wants_modeline | |
190 | #define FRAME_ICONIFIED_P(f) (f)->iconified | |
191 | #define FRAME_MINIBUF_WINDOW(f) (f)->minibuffer_window | |
192 | #define FRAME_ROOT_WINDOW(f) (f)->root_window | |
193 | #define FRAME_SELECTED_WINDOW(f) (f)->selected_window | |
194 | #define SET_GLYPHS_FRAME(glyphs,frame) ((glyphs)->frame = (frame)) | |
195 | #define FRAME_INSERT_COST(f) (f)->insert_line_cost | |
196 | #define FRAME_DELETE_COST(f) (f)->delete_line_cost | |
197 | #define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost | |
198 | #define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost | |
199 | #define FRAME_MESSAGE_BUF(f) (f)->message_buf | |
200 | #define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos | |
201 | #define FRAME_FOCUS_FRAME(f) (f)->focus_frame | |
202 | ||
203 | #define CHECK_FRAME(x, i) \ | |
265a9e55 | 204 | { \ |
ff11dfa1 JB |
205 | if (! FRAMEP (x)) \ |
206 | x = wrong_type_argument (Qframep, (x)); \ | |
265a9e55 JB |
207 | } |
208 | ||
ff11dfa1 | 209 | #define CHECK_LIVE_FRAME(x, i) \ |
265a9e55 | 210 | { \ |
ff11dfa1 JB |
211 | if (! FRAMEP (x) \ |
212 | || ! FRAME_LIVE_P (XFRAME (x))) \ | |
213 | x = wrong_type_argument (Qlive_frame_p, (x)); \ | |
265a9e55 JB |
214 | } |
215 | ||
ff11dfa1 JB |
216 | /* FOR_EACH_FRAME (LIST_VAR, FRAME_VAR) followed by a statement is a |
217 | `for' loop which iterates over the elements of Vframe_list. The | |
218 | loop will set FRAME_VAR, a FRAME_PTR, to each frame in | |
219 | Vframe_list in succession and execute the statement. LIST_VAR | |
e5d77022 | 220 | should be a Lisp_Object; it is used to iterate through the |
ff11dfa1 | 221 | Vframe_list. |
e5d77022 | 222 | |
ff11dfa1 | 223 | If MULTI_FRAME isn't defined, then this loop expands to something which |
e5d77022 | 224 | executes the statement once. */ |
ff11dfa1 JB |
225 | #define FOR_EACH_FRAME(list_var, frame_var) \ |
226 | for ((list_var) = Vframe_list; \ | |
e5d77022 | 227 | (CONSP (list_var) \ |
ff11dfa1 | 228 | && (frame_var = XFRAME (XCONS (list_var)->car), 1)); \ |
e5d77022 JB |
229 | list_var = XCONS (list_var)->cdr) |
230 | ||
231 | ||
ff11dfa1 | 232 | extern Lisp_Object Qframep, Qlive_frame_p; |
efa4ce8b | 233 | |
ff11dfa1 JB |
234 | extern struct frame *selected_frame; |
235 | extern struct frame *last_nonminibuf_frame; | |
efa4ce8b | 236 | |
ff11dfa1 JB |
237 | extern struct frame *make_terminal_frame (); |
238 | extern struct frame *make_frame (); | |
239 | extern struct frame *make_minibuffer_frame (); | |
240 | extern struct frame *make_frame_without_minibuffer (); | |
efa4ce8b | 241 | |
ff11dfa1 | 242 | /* Nonzero means FRAME_MESSAGE_BUF (selected_frame) is being used by |
e5d77022 JB |
243 | print. */ |
244 | extern int message_buf_print; | |
245 | ||
ff11dfa1 JB |
246 | extern Lisp_Object Vframe_list; |
247 | extern Lisp_Object Vdefault_frame_alist; | |
efa4ce8b | 248 | |
ff11dfa1 | 249 | extern Lisp_Object Vterminal_frame; |
efa4ce8b | 250 | \f |
ff11dfa1 | 251 | #else /* not MULTI_FRAME */ |
efa4ce8b | 252 | |
ff11dfa1 | 253 | /* These definitions are used in a single-frame version of Emacs. */ |
efa4ce8b | 254 | |
ff11dfa1 | 255 | #define FRAME_PTR int |
efa4ce8b | 256 | |
ce4e9d43 JB |
257 | /* A frame we use to store all the data concerning the screen when we |
258 | don't have multiple frames. Remember, if you store any data in it | |
259 | which needs to be protected from GC, you should staticpro that | |
260 | element explicitly. */ | |
ff11dfa1 | 261 | extern struct frame the_only_frame; |
e5d77022 | 262 | |
ff11dfa1 JB |
263 | extern int selected_frame; |
264 | extern int last_nonminibuf_frame; | |
e5d77022 | 265 | |
ff11dfa1 | 266 | /* Nonzero means FRAME_MESSAGE_BUF (selected_frame) is being used by |
e5d77022 JB |
267 | print. */ |
268 | extern int message_buf_print; | |
efa4ce8b | 269 | |
ff11dfa1 JB |
270 | #define XFRAME(f) selected_frame |
271 | #define WINDOW_FRAME(w) selected_frame | |
272 | ||
273 | #define FRAMEP(f) (XTYPE(f) == Lisp_Frame) | |
274 | #define FRAME_LIVE_P(f) 1 | |
10a4cc63 JB |
275 | #define FRAME_TERMCAP_P(f) 1 |
276 | #define FRAME_X_P(f) 0 | |
ff11dfa1 | 277 | #define FRAME_MINIBUF_ONLY_P(f) 0 |
10a4cc63 | 278 | #define FRAME_HAS_MINIBUF_P(f) 1 |
ce4e9d43 JB |
279 | #define FRAME_CURRENT_GLYPHS(f) (the_only_frame.current_glyphs) |
280 | #define FRAME_DESIRED_GLYPHS(f) (the_only_frame.desired_glyphs) | |
281 | #define FRAME_TEMP_GLYPHS(f) (the_only_frame.temp_glyphs) | |
282 | #define FRAME_HEIGHT(f) (the_only_frame.height) | |
283 | #define FRAME_WIDTH(f) (the_only_frame.width) | |
284 | #define FRAME_NEW_HEIGHT(f) (the_only_frame.new_height) | |
285 | #define FRAME_NEW_WIDTH(f) (the_only_frame.new_width) | |
286 | #define FRAME_CURSOR_X(f) (the_only_frame.cursor_x) | |
287 | #define FRAME_CURSOR_Y(f) (the_only_frame.cursor_y) | |
ff11dfa1 JB |
288 | #define FRAME_VISIBLE_P(f) 1 |
289 | #define SET_FRAME_GARBAGED(f) (frame_garbaged = 1) | |
ce4e9d43 | 290 | #define FRAME_GARBAGED_P(f) (frame_garbaged) |
ff11dfa1 JB |
291 | #define FRAME_NO_SPLIT_P(f) 0 |
292 | #define FRAME_WANTS_MODELINE_P(f) 1 | |
293 | #define FRAME_ICONIFIED_P(f) 0 | |
fbfed6f0 JB |
294 | #define FRAME_MINIBUF_WINDOW(f) (the_only_frame.root_window) |
295 | #define FRAME_ROOT_WINDOW(f) (the_only_frame.root_window) | |
ce4e9d43 JB |
296 | #define FRAME_SELECTED_WINDOW(f) (selected_window) |
297 | #define SET_GLYPHS_FRAME(glyphs,frame) do ; while (0) | |
298 | #define FRAME_INSERT_COST(frame) (the_only_frame.insert_line_cost) | |
299 | #define FRAME_DELETE_COST(frame) (the_only_frame.delete_line_cost) | |
300 | #define FRAME_INSERTN_COST(frame) (the_only_frame.insert_n_lines_cost) | |
301 | #define FRAME_DELETEN_COST(frame) (the_only_frame.delete_n_lines_cost) | |
302 | #define FRAME_MESSAGE_BUF(f) (the_only_frame.message_buf) | |
303 | #define FRAME_SCROLL_BOTTOM_VPOS(f) (the_only_frame.scroll_bottom_vpos) | |
304 | #define FRAME_FOCUS_FRAME(f) (0) | |
ff11dfa1 | 305 | |
10a4cc63 JB |
306 | #define CHECK_FRAME(x, i) do; while (0) |
307 | #define CHECK_LIVE_FRAME(x, y) do; while (0) | |
ff11dfa1 JB |
308 | |
309 | /* FOR_EACH_FRAME (LIST_VAR, FRAME_VAR) followed by a statement is a | |
310 | `for' loop which iterates over the elements of Vframe_list. The | |
311 | loop will set FRAME_VAR, a FRAME_PTR, to each frame in | |
312 | Vframe_list in succession and execute the statement. LIST_VAR | |
e5d77022 | 313 | should be a Lisp_Object; it is used to iterate through the |
ff11dfa1 | 314 | Vframe_list. |
e5d77022 | 315 | |
ff11dfa1 JB |
316 | If MULTI_FRAME _is_ defined, then this loop expands to a real |
317 | `for' loop which traverses Vframe_list using LIST_VAR and | |
318 | FRAME_VAR. */ | |
319 | #define FOR_EACH_FRAME(list_var, frame_var) \ | |
320 | for (frame_var = (FRAME_PTR) 1; frame_var; frame_var = (FRAME_PTR) 0) | |
efa4ce8b | 321 | |
ff11dfa1 | 322 | #endif /* not MULTI_FRAME */ |