(Hopefully) fix bootstrap error on OpenBSD. (reported by Han Boetes)
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
0b5538bd
TTN
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005 Free Software Foundation, Inc.
dc6f92b8
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
1113d9db 9the Free Software Foundation; either version 2, or (at your option)
dc6f92b8
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
dc6f92b8 21
18160b98 22#include <config.h>
565620a5
RS
23
24#include <stdio.h>
cc38027b 25#include "lisp.h"
71025e5e 26#include "charset.h"
6d55d620 27#ifdef HAVE_X_WINDOWS
dfcf069d 28#include "xterm.h"
71025e5e 29#endif
8f23f280
AI
30#ifdef WINDOWSNT
31#include "w32term.h"
32#endif
e0f712ba 33#ifdef MAC_OS
1a578e9b
AC
34#include "macterm.h"
35#endif
2538fae4
AI
36#include "buffer.h"
37/* These help us bind and responding to switch-frame events. */
38#include "commands.h"
39#include "keyboard.h"
cc38027b 40#include "frame.h"
a1dfb88a
KH
41#ifdef HAVE_WINDOW_SYSTEM
42#include "fontset.h"
43#endif
972f4259 44#include "blockinput.h"
28d440ab 45#include "termchar.h"
bc1ed486 46#include "termhooks.h"
dfcf069d 47#include "dispextern.h"
f769f1b2 48#include "window.h"
87485d6f
MW
49#ifdef MSDOS
50#include "msdos.h"
4aec4b29 51#include "dosfns.h"
87485d6f 52#endif
e5d77022 53
972f4259 54
2731a0ad
KS
55#ifdef HAVE_WINDOW_SYSTEM
56
972f4259
KS
57/* The name we're using in resource queries. Most often "emacs". */
58
59Lisp_Object Vx_resource_name;
60
61/* The application class we're using in resource queries.
62 Normally "Emacs". */
63
64Lisp_Object Vx_resource_class;
65
2731a0ad 66#endif
972f4259
KS
67
68Lisp_Object Qframep, Qframe_live_p;
69Lisp_Object Qicon, Qmodeline;
fd0c2bd1 70Lisp_Object Qonly;
972f4259 71Lisp_Object Qx, Qw32, Qmac, Qpc;
f7af3f7b 72Lisp_Object Qvisible;
8b60f7bc 73Lisp_Object Qdisplay_type;
6345f6aa 74Lisp_Object Qbackground_mode;
3df1fda2 75Lisp_Object Qinhibit_default_face_x_resources;
972f4259
KS
76
77Lisp_Object Qx_frame_parameter;
78Lisp_Object Qx_resource_name;
6ed8eeff
KL
79Lisp_Object Qterminal;
80Lisp_Object Qterminal_live_p;
972f4259
KS
81
82/* Frame parameters (set or reported). */
83
84Lisp_Object Qauto_raise, Qauto_lower;
85Lisp_Object Qborder_color, Qborder_width;
86Lisp_Object Qcursor_color, Qcursor_type;
87Lisp_Object Qgeometry; /* Not used */
88Lisp_Object Qheight, Qwidth;
89Lisp_Object Qleft, Qright;
90Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
91Lisp_Object Qinternal_border_width;
92Lisp_Object Qmouse_color;
93Lisp_Object Qminibuffer;
94Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
95Lisp_Object Qvisibility;
96Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
97Lisp_Object Qscreen_gamma;
98Lisp_Object Qline_spacing;
99Lisp_Object Quser_position, Quser_size;
100Lisp_Object Qwait_for_wm;
101Lisp_Object Qwindow_id;
102#ifdef HAVE_X_WINDOWS
103Lisp_Object Qouter_window_id;
104#endif
105Lisp_Object Qparent_id;
106Lisp_Object Qtitle, Qname;
107Lisp_Object Qunsplittable;
108Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
109Lisp_Object Qleft_fringe, Qright_fringe;
a18b8cb5 110Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
94674d18 111Lisp_Object Qtty_color_mode;
28d440ab 112Lisp_Object Qtty, Qtty_type;
7f19e125 113Lisp_Object Qwindow_system;
da8e8fc1 114Lisp_Object Qenvironment;
dc6f92b8 115
972f4259
KS
116Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
117
118Lisp_Object Qface_set_after_frame_default;
119
daf01701 120Lisp_Object Vterminal_frame;
a1aaa23f 121Lisp_Object Vdefault_frame_alist;
a6e20602 122Lisp_Object Vdefault_frame_scroll_bars;
beb0bc36 123Lisp_Object Vmouse_position_function;
6018080f 124Lisp_Object Vmouse_highlight;
cd1d850f 125Lisp_Object Vdelete_frame_functions;
a249de79
RS
126\f
127static void
128set_menu_bar_lines_1 (window, n)
daf01701
KL
129 Lisp_Object window;
130 int n;
a249de79
RS
131{
132 struct window *w = XWINDOW (window);
133
57aeea1e 134 XSETFASTINT (w->last_modified, 0);
5af5757b
KS
135 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
136 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
177c0ea7 137
5af5757b
KS
138 if (INTEGERP (w->orig_top_line))
139 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
140 if (INTEGERP (w->orig_total_lines))
141 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
a249de79
RS
142
143 /* Handle just the top child in a vertical split. */
144 if (!NILP (w->vchild))
145 set_menu_bar_lines_1 (w->vchild, n);
146
147 /* Adjust all children in a horizontal split. */
148 for (window = w->hchild; !NILP (window); window = w->next)
149 {
150 w = XWINDOW (window);
151 set_menu_bar_lines_1 (window, n);
152 }
153}
154
e48f782c 155void
a249de79
RS
156set_menu_bar_lines (f, value, oldval)
157 struct frame *f;
158 Lisp_Object value, oldval;
159{
160 int nlines;
161 int olines = FRAME_MENU_BAR_LINES (f);
162
163 /* Right now, menu bars don't work properly in minibuf-only frames;
164 most of the commands try to apply themselves to the minibuffer
e3678b64 165 frame itself, and get an error because you can't switch buffers
a249de79
RS
166 in or split the minibuffer window. */
167 if (FRAME_MINIBUF_ONLY_P (f))
168 return;
169
170 if (INTEGERP (value))
171 nlines = XINT (value);
172 else
173 nlines = 0;
174
57aeea1e
RS
175 if (nlines != olines)
176 {
177 windows_or_buffers_changed++;
178 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
179 FRAME_MENU_BAR_LINES (f) = nlines;
180 set_menu_bar_lines_1 (f->root_window, nlines - olines);
18082e2d 181 adjust_glyphs (f);
57aeea1e 182 }
a249de79
RS
183}
184\f
a249de79
RS
185Lisp_Object Vemacs_iconified;
186Lisp_Object Vframe_list;
a249de79 187
dc6f92b8
JB
188extern Lisp_Object Vminibuffer_list;
189extern Lisp_Object get_minibuffer ();
84386599
RS
190extern Lisp_Object Fhandle_switch_frame ();
191extern Lisp_Object Fredirect_frame_focus ();
a54d3a73 192extern Lisp_Object x_get_focus_frame ();
dc6f92b8 193\f
ff11dfa1 194DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
14ff1ee0
PJ
195 doc: /* Return non-nil if OBJECT is a frame.
196Value is t for a termcap frame (a character-only terminal),
197`x' for an Emacs frame that is really an X window,
198`w32' for an Emacs frame that is a window on MS-Windows display,
199`mac' for an Emacs frame on a Macintosh display,
200`pc' for a direct-write MS-DOS frame.
201See also `frame-live-p'. */)
202 (object)
f9898cc6 203 Lisp_Object object;
dc6f92b8 204{
e35d291d 205 if (!FRAMEP (object))
dc6f92b8 206 return Qnil;
ff11dfa1 207 switch (XFRAME (object)->output_method)
dc6f92b8 208 {
3224dac1 209 case output_initial: /* The initial frame is like a termcap frame. */
dc6f92b8
JB
210 case output_termcap:
211 return Qt;
212 case output_x_window:
fd0c2bd1 213 return Qx;
fbd6baed
GV
214 case output_w32:
215 return Qw32;
bb221971
RS
216 case output_msdos_raw:
217 return Qpc;
574a1a90
RS
218 case output_mac:
219 return Qmac;
dc6f92b8
JB
220 default:
221 abort ();
222 }
223}
224
dbc4e1c1 225DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
14ff1ee0
PJ
226 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
227Value is nil if OBJECT is not a live frame. If object is a live
6ed8eeff 228frame, the return value indicates what sort of terminal device it is
f6fa0866 229displayed on. See the documentation of `framep' for possible
4e10df59 230return values. */)
14ff1ee0 231 (object)
f9898cc6
JB
232 Lisp_Object object;
233{
ff11dfa1
JB
234 return ((FRAMEP (object)
235 && FRAME_LIVE_P (XFRAME (object)))
236 ? Fframep (object)
f9898cc6
JB
237 : Qnil);
238}
239
428a555e
KL
240DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
241 doc: /* The name of the window system that FRAME is displaying through.
242The value is a symbol---for instance, 'x' for X windows.
243The value is nil if Emacs is using a text-only terminal.
244
245FRAME defaults to the currently selected frame. */)
246 (frame)
247 Lisp_Object frame;
248{
249 Lisp_Object type;
250 if (NILP (frame))
251 frame = selected_frame;
252
253 type = Fframep (frame);
254
255 if (NILP (type))
256 wrong_type_argument (Qframep, frame);
257
258 if (EQ (type, Qt))
259 return Qnil;
260 else
261 return type;
262}
263
ff11dfa1
JB
264struct frame *
265make_frame (mini_p)
dc6f92b8
JB
266 int mini_p;
267{
ff11dfa1
JB
268 Lisp_Object frame;
269 register struct frame *f;
dc6f92b8
JB
270 register Lisp_Object root_window;
271 register Lisp_Object mini_window;
e9c96c62
GM
272
273 f = allocate_frame ();
36af7d69 274 XSETFRAME (frame, f);
ff11dfa1 275
18082e2d
GM
276 f->desired_matrix = 0;
277 f->current_matrix = 0;
278 f->desired_pool = 0;
279 f->current_pool = 0;
280 f->glyphs_initialized_p = 0;
281 f->decode_mode_spec_buffer = 0;
ff11dfa1 282 f->visible = 0;
323405de 283 f->async_visible = 0;
7556890b 284 f->output_data.nothing = 0;
ff11dfa1 285 f->iconified = 0;
323405de 286 f->async_iconified = 0;
ff11dfa1
JB
287 f->wants_modeline = 1;
288 f->auto_raise = 0;
289 f->auto_lower = 0;
290 f->no_split = 0;
10689a01 291 f->garbaged = 1;
ff11dfa1 292 f->has_minibuffer = mini_p;
a42e9724 293 f->focus_frame = Qnil;
804518aa 294 f->explicit_name = 0;
fd2777e0 295 f->can_have_scroll_bars = 0;
3a43d2dd 296 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
ff11dfa1 297 f->param_alist = Qnil;
fd2777e0
JB
298 f->scroll_bars = Qnil;
299 f->condemned_scroll_bars = Qnil;
306cc902 300 f->face_alist = Qnil;
18082e2d 301 f->face_cache = NULL;
9dd935ee 302 f->menu_bar_items = Qnil;
c8b8e7e3
RS
303 f->menu_bar_vector = Qnil;
304 f->menu_bar_items_used = 0;
329ca574 305 f->buffer_predicate = Qnil;
fa54c6ae 306 f->buffer_list = Qnil;
a18b8cb5 307 f->buried_buffer_list = Qnil;
aec6e486 308 f->namebuf = 0;
2b1c9cfb 309 f->title = Qnil;
18082e2d 310 f->menu_bar_window = Qnil;
9ea173e8 311 f->tool_bar_window = Qnil;
61752261 312 f->tool_bar_items = Qnil;
9ea173e8 313 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
61752261 314 f->n_tool_bar_items = 0;
5af5757b
KS
315 f->left_fringe_width = f->right_fringe_width = 0;
316 f->fringe_cols = 0;
317 f->scroll_bar_actual_width = 0;
318 f->border_width = 0;
319 f->internal_border_width = 0;
320 f->column_width = 1; /* !FRAME_WINDOW_P value */
321 f->line_height = 1; /* !FRAME_WINDOW_P value */
322 f->x_pixels_diff = f->y_pixels_diff = 0;
93421a1f 323#ifdef HAVE_WINDOW_SYSTEM
5af5757b 324 f->want_fullscreen = FULLSCREEN_NONE;
93421a1f 325#endif
5af5757b
KS
326 f->size_hint_flags = 0;
327 f->win_gravity = 0;
dc6f92b8 328
cc38027b 329 root_window = make_window ();
dc6f92b8
JB
330 if (mini_p)
331 {
cc38027b 332 mini_window = make_window ();
dc6f92b8
JB
333 XWINDOW (root_window)->next = mini_window;
334 XWINDOW (mini_window)->prev = root_window;
335 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
336 XWINDOW (mini_window)->frame = frame;
337 f->minibuffer_window = mini_window;
dc6f92b8
JB
338 }
339 else
340 {
341 mini_window = Qnil;
342 XWINDOW (root_window)->next = Qnil;
ff11dfa1 343 f->minibuffer_window = Qnil;
dc6f92b8
JB
344 }
345
ff11dfa1 346 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
347
348 /* 10 is arbitrary,
349 just so that there is "something there."
ff11dfa1 350 Correct size will be set up later with change_frame_size. */
dc6f92b8 351
5af5757b
KS
352 SET_FRAME_COLS (f, 10);
353 FRAME_LINES (f) = 10;
dc6f92b8 354
5af5757b
KS
355 XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
356 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10));
dc6f92b8
JB
357
358 if (mini_p)
359 {
5af5757b
KS
360 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
361 XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
362 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1);
dc6f92b8
JB
363 }
364
ff11dfa1 365 /* Choose a buffer for the frame's root window. */
5bce042c
JB
366 {
367 Lisp_Object buf;
368
369 XWINDOW (root_window)->buffer = Qt;
370 buf = Fcurrent_buffer ();
371 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
372 a space), try to find another one. */
d5db4077 373 if (SREF (Fbuffer_name (buf), 0) == ' ')
98ce1622 374 buf = Fother_buffer (buf, Qnil, Qnil);
fa54c6ae 375
18082e2d
GM
376 /* Use set_window_buffer, not Fset_window_buffer, and don't let
377 hooks be run by it. The reason is that the whole frame/window
378 arrangement is not yet fully intialized at this point. Windows
379 don't have the right size, glyph matrices aren't initialized
380 etc. Running Lisp functions at this point surely ends in a
381 SEGV. */
5af5757b 382 set_window_buffer (root_window, buf, 0, 0);
fa54c6ae 383 f->buffer_list = Fcons (buf, Qnil);
5bce042c
JB
384 }
385
dc6f92b8
JB
386 if (mini_p)
387 {
388 XWINDOW (mini_window)->buffer = Qt;
18082e2d
GM
389 set_window_buffer (mini_window,
390 (NILP (Vminibuffer_list)
391 ? get_minibuffer (0)
392 : Fcar (Vminibuffer_list)),
5af5757b 393 0, 0);
dc6f92b8
JB
394 }
395
ff11dfa1
JB
396 f->root_window = root_window;
397 f->selected_window = root_window;
d5e7c279
JB
398 /* Make sure this window seems more recently used than
399 a newly-created, never-selected window. */
2a1893f4
SM
400 ++window_select_count;
401 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
dc6f92b8 402
a5f696ac
JD
403 f->default_face_done_p = 0;
404
ff11dfa1 405 return f;
dc6f92b8
JB
406}
407\f
bba88bb1 408#ifdef HAVE_WINDOW_SYSTEM
ff11dfa1 409/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
410 MINI_WINDOW is the minibuffer window to use. nil means use the
411 default (the global minibuffer). */
412
ff11dfa1 413struct frame *
b0660239 414make_frame_without_minibuffer (mini_window, kb, display)
dc6f92b8 415 register Lisp_Object mini_window;
662ac59a 416 KBOARD *kb;
b0660239 417 Lisp_Object display;
dc6f92b8 418{
ff11dfa1 419 register struct frame *f;
363b873b 420 struct gcpro gcpro1;
dc6f92b8 421
b0660239 422 if (!NILP (mini_window))
b7826503 423 CHECK_LIVE_WINDOW (mini_window);
dc6f92b8 424
662ac59a 425#ifdef MULTI_KBOARD
b0660239 426 if (!NILP (mini_window)
6ed8eeff
KL
427 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
428 error ("Frame and minibuffer must be on the same terminal");
662ac59a
KH
429#endif
430
ff11dfa1
JB
431 /* Make a frame containing just a root window. */
432 f = make_frame (0);
dc6f92b8 433
b0660239
KH
434 if (NILP (mini_window))
435 {
436 /* Use default-minibuffer-frame if possible. */
437 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
438 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
439 {
363b873b
RS
440 Lisp_Object frame_dummy;
441
442 XSETFRAME (frame_dummy, f);
443 GCPRO1 (frame_dummy);
b0660239 444 /* If there's no minibuffer frame to use, create one. */
363b873b
RS
445 kb->Vdefault_minibuffer_frame =
446 call1 (intern ("make-initial-minibuffer-frame"), display);
447 UNGCPRO;
b0660239 448 }
177c0ea7 449
b0660239
KH
450 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
451 }
a2812a26 452
ff11dfa1 453 f->minibuffer_window = mini_window;
a2812a26
RS
454
455 /* Make the chosen minibuffer window display the proper minibuffer,
456 unless it is already showing a minibuffer. */
457 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
458 Fset_window_buffer (mini_window,
459 (NILP (Vminibuffer_list)
460 ? get_minibuffer (0)
5af5757b 461 : Fcar (Vminibuffer_list)), Qnil);
ff11dfa1 462 return f;
dc6f92b8
JB
463}
464
ff11dfa1 465/* Make a frame containing only a minibuffer window. */
dc6f92b8 466
ff11dfa1
JB
467struct frame *
468make_minibuffer_frame ()
dc6f92b8 469{
ff11dfa1 470 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 471
ff11dfa1 472 register struct frame *f = make_frame (0);
dc6f92b8 473 register Lisp_Object mini_window;
ff11dfa1 474 register Lisp_Object frame;
dc6f92b8 475
2d80a27a 476 XSETFRAME (frame, f);
dc6f92b8 477
804518aa 478 f->auto_raise = 0;
ff11dfa1
JB
479 f->auto_lower = 0;
480 f->no_split = 1;
481 f->wants_modeline = 0;
482 f->has_minibuffer = 1;
dc6f92b8
JB
483
484 /* Now label the root window as also being the minibuffer.
485 Avoid infinite looping on the window chain by marking next pointer
486 as nil. */
487
ff11dfa1 488 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
489 XWINDOW (mini_window)->mini_p = Qt;
490 XWINDOW (mini_window)->next = Qnil;
804518aa 491 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 492 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
493
494 /* Put the proper buffer in that window. */
495
496 Fset_window_buffer (mini_window,
265a9e55 497 (NILP (Vminibuffer_list)
dc6f92b8 498 ? get_minibuffer (0)
5af5757b 499 : Fcar (Vminibuffer_list)), Qnil);
ff11dfa1 500 return f;
dc6f92b8 501}
bba88bb1 502#endif /* HAVE_WINDOW_SYSTEM */
dc6f92b8 503\f
28d440ab 504/* Construct a frame that refers to a terminal. */
dc6f92b8 505
6ed8eeff 506static int tty_frame_count;
bb1513c9 507
ff11dfa1 508struct frame *
3224dac1 509make_initial_frame (void)
dc6f92b8 510{
3224dac1 511 struct frame *f;
6ed8eeff 512 struct terminal *terminal;
d063751a 513 Lisp_Object frame;
3224dac1 514
b4f0ee5d 515#ifdef MULTI_KBOARD
7b00d185 516 /* Create the initial keyboard. */
b4f0ee5d
KH
517 if (!initial_kboard)
518 {
519 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
520 init_kboard (initial_kboard);
a1b658dd
KH
521 initial_kboard->next_kboard = all_kboards;
522 all_kboards = initial_kboard;
b4f0ee5d
KH
523 }
524#endif
525
bb1513c9
RS
526 /* The first call must initialize Vframe_list. */
527 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
528 Vframe_list = Qnil;
ff11dfa1 529
6ed8eeff 530 terminal = init_initial_terminal ();
3224dac1
KL
531
532 f = make_frame (1);
533 XSETFRAME (frame, f);
534
535 Vframe_list = Fcons (frame, Vframe_list);
536
6ed8eeff 537 tty_frame_count = 1;
3224dac1
KL
538 f->name = build_string ("F1");
539
540 f->visible = 1;
541 f->async_visible = 1;
542
6ed8eeff
KL
543 f->output_method = terminal->type;
544 f->terminal = terminal;
545 f->terminal->reference_count++;
3224dac1
KL
546 f->output_data.nothing = 0;
547
548 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
549 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
550
551 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
552 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
553
3224dac1
KL
554 return f;
555}
556
557
558struct frame *
6ed8eeff 559make_terminal_frame (struct terminal *terminal)
3224dac1
KL
560{
561 register struct frame *f;
3224dac1
KL
562 Lisp_Object frame;
563 char name[20];
564
ff11dfa1 565 f = make_frame (1);
d063751a 566
2d80a27a 567 XSETFRAME (frame, f);
d063751a
RS
568 Vframe_list = Fcons (frame, Vframe_list);
569
6ed8eeff
KL
570 tty_frame_count++;
571 sprintf (name, "F%d", tty_frame_count);
0303e8da 572 f->name = build_string (name);
bb1513c9 573
bb1513c9
RS
574 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
575 f->async_visible = 1; /* Don't let visible be cleared later. */
bb221971
RS
576#ifdef MSDOS
577 f->output_data.x = &the_only_x_display;
2d764c78
EZ
578 if (!inhibit_window_system
579 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
580 || XFRAME (selected_frame)->output_method == output_msdos_raw))
65606f5e
EZ
581 {
582 f->output_method = output_msdos_raw;
583 /* This initialization of foreground and background pixels is
584 only important for the initial frame created in temacs. If
585 we don't do that, we get black background and foreground in
586 the dumped Emacs because the_only_x_display is a static
587 variable, hence it is born all-zeroes, and zero is the code
588 for the black color. Other frames all inherit their pixels
589 from what's already in the_only_x_display. */
590 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
591 && f->output_data.x->background_pixel == 0
592 && f->output_data.x->foreground_pixel == 0)
593 {
594 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
595 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
596 }
597 }
2d764c78
EZ
598 else
599 f->output_method = output_termcap;
600#else
4ec0d3c1 601#ifdef WINDOWSNT
ff8d4bf4 602 f->output_method = output_termcap;
428a555e 603 f->output_data.x = &tty_display; /* XXX ??? */
4ec0d3c1 604#else
e0f712ba 605#ifdef MAC_OS8
1a578e9b
AC
606 make_mac_terminal_frame (f);
607#else
0a125897 608 {
0a125897 609 f->output_method = output_termcap;
6ed8eeff
KL
610 f->terminal = terminal;
611 f->terminal->reference_count++;
428a555e
KL
612 create_tty_output (f);
613
28d7d09f
KL
614 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
615 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
0a125897 616
428a555e
KL
617 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
618 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
619
428a555e 620 /* Set the top frame to the newly created frame. */
114a8b8c
KL
621 if (FRAME_TTY (f)->top_frame
622 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
623 XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
624
428a555e 625 FRAME_TTY (f)->top_frame = frame;
0a125897
KL
626 }
627
58bd8318
KS
628#ifdef CANNOT_DUMP
629 FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
630 FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
631#endif
e0f712ba 632#endif /* MAC_OS8 */
4ec0d3c1 633#endif /* WINDOWSNT */
2d764c78 634#endif /* MSDOS */
574a1a90 635
1a6d3623
EZ
636 if (!noninteractive)
637 init_frame_faces (f);
1a578e9b 638
ff11dfa1 639 return f;
dc6f92b8 640}
bb1513c9 641
ed8dad6b
KL
642/* Get a suitable value for frame parameter PARAMETER for a newly
643 created frame, based on (1) the user-supplied frame parameter
644 alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
645 fails, (3) Vdefault_frame_alist. */
646
647static Lisp_Object
648get_future_frame_param (Lisp_Object parameter,
649 Lisp_Object supplied_parms,
650 char *current_value)
651{
652 Lisp_Object result;
653
654 result = Fassq (parameter, supplied_parms);
655 if (NILP (result))
656 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
657 if (NILP (result) && current_value != NULL)
658 result = build_string (current_value);
659 if (NILP (result))
660 result = Fassq (parameter, Vdefault_frame_alist);
661 if (!NILP (result) && !STRINGP (result))
662 result = XCDR (result);
663 if (NILP (result) || !STRINGP (result))
664 result = Qnil;
665
666 return result;
667}
668
bb1513c9 669DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
14ff1ee0 670 1, 1, 0,
28d440ab 671 doc: /* Create an additional terminal frame, possibly on another terminal.
14ff1ee0 672This function takes one argument, an alist specifying frame parameters.
28d440ab
KL
673
674You can create multiple frames on a single text-only terminal, but
675only one of them (the selected terminal frame) is actually displayed.
676
677In practice, generally you don't need to specify any parameters,
678except when you want to create a new frame on another terminal.
679In that case, the `tty' parameter specifies the device file to open,
680and the `tty-type' parameter specifies the terminal type. Example:
681
682 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
683
0b0d3e0b
KL
684Note that changing the size of one terminal frame automatically
685affects all frames on the same terminal device. */)
14ff1ee0 686 (parms)
bb1513c9
RS
687 Lisp_Object parms;
688{
689 struct frame *f;
6ed8eeff 690 struct terminal *t = NULL;
574a1a90 691 Lisp_Object frame, tem;
8d2666fe 692 struct frame *sf = SELECTED_FRAME ();
bb1513c9 693
541580aa 694#ifdef MSDOS
2d764c78
EZ
695 if (sf->output_method != output_msdos_raw
696 && sf->output_method != output_termcap)
bb221971 697 abort ();
574a1a90
RS
698#else /* not MSDOS */
699
e0f712ba 700#ifdef MAC_OS
8d2666fe 701 if (sf->output_method != output_mac)
574a1a90 702 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
bb221971 703#else
daf01701 704#if 0 /* This should work now! */
8d2666fe 705 if (sf->output_method != output_termcap)
bb1513c9 706 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
bb221971 707#endif
daf01701 708#endif
574a1a90 709#endif /* not MSDOS */
b6660415
KL
710
711 {
6ed8eeff 712 Lisp_Object terminal;
bb1513c9 713
6ed8eeff
KL
714 terminal = Fassq (Qterminal, parms);
715 if (!NILP (terminal))
28d440ab 716 {
6ed8eeff
KL
717 terminal = XCDR (terminal);
718 t = get_terminal (terminal, 1);
28d440ab 719 }
28d440ab 720 }
b6660415 721
6ed8eeff 722 if (!t)
b6660415 723 {
b6660415 724 char *name = 0, *type = 0;
ed8dad6b 725 Lisp_Object tty, tty_type;
b6660415 726
ed8dad6b
KL
727 tty = get_future_frame_param
728 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
729 ? FRAME_TTY (XFRAME (selected_frame))->name
730 : NULL));
731 if (!NILP (tty))
b6660415
KL
732 {
733 name = (char *) alloca (SBYTES (tty) + 1);
734 strncpy (name, SDATA (tty), SBYTES (tty));
735 name[SBYTES (tty)] = 0;
736 }
737
ed8dad6b
KL
738 tty_type = get_future_frame_param
739 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
740 ? FRAME_TTY (XFRAME (selected_frame))->type
741 : NULL));
742 if (!NILP (tty_type))
b6660415
KL
743 {
744 type = (char *) alloca (SBYTES (tty_type) + 1);
745 strncpy (type, SDATA (tty_type), SBYTES (tty_type));
746 type[SBYTES (tty_type)] = 0;
747 }
748
6ed8eeff 749 t = init_tty (name, type, 0); /* Errors are not fatal. */
b6660415
KL
750 }
751
6ed8eeff 752 f = make_terminal_frame (t);
574a1a90 753
9628b887
KL
754 {
755 int width, height;
0b0d3e0b 756 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
9628b887
KL
757 change_frame_size (f, height, width, 0, 0, 0);
758 }
759
18082e2d 760 adjust_glyphs (f);
bb1513c9
RS
761 calculate_costs (f);
762 XSETFRAME (frame, f);
8adfc1ec 763 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
bb1513c9 764 Fmodify_frame_parameters (frame, parms);
7f19e125 765 Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
ed8dad6b 766 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
6ed8eeff 767 build_string (t->display_info.tty->type)),
ed8dad6b
KL
768 Qnil));
769 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
6ed8eeff 770 build_string (t->display_info.tty->name)),
ed8dad6b 771 Qnil));
5b65d888 772
87f1940e
EZ
773 /* Make the frame face alist be frame-specific, so that each
774 frame could change its face definitions independently. */
8d2666fe 775 f->face_alist = Fcopy_alist (sf->face_alist);
87f1940e
EZ
776 /* Simple Fcopy_alist isn't enough, because we need the contents of
777 the vectors which are the CDRs of associations in face_alist to
778 be copied as well. */
779 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
f3fbd155 780 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
bb1513c9
RS
781 return frame;
782}
1e8324d9 783
dc6f92b8 784\f
1e8324d9
GM
785/* Perform the switch to frame FRAME.
786
787 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
788 FRAME1 as frame.
789
790 If TRACK is non-zero and the frame that currently has the focus
791 redirects its focus to the selected frame, redirect that focused
792 frame's focus to FRAME instead.
793
794 FOR_DELETION non-zero means that the selected frame is being
6ed8eeff 795 deleted, which includes the possibility that the frame's terminal
1e8324d9
GM
796 is dead. */
797
61f94483 798Lisp_Object
1e8324d9
GM
799do_switch_frame (frame, track, for_deletion)
800 Lisp_Object frame;
801 int track, for_deletion;
dc6f92b8 802{
8d2666fe 803 struct frame *sf = SELECTED_FRAME ();
177c0ea7 804
2f0b07e0
JB
805 /* If FRAME is a switch-frame event, extract the frame we should
806 switch to. */
807 if (CONSP (frame)
7539e11f
KR
808 && EQ (XCAR (frame), Qswitch_frame)
809 && CONSP (XCDR (frame)))
810 frame = XCAR (XCDR (frame));
2f0b07e0 811
09907c3a
KH
812 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
813 a switch-frame event to arrive after a frame is no longer live,
814 especially when deleting the initial frame during startup. */
b7826503 815 CHECK_FRAME (frame);
09907c3a
KH
816 if (! FRAME_LIVE_P (XFRAME (frame)))
817 return Qnil;
dc6f92b8 818
8d2666fe 819 if (sf == XFRAME (frame))
ff11dfa1 820 return frame;
dc6f92b8 821
0aed85f4
KH
822 /* This is too greedy; it causes inappropriate focus redirection
823 that's hard to get rid of. */
824#if 0
a42e9724
JB
825 /* If a frame's focus has been redirected toward the currently
826 selected frame, we should change the redirection to point to the
827 newly selected frame. This means that if the focus is redirected
828 from a minibufferless frame to a surrogate minibuffer frame, we
829 can use `other-window' to switch between all the frames using
830 that minibuffer frame, and the focus redirection will follow us
831 around. */
0aed85f4
KH
832 if (track)
833 {
834 Lisp_Object tail;
a42e9724 835
7539e11f 836 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
0aed85f4
KH
837 {
838 Lisp_Object focus;
a42e9724 839
7539e11f 840 if (!FRAMEP (XCAR (tail)))
0aed85f4 841 abort ();
a42e9724 842
7539e11f 843 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
a42e9724 844
8d2666fe 845 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
7539e11f 846 Fredirect_frame_focus (XCAR (tail), frame);
0aed85f4
KH
847 }
848 }
849#else /* ! 0 */
850 /* Instead, apply it only to the frame we're pointing to. */
032d78fe 851#ifdef HAVE_WINDOW_SYSTEM
1e8324d9 852 if (track && FRAME_WINDOW_P (XFRAME (frame)))
0aed85f4
KH
853 {
854 Lisp_Object focus, xfocus;
855
d7266360 856 xfocus = x_get_focus_frame (XFRAME (frame));
0aed85f4
KH
857 if (FRAMEP (xfocus))
858 {
859 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
8d2666fe 860 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
0aed85f4
KH
861 Fredirect_frame_focus (xfocus, frame);
862 }
863 }
864#endif /* HAVE_X_WINDOWS */
865#endif /* ! 0 */
a42e9724 866
1e8324d9 867 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
550f0e6a
GM
868 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
869
9628b887
KL
870 if (FRAME_TERMCAP_P (XFRAME (selected_frame))
871 && FRAME_TERMCAP_P (XFRAME (frame))
872 && FRAME_TTY (XFRAME (selected_frame)) == FRAME_TTY (XFRAME (frame)))
873 {
6548cf00 874 XFRAME (selected_frame)->async_visible = 2; /* obscured */
9628b887
KL
875 XFRAME (frame)->async_visible = 1;
876 FRAME_TTY (XFRAME (frame))->top_frame = frame;
877 }
878
8d2666fe
GM
879 selected_frame = frame;
880 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
881 last_nonminibuf_frame = XFRAME (selected_frame);
d5e7c279 882
f1321dc3 883 Fselect_window (XFRAME (frame)->selected_window, Qnil);
dc6f92b8 884
94674d18
EZ
885#ifndef WINDOWSNT
886 /* Make sure to switch the tty color mode to that of the newly
887 selected frame. */
888 sf = SELECTED_FRAME ();
889 if (FRAME_TERMCAP_P (sf))
890 {
891 Lisp_Object color_mode_spec, color_mode;
892
893 color_mode_spec = assq_no_quit (Qtty_color_mode, sf->param_alist);
894 if (CONSP (color_mode_spec))
895 color_mode = XCDR (color_mode_spec);
896 else
897 color_mode = make_number (0);
898 set_tty_color_mode (sf, color_mode);
899 }
900#endif /* !WINDOWSNT */
901
074577b8 902 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 903 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
904 before you take it out, make sure that evaluating something like
905 (select-window (frame-root-window (new-frame))) doesn't end up
906 with your typing being interpreted in the new frame instead of
907 the one you're actually typing in. */
ef352596 908 internal_last_event_frame = Qnil;
074577b8 909
ff11dfa1 910 return frame;
dc6f92b8
JB
911}
912
20dc6fbb 913DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 1, "e",
14ff1ee0
PJ
914 doc: /* Select the frame FRAME.
915Subsequent editing commands apply to its selected window.
916The selection of FRAME lasts until the next time the user does
917something to select a different frame, or until the next time this
e4ed805e
LT
918function is called. If you are using a window system, the previously
919selected frame may be restored as the selected frame after return to
920the command loop, because it still may have the window system's input
921focus. On a text-only terminal, the next redisplay will display FRAME.
922
923This function returns FRAME, or nil if FRAME has been deleted. */)
20dc6fbb
LT
924 (frame)
925 Lisp_Object frame;
0aed85f4 926{
1e8324d9 927 return do_switch_frame (frame, 1, 0);
0aed85f4
KH
928}
929
930
20dc6fbb 931DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
14ff1ee0
PJ
932 doc: /* Handle a switch-frame event EVENT.
933Switch-frame events are usually bound to this function.
934A switch-frame event tells Emacs that the window manager has requested
935that the user's events be directed to the frame mentioned in the event.
936This function selects the selected window of the frame of EVENT.
937
938If EVENT is frame object, handle it as if it were a switch-frame event
939to that frame. */)
20dc6fbb
LT
940 (event)
941 Lisp_Object event;
0aed85f4 942{
6951cd71
KH
943 /* Preserve prefix arg that the command loop just cleared. */
944 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
e05169e2 945 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
1e8324d9 946 return do_switch_frame (event, 0, 0);
0aed85f4
KH
947}
948
ff11dfa1 949DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
14ff1ee0
PJ
950 doc: /* Return the frame that is now selected. */)
951 ()
dc6f92b8 952{
8d2666fe 953 return selected_frame;
dc6f92b8 954}
4a7cfafc 955\f
ff11dfa1 956DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
14ff1ee0
PJ
957 doc: /* Return the frame object that window WINDOW is on. */)
958 (window)
dc6f92b8
JB
959 Lisp_Object window;
960{
b7826503 961 CHECK_LIVE_WINDOW (window);
ff11dfa1 962 return XWINDOW (window)->frame;
dc6f92b8
JB
963}
964
ba32f2db 965DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
14ff1ee0
PJ
966 doc: /* Returns the topmost, leftmost window of FRAME.
967If omitted, FRAME defaults to the currently selected frame. */)
968 (frame)
ba32f2db
KH
969 Lisp_Object frame;
970{
971 Lisp_Object w;
972
973 if (NILP (frame))
8d2666fe 974 w = SELECTED_FRAME ()->root_window;
ba32f2db
KH
975 else
976 {
b7826503 977 CHECK_LIVE_FRAME (frame);
ba32f2db
KH
978 w = XFRAME (frame)->root_window;
979 }
980 while (NILP (XWINDOW (w)->buffer))
981 {
982 if (! NILP (XWINDOW (w)->hchild))
983 w = XWINDOW (w)->hchild;
984 else if (! NILP (XWINDOW (w)->vchild))
985 w = XWINDOW (w)->vchild;
986 else
987 abort ();
988 }
989 return w;
990}
991
5add3885
RS
992DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
993 Sactive_minibuffer_window, 0, 0, 0,
14ff1ee0
PJ
994 doc: /* Return the currently active minibuffer window, or nil if none. */)
995 ()
5add3885
RS
996{
997 return minibuf_level ? minibuf_window : Qnil;
998}
999
ff11dfa1 1000DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
14ff1ee0
PJ
1001 doc: /* Returns the root-window of FRAME.
1002If omitted, FRAME defaults to the currently selected frame. */)
1003 (frame)
ff11dfa1 1004 Lisp_Object frame;
dc6f92b8 1005{
8d2666fe 1006 Lisp_Object window;
177c0ea7 1007
ff11dfa1 1008 if (NILP (frame))
8d2666fe 1009 window = SELECTED_FRAME ()->root_window;
f9898cc6 1010 else
8d2666fe 1011 {
b7826503 1012 CHECK_LIVE_FRAME (frame);
8d2666fe
GM
1013 window = XFRAME (frame)->root_window;
1014 }
177c0ea7 1015
8d2666fe 1016 return window;
dc6f92b8
JB
1017}
1018
ff11dfa1
JB
1019DEFUN ("frame-selected-window", Fframe_selected_window,
1020 Sframe_selected_window, 0, 1, 0,
14ff1ee0
PJ
1021 doc: /* Return the selected window of frame object FRAME.
1022If omitted, FRAME defaults to the currently selected frame. */)
1023 (frame)
ff11dfa1 1024 Lisp_Object frame;
dc6f92b8 1025{
8d2666fe 1026 Lisp_Object window;
177c0ea7 1027
ff11dfa1 1028 if (NILP (frame))
8d2666fe 1029 window = SELECTED_FRAME ()->selected_window;
f9898cc6 1030 else
8d2666fe 1031 {
b7826503 1032 CHECK_LIVE_FRAME (frame);
8d2666fe
GM
1033 window = XFRAME (frame)->selected_window;
1034 }
dc6f92b8 1035
8d2666fe 1036 return window;
dc6f92b8
JB
1037}
1038
4a7cfafc
RS
1039DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
1040 Sset_frame_selected_window, 2, 2, 0,
14ff1ee0 1041 doc: /* Set the selected window of frame object FRAME to WINDOW.
e4ed805e 1042Return WINDOW.
14ff1ee0
PJ
1043If FRAME is nil, the selected frame is used.
1044If FRAME is the selected frame, this makes WINDOW the selected window. */)
1045 (frame, window)
4a7cfafc
RS
1046 Lisp_Object frame, window;
1047{
1048 if (NILP (frame))
8d2666fe 1049 frame = selected_frame;
177c0ea7 1050
b7826503
PJ
1051 CHECK_LIVE_FRAME (frame);
1052 CHECK_LIVE_WINDOW (window);
4a7cfafc
RS
1053
1054 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
1055 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
1056
8d2666fe 1057 if (EQ (frame, selected_frame))
f1321dc3 1058 return Fselect_window (window, Qnil);
4a7cfafc
RS
1059
1060 return XFRAME (frame)->selected_window = window;
1061}
b6660415
KL
1062
1063\f
ff11dfa1 1064DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 1065 0, 0, 0,
14ff1ee0
PJ
1066 doc: /* Return a list of all frames. */)
1067 ()
dc6f92b8 1068{
d74c1900
GM
1069 Lisp_Object frames;
1070 frames = Fcopy_sequence (Vframe_list);
6a65b1b5 1071#ifdef HAVE_WINDOW_SYSTEM
d74c1900
GM
1072 if (FRAMEP (tip_frame))
1073 frames = Fdelq (tip_frame, frames);
6a65b1b5 1074#endif
d74c1900 1075 return frames;
dc6f92b8
JB
1076}
1077
ff11dfa1 1078/* Return the next frame in the frame list after FRAME.
ff11dfa1 1079 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
1080 If MINIBUF is a window, include only its own frame
1081 and any frame now using that window as the minibuffer.
f7af3f7b 1082 If MINIBUF is `visible', include all visible frames.
a9986780 1083 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
1084 Otherwise, include all frames. */
1085
66a9dbbe 1086static Lisp_Object
ff11dfa1
JB
1087next_frame (frame, minibuf)
1088 Lisp_Object frame;
f9898cc6 1089 Lisp_Object minibuf;
dc6f92b8
JB
1090{
1091 Lisp_Object tail;
1092 int passed = 0;
1093
ff11dfa1
JB
1094 /* There must always be at least one frame in Vframe_list. */
1095 if (! CONSP (Vframe_list))
f9898cc6
JB
1096 abort ();
1097
dbc4e1c1
JB
1098 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
1099 forever. Forestall that. */
b7826503 1100 CHECK_LIVE_FRAME (frame);
dbc4e1c1 1101
dc6f92b8 1102 while (1)
7539e11f 1103 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
dc6f92b8 1104 {
ab9f008d 1105 Lisp_Object f;
d06a8a56 1106
7539e11f 1107 f = XCAR (tail);
06537cc8
RS
1108
1109 if (passed
9628b887
KL
1110 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1111 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1112 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1113 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
d5e7c279 1114 {
d06a8a56
JB
1115 /* Decide whether this frame is eligible to be returned. */
1116
1117 /* If we've looped all the way around without finding any
1118 eligible frames, return the original frame. */
1119 if (EQ (f, frame))
1120 return f;
1121
1122 /* Let minibuf decide if this frame is acceptable. */
1123 if (NILP (minibuf))
1124 {
1125 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1126 return f;
1127 }
f7af3f7b
RS
1128 else if (EQ (minibuf, Qvisible))
1129 {
1130 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1131 if (FRAME_VISIBLE_P (XFRAME (f)))
1132 return f;
1133 }
3780bc22 1134 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
a9986780
RS
1135 {
1136 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1137 if (FRAME_VISIBLE_P (XFRAME (f))
1138 || FRAME_ICONIFIED_P (XFRAME (f)))
1139 return f;
1140 }
f7af3f7b 1141 else if (WINDOWP (minibuf))
d06a8a56 1142 {
a9986780 1143 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
551645f8
GM
1144 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1145 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1146 FRAME_FOCUS_FRAME (XFRAME (f))))
d06a8a56
JB
1147 return f;
1148 }
1149 else
ff11dfa1 1150 return f;
d5e7c279 1151 }
dc6f92b8 1152
d06a8a56 1153 if (EQ (frame, f))
dc6f92b8
JB
1154 passed++;
1155 }
1156}
1157
ff11dfa1 1158/* Return the previous frame in the frame list before FRAME.
ff11dfa1 1159 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
1160 If MINIBUF is a window, include only its own frame
1161 and any frame now using that window as the minibuffer.
f7af3f7b 1162 If MINIBUF is `visible', include all visible frames.
a9986780 1163 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
1164 Otherwise, include all frames. */
1165
66a9dbbe 1166static Lisp_Object
ff11dfa1
JB
1167prev_frame (frame, minibuf)
1168 Lisp_Object frame;
f9898cc6 1169 Lisp_Object minibuf;
dc6f92b8
JB
1170{
1171 Lisp_Object tail;
1172 Lisp_Object prev;
1173
ff11dfa1
JB
1174 /* There must always be at least one frame in Vframe_list. */
1175 if (! CONSP (Vframe_list))
f9898cc6
JB
1176 abort ();
1177
dc6f92b8 1178 prev = Qnil;
7539e11f 1179 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
f9898cc6 1180 {
ab9f008d 1181 Lisp_Object f;
f9898cc6 1182
7539e11f 1183 f = XCAR (tail);
e35d291d 1184 if (!FRAMEP (f))
d06a8a56 1185 abort ();
f9898cc6 1186
d06a8a56
JB
1187 if (EQ (frame, f) && !NILP (prev))
1188 return prev;
f9898cc6 1189
9628b887
KL
1190 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1191 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1192 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1193 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
f7af3f7b 1194 {
06537cc8
RS
1195 /* Decide whether this frame is eligible to be returned,
1196 according to minibuf. */
1197 if (NILP (minibuf))
1198 {
1199 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1200 prev = f;
1201 }
1202 else if (WINDOWP (minibuf))
1203 {
1204 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
551645f8
GM
1205 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1206 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1207 FRAME_FOCUS_FRAME (XFRAME (f))))
06537cc8
RS
1208 prev = f;
1209 }
1210 else if (EQ (minibuf, Qvisible))
1211 {
1212 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1213 if (FRAME_VISIBLE_P (XFRAME (f)))
1214 prev = f;
1215 }
1216 else if (XFASTINT (minibuf) == 0)
1217 {
1218 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1219 if (FRAME_VISIBLE_P (XFRAME (f))
1220 || FRAME_ICONIFIED_P (XFRAME (f)))
1221 prev = f;
1222 }
1223 else
a9986780
RS
1224 prev = f;
1225 }
f9898cc6 1226 }
d06a8a56
JB
1227
1228 /* We've scanned the entire list. */
1229 if (NILP (prev))
1230 /* We went through the whole frame list without finding a single
1231 acceptable frame. Return the original frame. */
1232 return frame;
1233 else
1234 /* There were no acceptable frames in the list before FRAME; otherwise,
1235 we would have returned directly from the loop. Since PREV is the last
1236 acceptable frame in the list, return it. */
1237 return prev;
dc6f92b8
JB
1238}
1239
ef2c57ac 1240
ff11dfa1 1241DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
14ff1ee0
PJ
1242 doc: /* Return the next frame in the frame list after FRAME.
1243It considers only frames on the same terminal as FRAME.
1244By default, skip minibuffer-only frames.
1245If omitted, FRAME defaults to the selected frame.
1246If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1247If MINIFRAME is a window, include only its own frame
1248and any frame now using that window as the minibuffer.
1249If MINIFRAME is `visible', include all visible frames.
1250If MINIFRAME is 0, include all visible and iconified frames.
1251Otherwise, include all frames. */)
1252 (frame, miniframe)
8693ca83 1253 Lisp_Object frame, miniframe;
dc6f92b8 1254{
ff11dfa1 1255 if (NILP (frame))
8d2666fe 1256 frame = selected_frame;
177c0ea7 1257
b7826503 1258 CHECK_LIVE_FRAME (frame);
ff11dfa1 1259 return next_frame (frame, miniframe);
dc6f92b8 1260}
dbc4e1c1 1261
ef2c57ac 1262DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
14ff1ee0
PJ
1263 doc: /* Return the previous frame in the frame list before FRAME.
1264It considers only frames on the same terminal as FRAME.
1265By default, skip minibuffer-only frames.
1266If omitted, FRAME defaults to the selected frame.
1267If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1268If MINIFRAME is a window, include only its own frame
1269and any frame now using that window as the minibuffer.
1270If MINIFRAME is `visible', include all visible frames.
1271If MINIFRAME is 0, include all visible and iconified frames.
1272Otherwise, include all frames. */)
1273 (frame, miniframe)
ef2c57ac
RM
1274 Lisp_Object frame, miniframe;
1275{
ef2c57ac 1276 if (NILP (frame))
8d2666fe 1277 frame = selected_frame;
b7826503 1278 CHECK_LIVE_FRAME (frame);
ef2c57ac
RM
1279 return prev_frame (frame, miniframe);
1280}
dc6f92b8 1281\f
808c0f20
RS
1282/* Return 1 if it is ok to delete frame F;
1283 0 if all frames aside from F are invisible.
1284 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 1285
d56b45eb 1286int
808c0f20
RS
1287other_visible_frames (f)
1288 FRAME_PTR f;
1289{
1290 /* We know the selected frame is visible,
1291 so if F is some other frame, it can't be the sole visible one. */
8d2666fe 1292 if (f == SELECTED_FRAME ())
c08c95c7
RS
1293 {
1294 Lisp_Object frames;
1295 int count = 0;
1296
1297 for (frames = Vframe_list;
1298 CONSP (frames);
7539e11f 1299 frames = XCDR (frames))
c08c95c7 1300 {
ab9f008d 1301 Lisp_Object this;
c08c95c7 1302
7539e11f 1303 this = XCAR (frames);
808c0f20
RS
1304 /* Verify that the frame's window still exists
1305 and we can still talk to it. And note any recent change
1306 in visibility. */
032d78fe
GV
1307#ifdef HAVE_WINDOW_SYSTEM
1308 if (FRAME_WINDOW_P (XFRAME (this)))
5e7b7c5b 1309 {
b0509a40 1310 x_sync (XFRAME (this));
5e7b7c5b
RS
1311 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1312 }
1313#endif
1314
c08c95c7
RS
1315 if (FRAME_VISIBLE_P (XFRAME (this))
1316 || FRAME_ICONIFIED_P (XFRAME (this))
1317 /* Allow deleting the terminal frame when at least
1318 one X frame exists! */
032d78fe 1319 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
c08c95c7
RS
1320 count++;
1321 }
808c0f20 1322 return count > 1;
c08c95c7 1323 }
808c0f20
RS
1324 return 1;
1325}
1326
ea161626
KL
1327/* Error handler for `delete-frame-functions'. */
1328static Lisp_Object
1329delete_frame_handler (Lisp_Object arg)
1330{
1331 add_to_log ("Error during `delete-frame': %s", arg, Qnil);
1332 return Qnil;
1333}
1334
808c0f20 1335DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
14ff1ee0
PJ
1336 doc: /* Delete FRAME, permanently eliminating it from use.
1337If omitted, FRAME defaults to the selected frame.
1338A frame may not be deleted if its minibuffer is used by other frames.
1339Normally, you may not delete a frame if all other frames are invisible,
1340but if the second optional argument FORCE is non-nil, you may do so.
1341
cd1d850f
JPW
1342This function runs `delete-frame-functions' before actually deleting the
1343frame, unless the frame is a tooltip.
1344The functions are run with one arg, the frame to be deleted. */)
14ff1ee0 1345 (frame, force)
808c0f20
RS
1346 Lisp_Object frame, force;
1347{
1348 struct frame *f;
8d2666fe 1349 struct frame *sf = SELECTED_FRAME ();
bedb9c0e
KL
1350 struct kboard *kb;
1351
99b92e64 1352 int minibuffer_selected;
808c0f20
RS
1353
1354 if (EQ (frame, Qnil))
1355 {
8d2666fe 1356 f = sf;
2d80a27a 1357 XSETFRAME (frame, f);
808c0f20
RS
1358 }
1359 else
1360 {
b7826503 1361 CHECK_FRAME (frame);
808c0f20
RS
1362 f = XFRAME (frame);
1363 }
1364
1365 if (! FRAME_LIVE_P (f))
1366 return Qnil;
1367
83a96b4d 1368 if (NILP (force) && !other_visible_frames (f)
e0f712ba 1369#ifdef MAC_OS8
83a96b4d
AC
1370 /* Terminal frame deleted before any other visible frames are
1371 created. */
d5db4077 1372 && strcmp (SDATA (f->name), "F1") != 0
83a96b4d
AC
1373#endif
1374 )
808c0f20 1375 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 1376
00c5fd51
RS
1377#if 0
1378 /* This is a nice idea, but x_connection_closed needs to be able
1379 to delete the last frame, if it is gone. */
7539e11f 1380 if (NILP (XCDR (Vframe_list)))
e9687ee8 1381 error ("Attempt to delete the only frame");
00c5fd51 1382#endif
e9687ee8 1383
ff11dfa1
JB
1384 /* Does this frame have a minibuffer, and is it the surrogate
1385 minibuffer for any other frame? */
fd0c2bd1 1386 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 1387 {
ff11dfa1 1388 Lisp_Object frames;
1113d9db 1389
ff11dfa1
JB
1390 for (frames = Vframe_list;
1391 CONSP (frames);
7539e11f 1392 frames = XCDR (frames))
1113d9db 1393 {
7a8cc307 1394 Lisp_Object this;
7539e11f 1395 this = XCAR (frames);
1113d9db 1396
ff11dfa1
JB
1397 if (! EQ (this, frame)
1398 && EQ (frame,
7a8cc307
RS
1399 WINDOW_FRAME (XWINDOW
1400 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 1401 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 1402 }
dc6f92b8
JB
1403 }
1404
cd1d850f
JPW
1405 /* Run `delete-frame-functions' unless frame is a tooltip. */
1406 if (!NILP (Vrun_hooks)
1407 && NILP (Fframe_parameter (frame, intern ("tooltip"))))
0e662342 1408 {
ea161626 1409 int count = SPECPDL_INDEX ();
0e662342 1410 Lisp_Object args[2];
ea161626
KL
1411 struct gcpro gcpro1, gcpro2;
1412
1413 /* Don't let a rogue function in `delete-frame-functions'
1414 prevent the frame deletion. */
1415 GCPRO2 (args[0], args[1]);
cd1d850f 1416 args[0] = intern ("delete-frame-functions");
0e662342 1417 args[1] = frame;
ea161626
KL
1418 internal_condition_case_2 (Frun_hook_with_args, 2, args,
1419 Qt, delete_frame_handler);
1420 UNGCPRO;
0e662342
GM
1421 }
1422
b6660415
KL
1423 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1424 if (! FRAME_LIVE_P (f))
1425 return Qnil;
1426
99b92e64
RS
1427 minibuffer_selected = EQ (minibuf_window, selected_window);
1428
ff11dfa1 1429 /* Don't let the frame remain selected. */
8d2666fe 1430 if (f == sf)
06537cc8
RS
1431 {
1432 Lisp_Object tail, frame1;
1433
1434 /* Look for another visible frame on the same terminal. */
1435 frame1 = next_frame (frame, Qvisible);
1436
1437 /* If there is none, find *some* other frame. */
1438 if (NILP (frame1) || EQ (frame1, frame))
1439 {
1440 FOR_EACH_FRAME (tail, frame1)
1441 {
fca177d4 1442 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
06537cc8
RS
1443 break;
1444 }
1445 }
1446
1e8324d9 1447 do_switch_frame (frame1, 0, 1);
79a65b7f 1448 sf = SELECTED_FRAME ();
06537cc8 1449 }
dc6f92b8 1450
ff11dfa1
JB
1451 /* Don't allow minibuf_window to remain on a deleted frame. */
1452 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 1453 {
8d2666fe 1454 Fset_window_buffer (sf->minibuffer_window,
5af5757b 1455 XWINDOW (minibuf_window)->buffer, Qnil);
8d2666fe 1456 minibuf_window = sf->minibuffer_window;
99b92e64
RS
1457
1458 /* If the dying minibuffer window was selected,
1459 select the new one. */
1460 if (minibuffer_selected)
f1321dc3 1461 Fselect_window (minibuf_window, Qnil);
dc6f92b8
JB
1462 }
1463
130adcb7
EZ
1464 /* Don't let echo_area_window to remain on a deleted frame. */
1465 if (EQ (f->minibuffer_window, echo_area_window))
1466 echo_area_window = sf->minibuffer_window;
1467
da8e8fc1
KL
1468 /* Don't allow other frames to refer to a deleted frame in their
1469 'environment parameter. */
1470 {
1471 Lisp_Object tail, frame1;
1472 Lisp_Object env = get_frame_param (XFRAME (frame), Qenvironment);
1473 FOR_EACH_FRAME (tail, frame1)
1474 {
1475 if (EQ (frame, frame1) || !FRAME_LIVE_P (XFRAME (frame1)))
1476 continue;
1477 if (EQ (frame, get_frame_param (XFRAME (frame1), Qenvironment)))
1478 {
1479 store_frame_param (XFRAME (frame1), Qenvironment, env);
1480 if (!FRAMEP (env))
1481 env = frame1;
1482 }
1483 }
1484 }
1485
bb2a0a65
RS
1486 /* Clear any X selections for this frame. */
1487#ifdef HAVE_X_WINDOWS
1488 if (FRAME_X_P (f))
1489 x_clear_frame_selections (f);
1490#endif
f706a7b2
YM
1491#ifdef MAC_OS
1492 if (FRAME_MAC_P (f))
1493 x_clear_frame_selections (f);
1494#endif
bb2a0a65 1495
177c0ea7
JB
1496 /* Free glyphs.
1497 This function must be called before the window tree of the
18082e2d
GM
1498 frame is deleted because windows contain dynamically allocated
1499 memory. */
1500 free_glyphs (f);
1501
4a88b3b0
JB
1502 /* Mark all the windows that used to be on FRAME as deleted, and then
1503 remove the reference to them. */
1504 delete_all_subwindows (XWINDOW (f->root_window));
1505 f->root_window = Qnil;
1506
ff11dfa1 1507 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 1508 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 1509
60a8823e 1510 if (f->namebuf)
18082e2d 1511 xfree (f->namebuf);
96f09305
JD
1512 if (f->decode_mode_spec_buffer)
1513 xfree (f->decode_mode_spec_buffer);
d2bee99e 1514 if (FRAME_INSERT_COST (f))
18082e2d 1515 xfree (FRAME_INSERT_COST (f));
d2bee99e 1516 if (FRAME_DELETEN_COST (f))
18082e2d 1517 xfree (FRAME_DELETEN_COST (f));
d2bee99e 1518 if (FRAME_INSERTN_COST (f))
18082e2d 1519 xfree (FRAME_INSERTN_COST (f));
d2bee99e 1520 if (FRAME_DELETE_COST (f))
18082e2d 1521 xfree (FRAME_DELETE_COST (f));
25734faf 1522 if (FRAME_MESSAGE_BUF (f))
18082e2d 1523 xfree (FRAME_MESSAGE_BUF (f));
d2bee99e 1524
8678b9cc 1525 /* Since some events are handled at the interrupt level, we may get
6ed8eeff 1526 an event for f at any time; if we zero out the frame's terminal
8678b9cc 1527 now, then we may trip up the event-handling code. Instead, we'll
6ed8eeff
KL
1528 promise that the terminal of the frame must be valid until we
1529 have called the window-system-dependent frame destruction
1530 routine. */
dbc4e1c1 1531
6ed8eeff
KL
1532 if (FRAME_TERMINAL (f)->delete_frame_hook)
1533 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
bedb9c0e 1534
428a555e 1535 {
6ed8eeff 1536 struct terminal *terminal = FRAME_TERMINAL (f);
428a555e 1537 f->output_data.nothing = 0;
6ed8eeff 1538 f->terminal = 0; /* Now the frame is dead. */
428a555e 1539
6ed8eeff 1540 /* If needed, delete the terminal that this frame was on.
bedb9c0e 1541 (This must be done after the frame is killed.) */
6ed8eeff
KL
1542 terminal->reference_count--;
1543 if (terminal->reference_count == 0)
bedb9c0e
KL
1544 {
1545 kb = NULL;
6ed8eeff
KL
1546 if (terminal->delete_terminal_hook)
1547 (*terminal->delete_terminal_hook) (terminal);
bedb9c0e 1548 else
6ed8eeff 1549 delete_terminal (terminal);
bedb9c0e
KL
1550 }
1551 else
6ed8eeff 1552 kb = terminal->kboard;
428a555e 1553 }
8678b9cc 1554
ff11dfa1 1555 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1556 another one. */
ff11dfa1 1557 if (f == last_nonminibuf_frame)
d5e7c279 1558 {
ff11dfa1 1559 Lisp_Object frames;
1113d9db 1560
ff11dfa1 1561 last_nonminibuf_frame = 0;
d5e7c279 1562
ff11dfa1
JB
1563 for (frames = Vframe_list;
1564 CONSP (frames);
7539e11f 1565 frames = XCDR (frames))
d5e7c279 1566 {
7539e11f 1567 f = XFRAME (XCAR (frames));
ff11dfa1 1568 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1569 {
ff11dfa1 1570 last_nonminibuf_frame = f;
d5e7c279
JB
1571 break;
1572 }
1573 }
1574 }
dc6f92b8 1575
8ceb7434
RS
1576 /* If there's no other frame on the same kboard, get out of
1577 single-kboard state if we're in it for this kboard. */
bedb9c0e
KL
1578 if (kb != NULL)
1579 {
1580 Lisp_Object frames;
1581 /* Some frame we found on the same kboard, or nil if there are none. */
1582 Lisp_Object frame_on_same_kboard;
8ceb7434 1583
bedb9c0e 1584 frame_on_same_kboard = Qnil;
8ceb7434 1585
bedb9c0e
KL
1586 for (frames = Vframe_list;
1587 CONSP (frames);
1588 frames = XCDR (frames))
1589 {
1590 Lisp_Object this;
1591 struct frame *f1;
8ceb7434 1592
bedb9c0e
KL
1593 this = XCAR (frames);
1594 if (!FRAMEP (this))
1595 abort ();
1596 f1 = XFRAME (this);
8ceb7434 1597
bedb9c0e
KL
1598 if (kb == FRAME_KBOARD (f1))
1599 frame_on_same_kboard = this;
1600 }
8ceb7434 1601
bedb9c0e
KL
1602 if (NILP (frame_on_same_kboard))
1603 not_single_kboard_state (kb);
1604 }
8ceb7434
RS
1605
1606
c4c6d073
KH
1607 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1608 find another one. Prefer minibuffer-only frames, but also notice
1609 frames with other windows. */
bedb9c0e 1610 if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
1113d9db 1611 {
ff11dfa1 1612 Lisp_Object frames;
1113d9db 1613
ff11dfa1 1614 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1615 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1616 /* Some frame we found on the same kboard, or nil if there are none. */
1617 Lisp_Object frame_on_same_kboard;
1113d9db 1618
32fda9ba 1619 frame_on_same_kboard = Qnil;
ab9f008d 1620 frame_with_minibuf = Qnil;
32fda9ba 1621
ff11dfa1
JB
1622 for (frames = Vframe_list;
1623 CONSP (frames);
7539e11f 1624 frames = XCDR (frames))
1113d9db 1625 {
ab9f008d 1626 Lisp_Object this;
c4c6d073 1627 struct frame *f1;
1113d9db 1628
7539e11f 1629 this = XCAR (frames);
e35d291d 1630 if (!FRAMEP (this))
1113d9db 1631 abort ();
c4c6d073 1632 f1 = XFRAME (this);
1113d9db 1633
c4c6d073
KH
1634 /* Consider only frames on the same kboard
1635 and only those with minibuffers. */
bedb9c0e 1636 if (kb == FRAME_KBOARD (f1)
c4c6d073 1637 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1638 {
ff11dfa1 1639 frame_with_minibuf = this;
c4c6d073 1640 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1641 break;
1642 }
32fda9ba 1643
bedb9c0e 1644 if (kb == FRAME_KBOARD (f1))
32fda9ba 1645 frame_on_same_kboard = this;
1113d9db
JB
1646 }
1647
32fda9ba
RS
1648 if (!NILP (frame_on_same_kboard))
1649 {
1650 /* We know that there must be some frame with a minibuffer out
1651 there. If this were not true, all of the frames present
1652 would have to be minibufferless, which implies that at some
1653 point their minibuffer frames must have been deleted, but
1654 that is prohibited at the top; you can't delete surrogate
1655 minibuffer frames. */
1656 if (NILP (frame_with_minibuf))
1657 abort ();
1113d9db 1658
bedb9c0e 1659 kb->Vdefault_minibuffer_frame = frame_with_minibuf;
32fda9ba
RS
1660 }
1661 else
1662 /* No frames left on this kboard--say no minibuffer either. */
bedb9c0e 1663 kb->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1664 }
1665
e681c92a
RS
1666 /* Cause frame titles to update--necessary if we now have just one frame. */
1667 update_mode_lines = 1;
1668
dc6f92b8
JB
1669 return Qnil;
1670}
1671\f
1672/* Return mouse position in character cell units. */
1673
f9898cc6 1674DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
14ff1ee0
PJ
1675 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1676The position is given in character cells, where (0, 0) is the
1677upper-left corner.
1678If Emacs is running on a mouseless terminal or hasn't been programmed
1679to read the mouse position, it returns the selected frame for FRAME
1680and nil for X and Y.
1681If `mouse-position-function' is non-nil, `mouse-position' calls it,
1682passing the normal return value to that function as an argument,
1683and returns whatever that function returns. */)
1684 ()
dc6f92b8 1685{
ff11dfa1 1686 FRAME_PTR f;
dbc4e1c1 1687 Lisp_Object lispy_dummy;
fd2777e0 1688 enum scroll_bar_part party_dummy;
beb0bc36 1689 Lisp_Object x, y, retval;
5384466a 1690 int col, row;
dbc4e1c1 1691 unsigned long long_dummy;
cb2255b3 1692 struct gcpro gcpro1;
dc6f92b8 1693
8d2666fe 1694 f = SELECTED_FRAME ();
c5074d8c
RS
1695 x = y = Qnil;
1696
f443c170 1697#ifdef HAVE_MOUSE
c5074d8c 1698 /* It's okay for the hook to refrain from storing anything. */
6ed8eeff
KL
1699 if (FRAME_TERMINAL (f)->mouse_position_hook)
1700 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1701 &lispy_dummy, &party_dummy,
1702 &x, &y,
1703 &long_dummy);
76db7eb4
KH
1704 if (! NILP (x))
1705 {
1706 col = XINT (x);
1707 row = XINT (y);
8126c3b4 1708 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1709 XSETINT (x, col);
1710 XSETINT (y, row);
1711 }
f443c170 1712#endif
2d80a27a 1713 XSETFRAME (lispy_dummy, f);
beb0bc36 1714 retval = Fcons (lispy_dummy, Fcons (x, y));
cb2255b3 1715 GCPRO1 (retval);
beb0bc36 1716 if (!NILP (Vmouse_position_function))
cb2255b3
GM
1717 retval = call1 (Vmouse_position_function, retval);
1718 RETURN_UNGCPRO (retval);
dc6f92b8
JB
1719}
1720
152e6c70
RS
1721DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1722 Smouse_pixel_position, 0, 0, 0,
14ff1ee0
PJ
1723 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1724The position is given in pixel units, where (0, 0) is the
1725upper-left corner.
1726If Emacs is running on a mouseless terminal or hasn't been programmed
1727to read the mouse position, it returns the selected frame for FRAME
1728and nil for X and Y. */)
1729 ()
152e6c70
RS
1730{
1731 FRAME_PTR f;
1732 Lisp_Object lispy_dummy;
1733 enum scroll_bar_part party_dummy;
1734 Lisp_Object x, y;
152e6c70
RS
1735 unsigned long long_dummy;
1736
8d2666fe 1737 f = SELECTED_FRAME ();
152e6c70
RS
1738 x = y = Qnil;
1739
0c5c1cf7 1740#ifdef HAVE_MOUSE
152e6c70 1741 /* It's okay for the hook to refrain from storing anything. */
6ed8eeff
KL
1742 if (FRAME_TERMINAL (f)->mouse_position_hook)
1743 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1744 &lispy_dummy, &party_dummy,
1745 &x, &y,
1746 &long_dummy);
0c5c1cf7 1747#endif
2d80a27a 1748 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1749 return Fcons (lispy_dummy, Fcons (x, y));
1750}
1751
dc6f92b8 1752DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
14ff1ee0
PJ
1753 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1754Coordinates are relative to the frame, not a window,
1755so the coordinates of the top left character in the frame
1756may be nonzero due to left-hand scroll bars or the menu bar.
1757
1758This function is a no-op for an X frame that is not visible.
1759If you have just created a frame, you must wait for it to become visible
1760before calling this function on it, like this.
1761 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
ff11dfa1
JB
1762 (frame, x, y)
1763 Lisp_Object frame, x, y;
dc6f92b8 1764{
b7826503
PJ
1765 CHECK_LIVE_FRAME (frame);
1766 CHECK_NUMBER (x);
1767 CHECK_NUMBER (y);
dc6f92b8 1768
dbc4e1c1 1769 /* I think this should be done with a hook. */
032d78fe
GV
1770#ifdef HAVE_WINDOW_SYSTEM
1771 if (FRAME_WINDOW_P (XFRAME (frame)))
d19be8a9 1772 /* Warping the mouse will cause enternotify and focus events. */
d4d76014 1773 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
bb221971 1774#else
be625e00 1775#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1776 if (FRAME_MSDOS_P (XFRAME (frame)))
1777 {
20dc6fbb 1778 Fselect_frame (frame);
bb221971
RS
1779 mouse_moveto (XINT (x), XINT (y));
1780 }
1781#endif
dc6f92b8
JB
1782#endif
1783
1784 return Qnil;
1785}
152e6c70
RS
1786
1787DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1788 Sset_mouse_pixel_position, 3, 3, 0,
14ff1ee0
PJ
1789 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1790Note, this is a no-op for an X frame that is not visible.
1791If you have just created a frame, you must wait for it to become visible
1792before calling this function on it, like this.
1793 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
152e6c70
RS
1794 (frame, x, y)
1795 Lisp_Object frame, x, y;
1796{
b7826503
PJ
1797 CHECK_LIVE_FRAME (frame);
1798 CHECK_NUMBER (x);
1799 CHECK_NUMBER (y);
152e6c70
RS
1800
1801 /* I think this should be done with a hook. */
032d78fe
GV
1802#ifdef HAVE_WINDOW_SYSTEM
1803 if (FRAME_WINDOW_P (XFRAME (frame)))
d19be8a9 1804 /* Warping the mouse will cause enternotify and focus events. */
d4d76014 1805 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
bb221971 1806#else
be625e00 1807#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1808 if (FRAME_MSDOS_P (XFRAME (frame)))
1809 {
20dc6fbb 1810 Fselect_frame (frame);
bb221971
RS
1811 mouse_moveto (XINT (x), XINT (y));
1812 }
1813#endif
152e6c70
RS
1814#endif
1815
1816 return Qnil;
1817}
dc6f92b8 1818\f
98ce1622
RS
1819static void make_frame_visible_1 P_ ((Lisp_Object));
1820
ff11dfa1 1821DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1822 0, 1, "",
14ff1ee0
PJ
1823 doc: /* Make the frame FRAME visible (assuming it is an X window).
1824If omitted, FRAME defaults to the currently selected frame. */)
1825 (frame)
ff11dfa1 1826 Lisp_Object frame;
dc6f92b8 1827{
1aa66088 1828 if (NILP (frame))
8d2666fe 1829 frame = selected_frame;
1aa66088 1830
b7826503 1831 CHECK_LIVE_FRAME (frame);
dc6f92b8 1832
dbc4e1c1 1833 /* I think this should be done with a hook. */
032d78fe
GV
1834#ifdef HAVE_WINDOW_SYSTEM
1835 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1836 {
1837 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1838 x_make_frame_visible (XFRAME (frame));
1839 }
fd0c2bd1 1840#endif
dc6f92b8 1841
98ce1622
RS
1842 make_frame_visible_1 (XFRAME (frame)->root_window);
1843
d19be8a9 1844 /* Make menu bar update for the Buffers and Frames menus. */
565620a5
RS
1845 windows_or_buffers_changed++;
1846
ff11dfa1 1847 return frame;
dc6f92b8
JB
1848}
1849
98ce1622
RS
1850/* Update the display_time slot of the buffers shown in WINDOW
1851 and all its descendents. */
1852
1853static void
1854make_frame_visible_1 (window)
1855 Lisp_Object window;
1856{
1857 struct window *w;
1858
1859 for (;!NILP (window); window = w->next)
1860 {
1861 w = XWINDOW (window);
1862
1863 if (!NILP (w->buffer))
1864 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1865
1866 if (!NILP (w->vchild))
1867 make_frame_visible_1 (w->vchild);
1868 if (!NILP (w->hchild))
1869 make_frame_visible_1 (w->hchild);
1870 }
1871}
1872
ff11dfa1 1873DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1874 0, 2, "",
14ff1ee0
PJ
1875 doc: /* Make the frame FRAME invisible (assuming it is an X window).
1876If omitted, FRAME defaults to the currently selected frame.
1877Normally you may not make FRAME invisible if all other frames are invisible,
1878but if the second optional argument FORCE is non-nil, you may do so. */)
808c0f20
RS
1879 (frame, force)
1880 Lisp_Object frame, force;
dc6f92b8 1881{
1aa66088 1882 if (NILP (frame))
8d2666fe 1883 frame = selected_frame;
1aa66088 1884
b7826503 1885 CHECK_LIVE_FRAME (frame);
dc6f92b8 1886
808c0f20
RS
1887 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1888 error ("Attempt to make invisible the sole visible or iconified frame");
1889
3d378fdf 1890#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17 1891 /* Don't let the frame remain selected. */
8d2666fe 1892 if (EQ (frame, selected_frame))
1e8324d9 1893 do_switch_frame (next_frame (frame, Qt), 0, 0)
3d378fdf 1894#endif
9c394f17
RS
1895
1896 /* Don't allow minibuf_window to remain on a deleted frame. */
1897 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1898 {
8d2666fe
GM
1899 struct frame *sf = XFRAME (selected_frame);
1900 Fset_window_buffer (sf->minibuffer_window,
5af5757b 1901 XWINDOW (minibuf_window)->buffer, Qnil);
8d2666fe 1902 minibuf_window = sf->minibuffer_window;
9c394f17
RS
1903 }
1904
dbc4e1c1 1905 /* I think this should be done with a hook. */
032d78fe
GV
1906#ifdef HAVE_WINDOW_SYSTEM
1907 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1908 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1909#endif
dc6f92b8 1910
d19be8a9 1911 /* Make menu bar update for the Buffers and Frames menus. */
565620a5
RS
1912 windows_or_buffers_changed++;
1913
dc6f92b8
JB
1914 return Qnil;
1915}
1916
ff11dfa1 1917DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1918 0, 1, "",
14ff1ee0
PJ
1919 doc: /* Make the frame FRAME into an icon.
1920If omitted, FRAME defaults to the currently selected frame. */)
ff11dfa1
JB
1921 (frame)
1922 Lisp_Object frame;
dc6f92b8 1923{
1aa66088 1924 if (NILP (frame))
8d2666fe 1925 frame = selected_frame;
177c0ea7 1926
b7826503 1927 CHECK_LIVE_FRAME (frame);
dc6f92b8 1928
3d378fdf 1929#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17 1930 /* Don't let the frame remain selected. */
8d2666fe 1931 if (EQ (frame, selected_frame))
20dc6fbb 1932 Fhandle_switch_frame (next_frame (frame, Qt));
3d378fdf 1933#endif
9c394f17
RS
1934
1935 /* Don't allow minibuf_window to remain on a deleted frame. */
1936 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1937 {
8d2666fe
GM
1938 struct frame *sf = XFRAME (selected_frame);
1939 Fset_window_buffer (sf->minibuffer_window,
5af5757b 1940 XWINDOW (minibuf_window)->buffer, Qnil);
8d2666fe 1941 minibuf_window = sf->minibuffer_window;
9c394f17
RS
1942 }
1943
dbc4e1c1 1944 /* I think this should be done with a hook. */
032d78fe
GV
1945#ifdef HAVE_WINDOW_SYSTEM
1946 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1947 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1948#endif
dc6f92b8 1949
d19be8a9 1950 /* Make menu bar update for the Buffers and Frames menus. */
565620a5
RS
1951 windows_or_buffers_changed++;
1952
dc6f92b8
JB
1953 return Qnil;
1954}
1955
ff11dfa1 1956DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1957 1, 1, 0,
14ff1ee0
PJ
1958 doc: /* Return t if FRAME is now \"visible\" (actually in use for display).
1959A frame that is not \"visible\" is not updated and, if it works through
1960a window system, it may not show at all.
e4ed805e
LT
1961Return the symbol `icon' if frame is visible only as an icon.
1962
1963On a text-only terminal, all frames are considered visible, whether
1964they are currently being displayed or not, and this function returns t
1965for all frames. */)
14ff1ee0 1966 (frame)
ff11dfa1 1967 Lisp_Object frame;
dc6f92b8 1968{
b7826503 1969 CHECK_LIVE_FRAME (frame);
dc6f92b8 1970
5c044f55
RS
1971 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1972
a42e9724 1973 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1974 return Qt;
a42e9724 1975 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1976 return Qicon;
dc6f92b8
JB
1977 return Qnil;
1978}
1979
ff11dfa1 1980DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1981 0, 0, 0,
14ff1ee0 1982 doc: /* Return a list of all frames now \"visible\" (being updated). */)
dc6f92b8
JB
1983 ()
1984{
ff11dfa1
JB
1985 Lisp_Object tail, frame;
1986 struct frame *f;
dc6f92b8
JB
1987 Lisp_Object value;
1988
1989 value = Qnil;
7539e11f 1990 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
dc6f92b8 1991 {
7539e11f 1992 frame = XCAR (tail);
e35d291d 1993 if (!FRAMEP (frame))
dc6f92b8 1994 continue;
ff11dfa1 1995 f = XFRAME (frame);
a42e9724 1996 if (FRAME_VISIBLE_P (f))
ff11dfa1 1997 value = Fcons (frame, value);
dc6f92b8
JB
1998 }
1999 return value;
2000}
d5e7c279
JB
2001
2002
e518d5e1 2003DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
14ff1ee0 2004 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
e4ed805e 2005If FRAME is invisible or iconified, make it visible.
14ff1ee0
PJ
2006If you don't specify a frame, the selected frame is used.
2007If Emacs is displaying on an ordinary terminal or some other device which
2008doesn't support multiple overlapping frames, this function does nothing. */)
2009 (frame)
dbc4e1c1
JB
2010 Lisp_Object frame;
2011{
428a555e 2012 struct frame *f;
828ac693 2013 if (NILP (frame))
8d2666fe 2014 frame = selected_frame;
828ac693 2015
b7826503 2016 CHECK_LIVE_FRAME (frame);
8a981af5 2017
428a555e
KL
2018 f = XFRAME (frame);
2019
8a981af5
RS
2020 /* Do like the documentation says. */
2021 Fmake_frame_visible (frame);
2022
6ed8eeff
KL
2023 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2024 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
dbc4e1c1
JB
2025
2026 return Qnil;
2027}
2028
b49f5578 2029/* Should we have a corresponding function called Flower_Power? */
e518d5e1 2030DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
14ff1ee0
PJ
2031 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2032If you don't specify a frame, the selected frame is used.
2033If Emacs is displaying on an ordinary terminal or some other device which
2034doesn't support multiple overlapping frames, this function does nothing. */)
2035 (frame)
dbc4e1c1
JB
2036 Lisp_Object frame;
2037{
428a555e
KL
2038 struct frame *f;
2039
828ac693 2040 if (NILP (frame))
8d2666fe 2041 frame = selected_frame;
828ac693 2042
b7826503 2043 CHECK_LIVE_FRAME (frame);
177c0ea7 2044
428a555e
KL
2045 f = XFRAME (frame);
2046
6ed8eeff
KL
2047 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2048 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
dbc4e1c1
JB
2049
2050 return Qnil;
2051}
2052
d5e7c279 2053\f
ff11dfa1 2054DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 2055 1, 2, 0,
14ff1ee0
PJ
2056 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2057In other words, switch-frame events caused by events in FRAME will
2058request a switch to FOCUS-FRAME, and `last-event-frame' will be
2059FOCUS-FRAME after reading an event typed at FRAME.
2060
2061If FOCUS-FRAME is omitted or nil, any existing redirection is
2062cancelled, and the frame again receives its own keystrokes.
2063
2064Focus redirection is useful for temporarily redirecting keystrokes to
2065a surrogate minibuffer frame when a frame doesn't have its own
2066minibuffer window.
2067
66a9dbbe 2068A frame's focus redirection can be changed by `select-frame'. If frame
14ff1ee0
PJ
2069FOO is selected, and then a different frame BAR is selected, any
2070frames redirecting their focus to FOO are shifted to redirect their
2071focus to BAR. This allows focus redirection to work properly when the
2072user switches from one frame to another using `select-window'.
2073
2074This means that a frame whose focus is redirected to itself is treated
2075differently from a frame whose focus is redirected to nil; the former
66a9dbbe 2076is affected by `select-frame', while the latter is not.
14ff1ee0
PJ
2077
2078The redirection lasts until `redirect-frame-focus' is called to change it. */)
2079 (frame, focus_frame)
2080 Lisp_Object frame, focus_frame;
d5e7c279 2081{
428a555e
KL
2082 struct frame *f;
2083
13144095
JB
2084 /* Note that we don't check for a live frame here. It's reasonable
2085 to redirect the focus of a frame you're about to delete, if you
2086 know what other frame should receive those keystrokes. */
b7826503 2087 CHECK_FRAME (frame);
f9898cc6 2088
a42e9724 2089 if (! NILP (focus_frame))
b7826503 2090 CHECK_LIVE_FRAME (focus_frame);
d5e7c279 2091
428a555e
KL
2092 f = XFRAME (frame);
2093
2094 f->focus_frame = focus_frame;
d5e7c279 2095
6ed8eeff
KL
2096 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
2097 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
177c0ea7 2098
d5e7c279
JB
2099 return Qnil;
2100}
2101
2102
ff11dfa1 2103DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
14ff1ee0
PJ
2104 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
2105This returns nil if FRAME's focus is not redirected.
2106See `redirect-frame-focus'. */)
2107 (frame)
2108 Lisp_Object frame;
d5e7c279 2109{
b7826503 2110 CHECK_LIVE_FRAME (frame);
a42e9724 2111
ff11dfa1 2112 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
2113}
2114
2115
dc6f92b8 2116\f
329ca574
RS
2117/* Return the value of frame parameter PROP in frame FRAME. */
2118
dc6f92b8 2119Lisp_Object
ff11dfa1
JB
2120get_frame_param (frame, prop)
2121 register struct frame *frame;
dc6f92b8
JB
2122 Lisp_Object prop;
2123{
2124 register Lisp_Object tem;
2125
ff11dfa1 2126 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
2127 if (EQ (tem, Qnil))
2128 return tem;
2129 return Fcdr (tem);
2130}
2131
329ca574
RS
2132/* Return the buffer-predicate of the selected frame. */
2133
2134Lisp_Object
98ce1622
RS
2135frame_buffer_predicate (frame)
2136 Lisp_Object frame;
329ca574 2137{
98ce1622 2138 return XFRAME (frame)->buffer_predicate;
329ca574
RS
2139}
2140
fa54c6ae
RS
2141/* Return the buffer-list of the selected frame. */
2142
2143Lisp_Object
98ce1622
RS
2144frame_buffer_list (frame)
2145 Lisp_Object frame;
fa54c6ae 2146{
98ce1622 2147 return XFRAME (frame)->buffer_list;
fa54c6ae
RS
2148}
2149
2150/* Set the buffer-list of the selected frame. */
2151
2152void
98ce1622
RS
2153set_frame_buffer_list (frame, list)
2154 Lisp_Object frame, list;
fa54c6ae 2155{
98ce1622 2156 XFRAME (frame)->buffer_list = list;
fa54c6ae
RS
2157}
2158
a18b8cb5 2159/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
fa54c6ae
RS
2160
2161void
2162frames_discard_buffer (buffer)
2163 Lisp_Object buffer;
2164{
2165 Lisp_Object frame, tail;
2166
2167 FOR_EACH_FRAME (tail, frame)
2168 {
2169 XFRAME (frame)->buffer_list
2170 = Fdelq (buffer, XFRAME (frame)->buffer_list);
a18b8cb5
KL
2171 XFRAME (frame)->buried_buffer_list
2172 = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
fa54c6ae
RS
2173 }
2174}
2175
329ca574
RS
2176/* Modify the alist in *ALISTPTR to associate PROP with VAL.
2177 If the alist already has an element for PROP, we change it. */
2178
dc6f92b8 2179void
fd0c2bd1 2180store_in_alist (alistptr, prop, val)
dc6f92b8 2181 Lisp_Object *alistptr, val;
fd0c2bd1 2182 Lisp_Object prop;
dc6f92b8
JB
2183{
2184 register Lisp_Object tem;
dc6f92b8 2185
dc6f92b8
JB
2186 tem = Fassq (prop, *alistptr);
2187 if (EQ (tem, Qnil))
2188 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2189 else
2190 Fsetcdr (tem, val);
2191}
2192
e5317d61
EZ
2193static int
2194frame_name_fnn_p (str, len)
2195 char *str;
2196 int len;
2197{
2198 if (len > 1 && str[0] == 'F')
2199 {
2200 char *end_ptr;
e5317d61 2201
48970f2f
EZ
2202 strtol (str + 1, &end_ptr, 10);
2203
e5317d61
EZ
2204 if (end_ptr == str + len)
2205 return 1;
2206 }
2207 return 0;
2208}
2209
2210/* Set the name of the terminal frame. Also used by MSDOS frames.
2211 Modeled after x_set_name which is used for WINDOW frames. */
2212
66a9dbbe 2213static void
e5317d61
EZ
2214set_term_frame_name (f, name)
2215 struct frame *f;
2216 Lisp_Object name;
2217{
2218 f->explicit_name = ! NILP (name);
2219
2220 /* If NAME is nil, set the name to F<num>. */
2221 if (NILP (name))
2222 {
2223 char namebuf[20];
2224
2225 /* Check for no change needed in this very common case
2226 before we do any consing. */
d5db4077
KR
2227 if (frame_name_fnn_p (SDATA (f->name),
2228 SBYTES (f->name)))
e5317d61
EZ
2229 return;
2230
6ed8eeff
KL
2231 tty_frame_count++;
2232 sprintf (namebuf, "F%d", tty_frame_count);
e5317d61
EZ
2233 name = build_string (namebuf);
2234 }
2235 else
2236 {
b7826503 2237 CHECK_STRING (name);
e5317d61
EZ
2238
2239 /* Don't change the name if it's already NAME. */
2240 if (! NILP (Fstring_equal (name, f->name)))
2241 return;
2242
2243 /* Don't allow the user to set the frame name to F<num>, so it
2244 doesn't clash with the names we generate for terminal frames. */
d5db4077 2245 if (frame_name_fnn_p (SDATA (name), SBYTES (name)))
e5317d61
EZ
2246 error ("Frame names of the form F<num> are usurped by Emacs");
2247 }
2248
2249 f->name = name;
2250 update_mode_lines = 1;
2251}
2252
dc6f92b8 2253void
ff11dfa1
JB
2254store_frame_param (f, prop, val)
2255 struct frame *f;
dc6f92b8
JB
2256 Lisp_Object prop, val;
2257{
7eb63b72 2258 register Lisp_Object old_alist_elt;
dc6f92b8 2259
a18b8cb5
KL
2260 /* The buffer-list parameters are stored in a special place and not
2261 in the alist. */
fa54c6ae
RS
2262 if (EQ (prop, Qbuffer_list))
2263 {
2264 f->buffer_list = val;
2265 return;
2266 }
a18b8cb5
KL
2267 if (EQ (prop, Qburied_buffer_list))
2268 {
2269 f->buried_buffer_list = val;
2270 return;
2271 }
fa54c6ae 2272
7eb63b72
GM
2273 /* If PROP is a symbol which is supposed to have frame-local values,
2274 and it is set up based on this frame, switch to the global
2275 binding. That way, we can create or alter the frame-local binding
2276 without messing up the symbol's status. */
2277 if (SYMBOLP (prop))
2278 {
2279 Lisp_Object valcontents;
f5c1dd0d 2280 valcontents = SYMBOL_VALUE (prop);
7eb63b72
GM
2281 if ((BUFFER_LOCAL_VALUEP (valcontents)
2282 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
2283 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
2284 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
2285 swap_in_global_binding (prop);
2286 }
2287
94674d18
EZ
2288#ifndef WINDOWSNT
2289 /* The tty color mode needs to be set before the frame's parameter
2290 alist is updated with the new value, because set_tty_color_mode
2291 wants to look at the old mode. */
2292 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode))
2293 set_tty_color_mode (f, val);
2294#endif
2295
7eb63b72
GM
2296 /* Update the frame parameter alist. */
2297 old_alist_elt = Fassq (prop, f->param_alist);
2298 if (EQ (old_alist_elt, Qnil))
ff11dfa1 2299 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8 2300 else
7eb63b72 2301 Fsetcdr (old_alist_elt, val);
bc93c097 2302
7eb63b72
GM
2303 /* Update some other special parameters in their special places
2304 in addition to the alist. */
177c0ea7 2305
329ca574
RS
2306 if (EQ (prop, Qbuffer_predicate))
2307 f->buffer_predicate = val;
2308
032d78fe 2309 if (! FRAME_WINDOW_P (f))
e5317d61
EZ
2310 {
2311 if (EQ (prop, Qmenu_bar_lines))
2312 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2313 else if (EQ (prop, Qname))
2314 set_term_frame_name (f, val);
2315 }
a249de79 2316
e35d291d 2317 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
2318 {
2319 if (! MINI_WINDOW_P (XWINDOW (val)))
7c402969 2320 error ("Surrogate minibuffer windows must be minibuffer windows");
bc93c097 2321
213bac8a 2322 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
7af7ef38
KH
2323 && !EQ (val, f->minibuffer_window))
2324 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
2325
2326 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 2327 f->minibuffer_window = val;
bc93c097 2328 }
dc6f92b8
JB
2329}
2330
ff11dfa1 2331DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
14ff1ee0
PJ
2332 doc: /* Return the parameters-alist of frame FRAME.
2333It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2334The meaningful PARMs depend on the kind of frame.
2335If FRAME is omitted, return information on the currently selected frame. */)
2336 (frame)
ff11dfa1 2337 Lisp_Object frame;
dc6f92b8
JB
2338{
2339 Lisp_Object alist;
f769f1b2 2340 FRAME_PTR f;
dd10ec4f 2341 int height, width;
57629833 2342 struct gcpro gcpro1;
dc6f92b8 2343
03390a72 2344 if (NILP (frame))
8d2666fe
GM
2345 frame = selected_frame;
2346
b7826503 2347 CHECK_FRAME (frame);
8d2666fe 2348 f = XFRAME (frame);
dc6f92b8 2349
f769f1b2 2350 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
2351 return Qnil;
2352
ff11dfa1 2353 alist = Fcopy_alist (f->param_alist);
57629833 2354 GCPRO1 (alist);
177c0ea7 2355
2d764c78 2356 if (!FRAME_WINDOW_P (f))
bb221971 2357 {
4aec4b29
EZ
2358 int fg = FRAME_FOREGROUND_PIXEL (f);
2359 int bg = FRAME_BACKGROUND_PIXEL (f);
e1d0bbc9
EZ
2360 Lisp_Object elt;
2361
2362 /* If the frame's parameter alist says the colors are
2363 unspecified and reversed, take the frame's background pixel
2364 for foreground and vice versa. */
2365 elt = Fassq (Qforeground_color, alist);
70de9f06
EZ
2366 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2367 {
d5db4077 2368 if (strncmp (SDATA (XCDR (elt)),
70de9f06 2369 unspecified_bg,
d5db4077 2370 SCHARS (XCDR (elt))) == 0)
70de9f06 2371 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
d5db4077 2372 else if (strncmp (SDATA (XCDR (elt)),
70de9f06 2373 unspecified_fg,
d5db4077 2374 SCHARS (XCDR (elt))) == 0)
70de9f06
EZ
2375 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2376 }
e1d0bbc9
EZ
2377 else
2378 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2379 elt = Fassq (Qbackground_color, alist);
70de9f06
EZ
2380 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2381 {
d5db4077 2382 if (strncmp (SDATA (XCDR (elt)),
70de9f06 2383 unspecified_fg,
d5db4077 2384 SCHARS (XCDR (elt))) == 0)
70de9f06 2385 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
d5db4077 2386 else if (strncmp (SDATA (XCDR (elt)),
70de9f06 2387 unspecified_bg,
d5db4077 2388 SCHARS (XCDR (elt))) == 0)
70de9f06
EZ
2389 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2390 }
e1d0bbc9
EZ
2391 else
2392 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2d764c78
EZ
2393 store_in_alist (&alist, intern ("font"),
2394 build_string (FRAME_MSDOS_P (f)
2395 ? "ms-dos"
4ec0d3c1 2396 : FRAME_W32_P (f) ? "w32term"
4ec0d3c1 2397 :"tty"));
bb221971 2398 }
fd0c2bd1 2399 store_in_alist (&alist, Qname, f->name);
5af5757b 2400 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
dd10ec4f 2401 store_in_alist (&alist, Qheight, make_number (height));
5af5757b 2402 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
dd10ec4f 2403 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 2404 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 2405 store_in_alist (&alist, Qminibuffer,
39acc701 2406 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
2407 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2408 : FRAME_MINIBUF_WINDOW (f)));
2409 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
03390a72 2410 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
a18b8cb5 2411 store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
fd0c2bd1 2412
dbc4e1c1 2413 /* I think this should be done with a hook. */
032d78fe
GV
2414#ifdef HAVE_WINDOW_SYSTEM
2415 if (FRAME_WINDOW_P (f))
ff11dfa1 2416 x_report_frame_params (f, &alist);
b6dd20ed 2417 else
fd0c2bd1 2418#endif
16a3738c
KH
2419 {
2420 /* This ought to be correct in f->param_alist for an X frame. */
2421 Lisp_Object lines;
f4e93c40 2422 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
2423 store_in_alist (&alist, Qmenu_bar_lines, lines);
2424 }
57629833
GM
2425
2426 UNGCPRO;
dc6f92b8
JB
2427 return alist;
2428}
2429
8b60f7bc
GM
2430
2431DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
14ff1ee0
PJ
2432 doc: /* Return FRAME's value for parameter PARAMETER.
2433If FRAME is nil, describe the currently selected frame. */)
2434 (frame, parameter)
2435 Lisp_Object frame, parameter;
8b60f7bc
GM
2436{
2437 struct frame *f;
2438 Lisp_Object value;
2439
2440 if (NILP (frame))
2441 frame = selected_frame;
2442 else
b7826503
PJ
2443 CHECK_FRAME (frame);
2444 CHECK_SYMBOL (parameter);
177c0ea7 2445
8b60f7bc
GM
2446 f = XFRAME (frame);
2447 value = Qnil;
177c0ea7 2448
8b60f7bc
GM
2449 if (FRAME_LIVE_P (f))
2450 {
5cd62b8c 2451 /* Avoid consing in frequent cases. */
67d853e6
GM
2452 if (EQ (parameter, Qname))
2453 value = f->name;
6345f6aa
GM
2454#ifdef HAVE_X_WINDOWS
2455 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2456 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2457#endif /* HAVE_X_WINDOWS */
75700ff2
GM
2458 else if (EQ (parameter, Qbackground_color)
2459 || EQ (parameter, Qforeground_color))
67d853e6
GM
2460 {
2461 value = Fassq (parameter, f->param_alist);
2462 if (CONSP (value))
5f65b39d 2463 {
5f65b39d
EZ
2464 value = XCDR (value);
2465 /* Fframe_parameters puts the actual fg/bg color names,
2466 even if f->param_alist says otherwise. This is
2467 important when param_alist's notion of colors is
2468 "unspecified". We need to do the same here. */
2469 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2470 {
c9b08ba8 2471 const char *color_name;
e1d0bbc9
EZ
2472 EMACS_INT csz;
2473
2474 if (EQ (parameter, Qbackground_color))
2475 {
d5db4077
KR
2476 color_name = SDATA (value);
2477 csz = SCHARS (value);
e1d0bbc9
EZ
2478 if (strncmp (color_name, unspecified_bg, csz) == 0)
2479 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2480 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2481 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2482 }
2483 else if (EQ (parameter, Qforeground_color))
2484 {
d5db4077
KR
2485 color_name = SDATA (value);
2486 csz = SCHARS (value);
e1d0bbc9
EZ
2487 if (strncmp (color_name, unspecified_fg, csz) == 0)
2488 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2489 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2490 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2491 }
5f65b39d
EZ
2492 }
2493 }
b23236fb
EZ
2494 else
2495 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
67d853e6 2496 }
75700ff2
GM
2497 else if (EQ (parameter, Qdisplay_type)
2498 || EQ (parameter, Qbackground_mode))
75700ff2
GM
2499 value = Fcdr (Fassq (parameter, f->param_alist));
2500 else
2501 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
8b60f7bc 2502 }
177c0ea7 2503
8b60f7bc
GM
2504 return value;
2505}
2506
2507
177c0ea7 2508DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
ff11dfa1 2509 Smodify_frame_parameters, 2, 2, 0,
14ff1ee0
PJ
2510 doc: /* Modify the parameters of frame FRAME according to ALIST.
2511If FRAME is nil, it defaults to the selected frame.
2512ALIST is an alist of parameters to change and their new values.
2513Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2514The meaningful PARMs depend on the kind of frame.
2515Undefined PARMs are ignored, but stored in the frame's parameter list
2516so that `frame-parameters' will return them.
2517
2518The value of frame parameter FOO can also be accessed
2519as a frame-local binding for the variable FOO, if you have
2520enabled such bindings for that variable with `make-variable-frame-local'. */)
2521 (frame, alist)
ff11dfa1 2522 Lisp_Object frame, alist;
dc6f92b8 2523{
fd0c2bd1 2524 FRAME_PTR f;
213bac8a 2525 register Lisp_Object tail, prop, val;
331379bf 2526 int count = SPECPDL_INDEX ();
3df1fda2
GM
2527
2528 /* Bind this to t to inhibit initialization of the default face from
2529 X resources in face-set-after-frame-default. If we don't inhibit
2530 this, modifying the `font' frame parameter, for example, while
2531 there is a `default.attributeFont' X resource, won't work,
2532 because `default's font is reset to the value of the X resource
2533 and that resets the `font' frame parameter. */
2534 specbind (Qinhibit_default_face_x_resources, Qt);
dc6f92b8 2535
ff11dfa1 2536 if (EQ (frame, Qnil))
8d2666fe 2537 frame = selected_frame;
b7826503 2538 CHECK_LIVE_FRAME (frame);
8d2666fe 2539 f = XFRAME (frame);
dc6f92b8 2540
dbc4e1c1 2541 /* I think this should be done with a hook. */
032d78fe
GV
2542#ifdef HAVE_WINDOW_SYSTEM
2543 if (FRAME_WINDOW_P (f))
fd0c2bd1 2544 x_set_frame_parameters (f, alist);
329ca574 2545 else
bb221971
RS
2546#endif
2547#ifdef MSDOS
2548 if (FRAME_MSDOS_P (f))
2549 IT_set_frame_parameters (f, alist);
2550 else
329ca574 2551#endif
574a1a90 2552
41d44f1f
RS
2553 {
2554 int length = XINT (Flength (alist));
2555 int i;
2556 Lisp_Object *parms
2557 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2558 Lisp_Object *values
2559 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2560
2561 /* Extract parm names and values into those vectors. */
2562
2563 i = 0;
2564 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2565 {
213bac8a 2566 Lisp_Object elt;
41d44f1f
RS
2567
2568 elt = Fcar (tail);
2569 parms[i] = Fcar (elt);
2570 values[i] = Fcdr (elt);
2571 i++;
2572 }
2573
2574 /* Now process them in reverse of specified order. */
2575 for (i--; i >= 0; i--)
2576 {
2577 prop = parms[i];
2578 val = values[i];
2579 store_frame_param (f, prop, val);
33d537f0
JL
2580
2581 /* Changing the background color might change the background
2582 mode, so that we have to load new defface specs.
2583 Call frame-set-background-mode to do that. */
2584 if (EQ (prop, Qbackground_color))
2585 call1 (Qframe_set_background_mode, frame);
41d44f1f
RS
2586 }
2587 }
dc6f92b8 2588
3df1fda2 2589 return unbind_to (count, Qnil);
dc6f92b8 2590}
da8e8fc1
KL
2591
2592DEFUN ("frame-with-environment", Fframe_with_environment, Sframe_with_environment, 0, 1, 0,
2593 doc: /* Return the frame that has the environment variable list for FRAME.
2594
2595The frame-local environment variable list is normally shared between
2596frames that were created in the same Emacsclient session. The
2597environment list is stored in a single frame's 'environment parameter;
2598the other frames' 'environment parameter is set to this frame. This
2599function follows to chain of 'environment references to reach the
2600frame that stores the actual local environment list, and returns that
2601frame. */)
2602 (frame)
2603 Lisp_Object frame;
2604{
2605 Lisp_Object hare, tortoise;
2606
2607 if (NILP (frame))
2608 frame = selected_frame;
2609 CHECK_FRAME (frame);
2610
2611 hare = tortoise = get_frame_param (XFRAME (frame), Qenvironment);
2612 while (!NILP (hare) && FRAMEP (hare))
2613 {
2614 frame = hare;
2615 hare = get_frame_param (XFRAME (hare), Qenvironment);
2616 if (NILP (hare) || !FRAMEP (hare))
2617 break;
2618 frame = hare;
2619 hare = get_frame_param (XFRAME (hare), Qenvironment);
2620 tortoise = get_frame_param (XFRAME (tortoise), Qenvironment);
2621 if (EQ (hare, tortoise))
2622 error ("Cyclic frame-local environment indirection");
2623 }
2624
2625 return frame;
2626}
2627
dc6f92b8 2628\f
a26a1f95 2629DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
14ff1ee0
PJ
2630 0, 1, 0,
2631 doc: /* Height in pixels of a line in the font in frame FRAME.
2632If FRAME is omitted, the selected frame is used.
2633For a terminal frame, the value is always 1. */)
ff11dfa1
JB
2634 (frame)
2635 Lisp_Object frame;
dc6f92b8 2636{
a26a1f95 2637 struct frame *f;
dc6f92b8 2638
a26a1f95 2639 if (NILP (frame))
8d2666fe 2640 frame = selected_frame;
b7826503 2641 CHECK_FRAME (frame);
8d2666fe 2642 f = XFRAME (frame);
a26a1f95 2643
032d78fe
GV
2644#ifdef HAVE_WINDOW_SYSTEM
2645 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2646 return make_number (x_char_height (f));
2647 else
dc6d9681 2648#endif
a26a1f95
RS
2649 return make_number (1);
2650}
dc6d9681 2651
dc6f92b8 2652
a26a1f95 2653DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
14ff1ee0
PJ
2654 0, 1, 0,
2655 doc: /* Width in pixels of characters in the font in frame FRAME.
2656If FRAME is omitted, the selected frame is used.
31b7cc74 2657On a graphical screen, the width is the standard width of the default font.
14ff1ee0
PJ
2658For a terminal screen, the value is always 1. */)
2659 (frame)
a26a1f95 2660 Lisp_Object frame;
dc6f92b8 2661{
a26a1f95
RS
2662 struct frame *f;
2663
2664 if (NILP (frame))
8d2666fe 2665 frame = selected_frame;
b7826503 2666 CHECK_FRAME (frame);
8d2666fe 2667 f = XFRAME (frame);
a26a1f95 2668
032d78fe
GV
2669#ifdef HAVE_WINDOW_SYSTEM
2670 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2671 return make_number (x_char_width (f));
2672 else
2673#endif
2674 return make_number (1);
dc6f92b8
JB
2675}
2676
177c0ea7 2677DEFUN ("frame-pixel-height", Fframe_pixel_height,
a26a1f95 2678 Sframe_pixel_height, 0, 1, 0,
14ff1ee0
PJ
2679 doc: /* Return a FRAME's height in pixels.
2680This counts only the height available for text lines,
2681not menu bars on window-system Emacs frames.
2682For a terminal frame, the result really gives the height in characters.
2683If FRAME is omitted, the selected frame is used. */)
2684 (frame)
a26a1f95 2685 Lisp_Object frame;
dc6f92b8 2686{
a26a1f95
RS
2687 struct frame *f;
2688
2689 if (NILP (frame))
8d2666fe 2690 frame = selected_frame;
b7826503 2691 CHECK_FRAME (frame);
8d2666fe 2692 f = XFRAME (frame);
a26a1f95 2693
032d78fe
GV
2694#ifdef HAVE_WINDOW_SYSTEM
2695 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2696 return make_number (x_pixel_height (f));
2697 else
dc6d9681 2698#endif
5af5757b 2699 return make_number (FRAME_LINES (f));
a26a1f95
RS
2700}
2701
177c0ea7 2702DEFUN ("frame-pixel-width", Fframe_pixel_width,
a26a1f95 2703 Sframe_pixel_width, 0, 1, 0,
14ff1ee0
PJ
2704 doc: /* Return FRAME's width in pixels.
2705For a terminal frame, the result really gives the width in characters.
2706If FRAME is omitted, the selected frame is used. */)
2707 (frame)
a26a1f95
RS
2708 Lisp_Object frame;
2709{
2710 struct frame *f;
2711
2712 if (NILP (frame))
8d2666fe 2713 frame = selected_frame;
b7826503 2714 CHECK_FRAME (frame);
8d2666fe 2715 f = XFRAME (frame);
dc6f92b8 2716
032d78fe
GV
2717#ifdef HAVE_WINDOW_SYSTEM
2718 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2719 return make_number (x_pixel_width (f));
2720 else
2721#endif
5af5757b 2722 return make_number (FRAME_COLS (f));
a26a1f95
RS
2723}
2724\f
ff11dfa1 2725DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
14ff1ee0
PJ
2726 doc: /* Specify that the frame FRAME has LINES lines.
2727Optional third arg non-nil means that redisplay should use LINES lines
2728but that the idea of the actual height of the frame should not be changed. */)
2729 (frame, lines, pretend)
735eeca3 2730 Lisp_Object frame, lines, pretend;
dc6f92b8 2731{
ff11dfa1 2732 register struct frame *f;
dc6f92b8 2733
b7826503 2734 CHECK_NUMBER (lines);
ff11dfa1 2735 if (NILP (frame))
8d2666fe 2736 frame = selected_frame;
b7826503 2737 CHECK_LIVE_FRAME (frame);
8d2666fe 2738 f = XFRAME (frame);
dc6f92b8 2739
dbc4e1c1 2740 /* I think this should be done with a hook. */
032d78fe
GV
2741#ifdef HAVE_WINDOW_SYSTEM
2742 if (FRAME_WINDOW_P (f))
dc6f92b8 2743 {
5af5757b
KS
2744 if (XINT (lines) != FRAME_LINES (f))
2745 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
32347cf4 2746 do_pending_window_change (0);
dc6f92b8
JB
2747 }
2748 else
fd0c2bd1 2749#endif
32347cf4 2750 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
dc6f92b8
JB
2751 return Qnil;
2752}
2753
ff11dfa1 2754DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
14ff1ee0
PJ
2755 doc: /* Specify that the frame FRAME has COLS columns.
2756Optional third arg non-nil means that redisplay should use COLS columns
2757but that the idea of the actual width of the frame should not be changed. */)
2758 (frame, cols, pretend)
fd0c2bd1 2759 Lisp_Object frame, cols, pretend;
dc6f92b8 2760{
ff11dfa1 2761 register struct frame *f;
b7826503 2762 CHECK_NUMBER (cols);
ff11dfa1 2763 if (NILP (frame))
8d2666fe 2764 frame = selected_frame;
b7826503 2765 CHECK_LIVE_FRAME (frame);
8d2666fe 2766 f = XFRAME (frame);
dc6f92b8 2767
dbc4e1c1 2768 /* I think this should be done with a hook. */
032d78fe
GV
2769#ifdef HAVE_WINDOW_SYSTEM
2770 if (FRAME_WINDOW_P (f))
dc6f92b8 2771 {
5af5757b
KS
2772 if (XINT (cols) != FRAME_COLS (f))
2773 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
32347cf4 2774 do_pending_window_change (0);
dc6f92b8
JB
2775 }
2776 else
fd0c2bd1 2777#endif
32347cf4 2778 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
dc6f92b8
JB
2779 return Qnil;
2780}
2781
ff11dfa1 2782DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
14ff1ee0
PJ
2783 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2784 (frame, cols, rows)
ff11dfa1 2785 Lisp_Object frame, cols, rows;
dc6f92b8 2786{
ff11dfa1 2787 register struct frame *f;
dc6f92b8 2788
b7826503
PJ
2789 CHECK_LIVE_FRAME (frame);
2790 CHECK_NUMBER (cols);
2791 CHECK_NUMBER (rows);
ff11dfa1 2792 f = XFRAME (frame);
dc6f92b8 2793
dbc4e1c1 2794 /* I think this should be done with a hook. */
032d78fe
GV
2795#ifdef HAVE_WINDOW_SYSTEM
2796 if (FRAME_WINDOW_P (f))
dc6f92b8 2797 {
5af5757b
KS
2798 if (XINT (rows) != FRAME_LINES (f)
2799 || XINT (cols) != FRAME_COLS (f)
2800 || f->new_text_lines || f->new_text_cols)
808c0f20 2801 x_set_window_size (f, 1, XINT (cols), XINT (rows));
32347cf4 2802 do_pending_window_change (0);
dc6f92b8
JB
2803 }
2804 else
fd0c2bd1 2805#endif
32347cf4 2806 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
dc6f92b8
JB
2807
2808 return Qnil;
2809}
2810
177c0ea7 2811DEFUN ("set-frame-position", Fset_frame_position,
ff11dfa1 2812 Sset_frame_position, 3, 3, 0,
14ff1ee0
PJ
2813 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2814This is actually the position of the upper left corner of the frame.
2815Negative values for XOFFSET or YOFFSET are interpreted relative to
2816the rightmost or bottommost possible position (that stays within the screen). */)
2817 (frame, xoffset, yoffset)
ff11dfa1 2818 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2819{
ff11dfa1 2820 register struct frame *f;
dc6f92b8 2821
b7826503
PJ
2822 CHECK_LIVE_FRAME (frame);
2823 CHECK_NUMBER (xoffset);
2824 CHECK_NUMBER (yoffset);
ff11dfa1 2825 f = XFRAME (frame);
dc6f92b8 2826
dbc4e1c1 2827 /* I think this should be done with a hook. */
032d78fe
GV
2828#ifdef HAVE_WINDOW_SYSTEM
2829 if (FRAME_WINDOW_P (f))
c7c70761 2830 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2831#endif
dc6f92b8
JB
2832
2833 return Qt;
2834}
dc6d9681 2835
dc6f92b8 2836\f
972f4259
KS
2837/***********************************************************************
2838 Frame Parameters
2839 ***********************************************************************/
2840
2841/* Connect the frame-parameter names for X frames
2842 to the ways of passing the parameter values to the window system.
2843
2844 The name of a parameter, as a Lisp symbol,
2845 has an `x-frame-parameter' property which is an integer in Lisp
2846 that is an index in this table. */
2847
2848struct frame_parm_table {
2849 char *name;
2850 Lisp_Object *variable;
2851};
2852
2853static struct frame_parm_table frame_parms[] =
2854{
2855 {"auto-raise", &Qauto_raise},
2856 {"auto-lower", &Qauto_lower},
2857 {"background-color", 0},
2858 {"border-color", &Qborder_color},
2859 {"border-width", &Qborder_width},
2860 {"cursor-color", &Qcursor_color},
2861 {"cursor-type", &Qcursor_type},
2862 {"font", 0},
2863 {"foreground-color", 0},
2864 {"icon-name", &Qicon_name},
2865 {"icon-type", &Qicon_type},
2866 {"internal-border-width", &Qinternal_border_width},
2867 {"menu-bar-lines", &Qmenu_bar_lines},
2868 {"mouse-color", &Qmouse_color},
2869 {"name", &Qname},
2870 {"scroll-bar-width", &Qscroll_bar_width},
2871 {"title", &Qtitle},
2872 {"unsplittable", &Qunsplittable},
2873 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2874 {"visibility", &Qvisibility},
2875 {"tool-bar-lines", &Qtool_bar_lines},
2876 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2877 {"scroll-bar-background", &Qscroll_bar_background},
2878 {"screen-gamma", &Qscreen_gamma},
2879 {"line-spacing", &Qline_spacing},
2880 {"left-fringe", &Qleft_fringe},
2881 {"right-fringe", &Qright_fringe},
2882 {"wait-for-wm", &Qwait_for_wm},
2883 {"fullscreen", &Qfullscreen},
2884};
2885
2886#ifdef HAVE_WINDOW_SYSTEM
2887
2888extern Lisp_Object Qbox;
2889extern Lisp_Object Qtop;
2890
2891/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2892 wanted positions of the WM window (not emacs window).
2893 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2894 window (FRAME_X_WINDOW).
2895 */
2896
dfcf069d 2897void
972f4259
KS
2898x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2899 struct frame *f;
2900 int *width;
2901 int *height;
2902 int *top_pos;
2903 int *left_pos;
dc6f92b8 2904{
5af5757b
KS
2905 int newwidth = FRAME_COLS (f);
2906 int newheight = FRAME_LINES (f);
dc6f92b8 2907
5af5757b
KS
2908 *top_pos = f->top_pos;
2909 *left_pos = f->left_pos;
3df1fda2 2910
5af5757b 2911 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
972f4259
KS
2912 {
2913 int ph;
2914
2915 ph = FRAME_X_DISPLAY_INFO (f)->height;
5af5757b
KS
2916 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2917 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2918 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
972f4259
KS
2919 *top_pos = 0;
2920 }
dc6f92b8 2921
5af5757b 2922 if (f->want_fullscreen & FULLSCREEN_WIDTH)
972f4259
KS
2923 {
2924 int pw;
2925
2926 pw = FRAME_X_DISPLAY_INFO (f)->width;
5af5757b
KS
2927 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2928 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2929 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
972f4259
KS
2930 *left_pos = 0;
2931 }
dc6f92b8 2932
972f4259
KS
2933 *width = newwidth;
2934 *height = newheight;
2935}
dc6f92b8 2936
beb0bc36 2937
972f4259
KS
2938/* Change the parameters of frame F as specified by ALIST.
2939 If a parameter is not specially recognized, do nothing special;
2940 otherwise call the `x_set_...' function for that parameter.
2941 Except for certain geometry properties, always call store_frame_param
2942 to store the new value in the parameter alist. */
14ff1ee0 2943
972f4259
KS
2944void
2945x_set_frame_parameters (f, alist)
2946 FRAME_PTR f;
2947 Lisp_Object alist;
2948{
2949 Lisp_Object tail;
dc6f92b8 2950
972f4259
KS
2951 /* If both of these parameters are present, it's more efficient to
2952 set them both at once. So we wait until we've looked at the
2953 entire list before we set them. */
2954 int width, height;
3df1fda2 2955
972f4259
KS
2956 /* Same here. */
2957 Lisp_Object left, top;
2958
2959 /* Same with these. */
2960 Lisp_Object icon_left, icon_top;
2961
2962 /* Record in these vectors all the parms specified. */
2963 Lisp_Object *parms;
2964 Lisp_Object *values;
2965 int i, p;
2966 int left_no_change = 0, top_no_change = 0;
2967 int icon_left_no_change = 0, icon_top_no_change = 0;
2968 int fullscreen_is_being_set = 0;
2969
2970 struct gcpro gcpro1, gcpro2;
2971
2972 i = 0;
2973 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2974 i++;
2975
2976 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2977 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2978
2979 /* Extract parm names and values into those vectors. */
2980
2981 i = 0;
2982 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2983 {
2984 Lisp_Object elt;
2985
2986 elt = Fcar (tail);
2987 parms[i] = Fcar (elt);
2988 values[i] = Fcdr (elt);
2989 i++;
2990 }
2991 /* TAIL and ALIST are not used again below here. */
2992 alist = tail = Qnil;
2993
2994 GCPRO2 (*parms, *values);
2995 gcpro1.nvars = i;
2996 gcpro2.nvars = i;
2997
2998 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2999 because their values appear in VALUES and strings are not valid. */
3000 top = left = Qunbound;
3001 icon_left = icon_top = Qunbound;
3002
3003 /* Provide default values for HEIGHT and WIDTH. */
5af5757b
KS
3004 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
3005 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
972f4259
KS
3006
3007 /* Process foreground_color and background_color before anything else.
3008 They are independent of other properties, but other properties (e.g.,
3009 cursor_color) are dependent upon them. */
3010 /* Process default font as well, since fringe widths depends on it. */
3011 /* Also, process fullscreen, width and height depend upon that */
3012 for (p = 0; p < i; p++)
3013 {
3014 Lisp_Object prop, val;
3015
3016 prop = parms[p];
3017 val = values[p];
3018 if (EQ (prop, Qforeground_color)
3019 || EQ (prop, Qbackground_color)
3020 || EQ (prop, Qfont)
3021 || EQ (prop, Qfullscreen))
3022 {
3023 register Lisp_Object param_index, old_value;
3024
3025 old_value = get_frame_param (f, prop);
3026 fullscreen_is_being_set |= EQ (prop, Qfullscreen);
3027
3028 if (NILP (Fequal (val, old_value)))
3029 {
3030 store_frame_param (f, prop, val);
3031
3032 param_index = Fget (prop, Qx_frame_parameter);
3033 if (NATNUMP (param_index)
3034 && (XFASTINT (param_index)
3035 < sizeof (frame_parms)/sizeof (frame_parms[0]))
fa971ac3
KL
3036 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3037 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
972f4259
KS
3038 }
3039 }
3040 }
3041
3042 /* Now process them in reverse of specified order. */
3043 for (i--; i >= 0; i--)
3044 {
3045 Lisp_Object prop, val;
3046
3047 prop = parms[i];
3048 val = values[i];
3049
3050 if (EQ (prop, Qwidth) && NUMBERP (val))
3051 width = XFASTINT (val);
3052 else if (EQ (prop, Qheight) && NUMBERP (val))
3053 height = XFASTINT (val);
3054 else if (EQ (prop, Qtop))
3055 top = val;
3056 else if (EQ (prop, Qleft))
3057 left = val;
3058 else if (EQ (prop, Qicon_top))
3059 icon_top = val;
3060 else if (EQ (prop, Qicon_left))
3061 icon_left = val;
3062 else if (EQ (prop, Qforeground_color)
3063 || EQ (prop, Qbackground_color)
3064 || EQ (prop, Qfont)
3065 || EQ (prop, Qfullscreen))
3066 /* Processed above. */
3067 continue;
3068 else
3069 {
3070 register Lisp_Object param_index, old_value;
3071
3072 old_value = get_frame_param (f, prop);
3073
3074 store_frame_param (f, prop, val);
3075
3076 param_index = Fget (prop, Qx_frame_parameter);
3077 if (NATNUMP (param_index)
3078 && (XFASTINT (param_index)
3079 < sizeof (frame_parms)/sizeof (frame_parms[0]))
fa971ac3
KL
3080 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3081 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
972f4259
KS
3082 }
3083 }
3084
3085 /* Don't die if just one of these was set. */
3086 if (EQ (left, Qunbound))
3087 {
3088 left_no_change = 1;
5af5757b
KS
3089 if (f->left_pos < 0)
3090 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
972f4259 3091 else
5af5757b 3092 XSETINT (left, f->left_pos);
972f4259
KS
3093 }
3094 if (EQ (top, Qunbound))
3095 {
3096 top_no_change = 1;
5af5757b
KS
3097 if (f->top_pos < 0)
3098 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
972f4259 3099 else
5af5757b 3100 XSETINT (top, f->top_pos);
972f4259
KS
3101 }
3102
3103 /* If one of the icon positions was not set, preserve or default it. */
3104 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
3105 {
3106 icon_left_no_change = 1;
3107 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
3108 if (NILP (icon_left))
3109 XSETINT (icon_left, 0);
3110 }
3111 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
3112 {
3113 icon_top_no_change = 1;
3114 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
3115 if (NILP (icon_top))
3116 XSETINT (icon_top, 0);
3117 }
3118
972f4259
KS
3119 if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
3120 {
3121 /* If the frame is visible already and the fullscreen parameter is
3122 being set, it is too late to set WM manager hints to specify
3123 size and position.
3124 Here we first get the width, height and position that applies to
3125 fullscreen. We then move the frame to the appropriate
3126 position. Resize of the frame is taken care of in the code after
3127 this if-statement. */
3128 int new_left, new_top;
3129
3130 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
068ae0fd
JD
3131 if (new_top != f->top_pos || new_left != f->left_pos)
3132 x_set_offset (f, new_left, new_top, 1);
972f4259 3133 }
972f4259
KS
3134
3135 /* Don't set these parameters unless they've been explicitly
3136 specified. The window might be mapped or resized while we're in
3137 this function, and we don't want to override that unless the lisp
3138 code has asked for it.
3139
3140 Don't set these parameters unless they actually differ from the
3141 window's current parameters; the window may not actually exist
3142 yet. */
3143 {
3144 Lisp_Object frame;
3145
3146 check_frame_size (f, &height, &width);
3147
3148 XSETFRAME (frame, f);
3149
5af5757b
KS
3150 if (width != FRAME_COLS (f)
3151 || height != FRAME_LINES (f)
3152 || f->new_text_lines || f->new_text_cols)
972f4259
KS
3153 Fset_frame_size (frame, make_number (width), make_number (height));
3154
3155 if ((!NILP (left) || !NILP (top))
3156 && ! (left_no_change && top_no_change)
5af5757b
KS
3157 && ! (NUMBERP (left) && XINT (left) == f->left_pos
3158 && NUMBERP (top) && XINT (top) == f->top_pos))
972f4259
KS
3159 {
3160 int leftpos = 0;
3161 int toppos = 0;
3162
3163 /* Record the signs. */
5af5757b 3164 f->size_hint_flags &= ~ (XNegative | YNegative);
972f4259 3165 if (EQ (left, Qminus))
5af5757b 3166 f->size_hint_flags |= XNegative;
972f4259
KS
3167 else if (INTEGERP (left))
3168 {
3169 leftpos = XINT (left);
3170 if (leftpos < 0)
5af5757b 3171 f->size_hint_flags |= XNegative;
972f4259
KS
3172 }
3173 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3174 && CONSP (XCDR (left))
3175 && INTEGERP (XCAR (XCDR (left))))
3176 {
3177 leftpos = - XINT (XCAR (XCDR (left)));
5af5757b 3178 f->size_hint_flags |= XNegative;
972f4259
KS
3179 }
3180 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3181 && CONSP (XCDR (left))
3182 && INTEGERP (XCAR (XCDR (left))))
3183 {
3184 leftpos = XINT (XCAR (XCDR (left)));
3185 }
3186
3187 if (EQ (top, Qminus))
5af5757b 3188 f->size_hint_flags |= YNegative;
972f4259
KS
3189 else if (INTEGERP (top))
3190 {
3191 toppos = XINT (top);
3192 if (toppos < 0)
5af5757b 3193 f->size_hint_flags |= YNegative;
972f4259
KS
3194 }
3195 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3196 && CONSP (XCDR (top))
3197 && INTEGERP (XCAR (XCDR (top))))
3198 {
3199 toppos = - XINT (XCAR (XCDR (top)));
5af5757b 3200 f->size_hint_flags |= YNegative;
972f4259
KS
3201 }
3202 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3203 && CONSP (XCDR (top))
3204 && INTEGERP (XCAR (XCDR (top))))
3205 {
3206 toppos = XINT (XCAR (XCDR (top)));
3207 }
3208
3209
3210 /* Store the numeric value of the position. */
5af5757b
KS
3211 f->top_pos = toppos;
3212 f->left_pos = leftpos;
972f4259 3213
5af5757b 3214 f->win_gravity = NorthWestGravity;
972f4259
KS
3215
3216 /* Actually set that position, and convert to absolute. */
3217 x_set_offset (f, leftpos, toppos, -1);
3218 }
3219
3220 if ((!NILP (icon_left) || !NILP (icon_top))
3221 && ! (icon_left_no_change && icon_top_no_change))
3222 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3223 }
3224
3225 UNGCPRO;
3226}
3227
3228
3229/* Insert a description of internally-recorded parameters of frame X
3230 into the parameter alist *ALISTPTR that is to be given to the user.
3231 Only parameters that are specific to the X window system
3232 and whose values are not correctly recorded in the frame's
3233 param_alist need to be considered here. */
3234
3235void
3236x_report_frame_params (f, alistptr)
3237 struct frame *f;
3238 Lisp_Object *alistptr;
3239{
3240 char buf[16];
3241 Lisp_Object tem;
3242
3243 /* Represent negative positions (off the top or left screen edge)
3244 in a way that Fmodify_frame_parameters will understand correctly. */
5af5757b
KS
3245 XSETINT (tem, f->left_pos);
3246 if (f->left_pos >= 0)
972f4259
KS
3247 store_in_alist (alistptr, Qleft, tem);
3248 else
3249 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
3250
5af5757b
KS
3251 XSETINT (tem, f->top_pos);
3252 if (f->top_pos >= 0)
972f4259
KS
3253 store_in_alist (alistptr, Qtop, tem);
3254 else
3255 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
3256
3257 store_in_alist (alistptr, Qborder_width,
5af5757b 3258 make_number (f->border_width));
972f4259 3259 store_in_alist (alistptr, Qinternal_border_width,
5af5757b 3260 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
972f4259 3261 store_in_alist (alistptr, Qleft_fringe,
5af5757b 3262 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
972f4259 3263 store_in_alist (alistptr, Qright_fringe,
5af5757b 3264 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
972f4259
KS
3265 store_in_alist (alistptr, Qscroll_bar_width,
3266 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3267 ? make_number (0)
5af5757b
KS
3268 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3269 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
972f4259
KS
3270 /* nil means "use default width"
3271 for non-toolkit scroll bar.
3272 ruler-mode.el depends on this. */
3273 : Qnil));
3274 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
3275 store_in_alist (alistptr, Qwindow_id,
3276 build_string (buf));
3277#ifdef HAVE_X_WINDOWS
3278#ifdef USE_X_TOOLKIT
3279 /* Tooltip frame may not have this widget. */
3280 if (FRAME_X_OUTPUT (f)->widget)
3281#endif
3282 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
3283 store_in_alist (alistptr, Qouter_window_id,
3284 build_string (buf));
3285#endif
3286 store_in_alist (alistptr, Qicon_name, f->icon_name);
3287 FRAME_SAMPLE_VISIBILITY (f);
3288 store_in_alist (alistptr, Qvisibility,
3289 (FRAME_VISIBLE_P (f) ? Qt
3290 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3291 store_in_alist (alistptr, Qdisplay,
3292 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
3293
3294 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
3295 tem = Qnil;
3296 else
3297 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
3298 store_in_alist (alistptr, Qparent_id, tem);
3299}
3300
3301
3302/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3303 the previous value of that parameter, NEW_VALUE is the new value. */
3304
3305void
3306x_set_fullscreen (f, new_value, old_value)
3307 struct frame *f;
3308 Lisp_Object new_value, old_value;
3309{
972f4259 3310 if (NILP (new_value))
5af5757b 3311 f->want_fullscreen = FULLSCREEN_NONE;
972f4259 3312 else if (EQ (new_value, Qfullboth))
5af5757b 3313 f->want_fullscreen = FULLSCREEN_BOTH;
972f4259 3314 else if (EQ (new_value, Qfullwidth))
5af5757b 3315 f->want_fullscreen = FULLSCREEN_WIDTH;
972f4259 3316 else if (EQ (new_value, Qfullheight))
5af5757b 3317 f->want_fullscreen = FULLSCREEN_HEIGHT;
972f4259
KS
3318}
3319
3320
3321/* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3322 the previous value of that parameter, NEW_VALUE is the new value. */
3323
3324void
3325x_set_line_spacing (f, new_value, old_value)
3326 struct frame *f;
3327 Lisp_Object new_value, old_value;
3328{
3329 if (NILP (new_value))
3330 f->extra_line_spacing = 0;
3331 else if (NATNUMP (new_value))
3332 f->extra_line_spacing = XFASTINT (new_value);
3333 else
3334 Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"),
3335 Fcons (new_value, Qnil)));
3336 if (FRAME_VISIBLE_P (f))
3337 redraw_frame (f);
3338}
3339
3340
3341/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3342 the previous value of that parameter, NEW_VALUE is the new value. */
3343
3344void
3345x_set_screen_gamma (f, new_value, old_value)
3346 struct frame *f;
3347 Lisp_Object new_value, old_value;
3348{
3349 if (NILP (new_value))
3350 f->gamma = 0;
3351 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3352 /* The value 0.4545 is the normal viewing gamma. */
3353 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3354 else
3355 Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"),
3356 Fcons (new_value, Qnil)));
3357
3358 clear_face_cache (0);
3359}
3360
3361
3362void
3363x_set_font (f, arg, oldval)
3364 struct frame *f;
3365 Lisp_Object arg, oldval;
3366{
3367 Lisp_Object result;
3368 Lisp_Object fontset_name;
3369 Lisp_Object frame;
3370 int old_fontset = FRAME_FONTSET(f);
3371
3372 CHECK_STRING (arg);
3373
3374 fontset_name = Fquery_fontset (arg, Qnil);
3375
3376 BLOCK_INPUT;
3377 result = (STRINGP (fontset_name)
3378 ? x_new_fontset (f, SDATA (fontset_name))
3379 : x_new_font (f, SDATA (arg)));
3380 UNBLOCK_INPUT;
3381
3382 if (EQ (result, Qnil))
3383 error ("Font `%s' is not defined", SDATA (arg));
3384 else if (EQ (result, Qt))
3385 error ("The characters of the given font have varying widths");
3386 else if (STRINGP (result))
3387 {
ee5d57b0 3388 set_default_ascii_font (result);
972f4259
KS
3389 if (STRINGP (fontset_name))
3390 {
3391 /* Fontset names are built from ASCII font names, so the
3392 names may be equal despite there was a change. */
3393 if (old_fontset == FRAME_FONTSET (f))
3394 return;
3395 }
3396 else if (!NILP (Fequal (result, oldval)))
3397 return;
3398
3399 store_frame_param (f, Qfont, result);
3400 recompute_basic_faces (f);
3401 }
3402 else
3403 abort ();
3404
3405 do_pending_window_change (0);
3406
3407 /* Don't call `face-set-after-frame-default' when faces haven't been
3408 initialized yet. This is the case when called from
3409 Fx_create_frame. In that case, the X widget or window doesn't
3410 exist either, and we can end up in x_report_frame_params with a
3411 null widget which gives a segfault. */
3412 if (FRAME_FACE_CACHE (f))
3413 {
3414 XSETFRAME (frame, f);
3415 call1 (Qface_set_after_frame_default, frame);
3416 }
3417}
3418
3419
3420void
3421x_set_fringe_width (f, new_value, old_value)
3422 struct frame *f;
3423 Lisp_Object new_value, old_value;
3424{
3425 compute_fringe_widths (f, 1);
3426}
3427
3428void
3429x_set_border_width (f, arg, oldval)
3430 struct frame *f;
3431 Lisp_Object arg, oldval;
3432{
3433 CHECK_NUMBER (arg);
3434
5af5757b 3435 if (XINT (arg) == f->border_width)
972f4259
KS
3436 return;
3437
b15325b2 3438#ifndef MAC_OS
972f4259
KS
3439 if (FRAME_X_WINDOW (f) != 0)
3440 error ("Cannot change the border width of a window");
3441#endif /* MAC_TODO */
3442
5af5757b 3443 f->border_width = XINT (arg);
972f4259
KS
3444}
3445
3446void
3447x_set_internal_border_width (f, arg, oldval)
3448 struct frame *f;
3449 Lisp_Object arg, oldval;
3450{
5af5757b 3451 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
972f4259
KS
3452
3453 CHECK_NUMBER (arg);
5af5757b
KS
3454 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3455 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3456 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
972f4259
KS
3457
3458#ifdef USE_X_TOOLKIT
3459 if (FRAME_X_OUTPUT (f)->edit_widget)
3460 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3461#endif
3462
5af5757b 3463 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
972f4259
KS
3464 return;
3465
3466 if (FRAME_X_WINDOW (f) != 0)
3467 {
5af5757b 3468 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3469 SET_FRAME_GARBAGED (f);
3470 do_pending_window_change (0);
3471 }
3472 else
3473 SET_FRAME_GARBAGED (f);
3474}
3475
3476void
3477x_set_visibility (f, value, oldval)
3478 struct frame *f;
3479 Lisp_Object value, oldval;
3480{
3481 Lisp_Object frame;
3482 XSETFRAME (frame, f);
3483
3484 if (NILP (value))
3485 Fmake_frame_invisible (frame, Qt);
3486 else if (EQ (value, Qicon))
3487 Ficonify_frame (frame);
3488 else
3489 Fmake_frame_visible (frame);
3490}
3491
3492void
3493x_set_autoraise (f, arg, oldval)
3494 struct frame *f;
3495 Lisp_Object arg, oldval;
3496{
3497 f->auto_raise = !EQ (Qnil, arg);
3498}
3499
3500void
3501x_set_autolower (f, arg, oldval)
3502 struct frame *f;
3503 Lisp_Object arg, oldval;
3504{
3505 f->auto_lower = !EQ (Qnil, arg);
3506}
3507
3508void
3509x_set_unsplittable (f, arg, oldval)
3510 struct frame *f;
3511 Lisp_Object arg, oldval;
3512{
3513 f->no_split = !NILP (arg);
3514}
3515
3516void
3517x_set_vertical_scroll_bars (f, arg, oldval)
3518 struct frame *f;
3519 Lisp_Object arg, oldval;
3520{
3521 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3522 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3523 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3524 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3525 {
3526 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3527 = (NILP (arg)
3528 ? vertical_scroll_bar_none
3529 : EQ (Qleft, arg)
3530 ? vertical_scroll_bar_left
3531 : EQ (Qright, arg)
3532 ? vertical_scroll_bar_right
a6e20602
KS
3533 : EQ (Qleft, Vdefault_frame_scroll_bars)
3534 ? vertical_scroll_bar_left
3535 : EQ (Qright, Vdefault_frame_scroll_bars)
3536 ? vertical_scroll_bar_right
3537 : vertical_scroll_bar_none);
972f4259
KS
3538
3539 /* We set this parameter before creating the X window for the
3540 frame, so we can get the geometry right from the start.
3541 However, if the window hasn't been created yet, we shouldn't
3542 call x_set_window_size. */
3543 if (FRAME_X_WINDOW (f))
5af5757b 3544 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3545 do_pending_window_change (0);
3546 }
3547}
3548
3549void
3550x_set_scroll_bar_width (f, arg, oldval)
3551 struct frame *f;
3552 Lisp_Object arg, oldval;
3553{
5af5757b 3554 int wid = FRAME_COLUMN_WIDTH (f);
972f4259
KS
3555
3556 if (NILP (arg))
3557 {
3558 x_set_scroll_bar_default_width (f);
3559
3560 if (FRAME_X_WINDOW (f))
5af5757b 3561 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3562 do_pending_window_change (0);
3563 }
3564 else if (INTEGERP (arg) && XINT (arg) > 0
5af5757b 3565 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
972f4259
KS
3566 {
3567 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3568 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3569
5af5757b
KS
3570 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3571 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
972f4259 3572 if (FRAME_X_WINDOW (f))
5af5757b 3573 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3574 do_pending_window_change (0);
3575 }
3576
5af5757b 3577 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
972f4259
KS
3578 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3579 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3580}
3581
3582
3583
3584/* Return non-nil if frame F wants a bitmap icon. */
3585
3586Lisp_Object
3587x_icon_type (f)
3588 FRAME_PTR f;
3589{
3590 Lisp_Object tem;
3591
3592 tem = assq_no_quit (Qicon_type, f->param_alist);
3593 if (CONSP (tem))
3594 return XCDR (tem);
3595 else
3596 return Qnil;
3597}
3598
3599\f
3600/* Subroutines of creating an X frame. */
3601
3602/* Make sure that Vx_resource_name is set to a reasonable value.
3603 Fix it up, or set it to `emacs' if it is too hopeless. */
3604
3605void
3606validate_x_resource_name ()
3607{
3608 int len = 0;
3609 /* Number of valid characters in the resource name. */
3610 int good_count = 0;
3611 /* Number of invalid characters in the resource name. */
3612 int bad_count = 0;
3613 Lisp_Object new;
3614 int i;
3615
3616 if (!STRINGP (Vx_resource_class))
3617 Vx_resource_class = build_string (EMACS_CLASS);
3618
3619 if (STRINGP (Vx_resource_name))
3620 {
3621 unsigned char *p = SDATA (Vx_resource_name);
3622 int i;
3623
3624 len = SBYTES (Vx_resource_name);
3625
3626 /* Only letters, digits, - and _ are valid in resource names.
3627 Count the valid characters and count the invalid ones. */
3628 for (i = 0; i < len; i++)
3629 {
3630 int c = p[i];
3631 if (! ((c >= 'a' && c <= 'z')
3632 || (c >= 'A' && c <= 'Z')
3633 || (c >= '0' && c <= '9')
3634 || c == '-' || c == '_'))
3635 bad_count++;
3636 else
3637 good_count++;
3638 }
3639 }
3640 else
3641 /* Not a string => completely invalid. */
3642 bad_count = 5, good_count = 0;
3643
3644 /* If name is valid already, return. */
3645 if (bad_count == 0)
3646 return;
3647
3648 /* If name is entirely invalid, or nearly so, use `emacs'. */
3649 if (good_count == 0
3650 || (good_count == 1 && bad_count > 0))
3651 {
3652 Vx_resource_name = build_string ("emacs");
3653 return;
3654 }
3655
3656 /* Name is partly valid. Copy it and replace the invalid characters
3657 with underscores. */
3658
3659 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3660
3661 for (i = 0; i < len; i++)
3662 {
3663 int c = SREF (new, i);
3664 if (! ((c >= 'a' && c <= 'z')
3665 || (c >= 'A' && c <= 'Z')
3666 || (c >= '0' && c <= '9')
3667 || c == '-' || c == '_'))
3668 SSET (new, i, '_');
3669 }
3670}
3671
3672
3673extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3674extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3675
3676
b5251fe7 3677/* Get specified attribute from resource database RDB.
972f4259
KS
3678 See Fx_get_resource below for other parameters. */
3679
3680static Lisp_Object
3681xrdb_get_resource (rdb, attribute, class, component, subclass)
3682 XrmDatabase rdb;
3683 Lisp_Object attribute, class, component, subclass;
3684{
3685 register char *value;
3686 char *name_key;
3687 char *class_key;
3688
3689 CHECK_STRING (attribute);
3690 CHECK_STRING (class);
3691
3692 if (!NILP (component))
3693 CHECK_STRING (component);
3694 if (!NILP (subclass))
3695 CHECK_STRING (subclass);
3696 if (NILP (component) != NILP (subclass))
3697 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3698
3699 validate_x_resource_name ();
3700
3701 /* Allocate space for the components, the dots which separate them,
3702 and the final '\0'. Make them big enough for the worst case. */
3703 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3704 + (STRINGP (component)
3705 ? SBYTES (component) : 0)
3706 + SBYTES (attribute)
3707 + 3);
3708
3709 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3710 + SBYTES (class)
3711 + (STRINGP (subclass)
3712 ? SBYTES (subclass) : 0)
3713 + 3);
3714
3715 /* Start with emacs.FRAMENAME for the name (the specific one)
3716 and with `Emacs' for the class key (the general one). */
3717 strcpy (name_key, SDATA (Vx_resource_name));
3718 strcpy (class_key, SDATA (Vx_resource_class));
3719
3720 strcat (class_key, ".");
3721 strcat (class_key, SDATA (class));
3722
3723 if (!NILP (component))
3724 {
3725 strcat (class_key, ".");
3726 strcat (class_key, SDATA (subclass));
3727
3728 strcat (name_key, ".");
3729 strcat (name_key, SDATA (component));
3730 }
3731
3732 strcat (name_key, ".");
3733 strcat (name_key, SDATA (attribute));
3734
3735 value = x_get_string_resource (rdb, name_key, class_key);
3736
3737 if (value != (char *) 0)
3738 return build_string (value);
3739 else
3740 return Qnil;
3741}
3742
3743
3744DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3745 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3746This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3747class, where INSTANCE is the name under which Emacs was invoked, or
3748the name specified by the `-name' or `-rn' command-line arguments.
3749
3750The optional arguments COMPONENT and SUBCLASS add to the key and the
3751class, respectively. You must specify both of them or neither.
3752If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3753and the class is `Emacs.CLASS.SUBCLASS'. */)
3754 (attribute, class, component, subclass)
3755 Lisp_Object attribute, class, component, subclass;
3756{
3757#ifdef HAVE_X_WINDOWS
3758 check_x ();
3759#endif
3760
3761 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3762 attribute, class, component, subclass);
3763}
3764
3765/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3766
3767Lisp_Object
3768display_x_get_resource (dpyinfo, attribute, class, component, subclass)
a1702920 3769 Display_Info *dpyinfo;
972f4259
KS
3770 Lisp_Object attribute, class, component, subclass;
3771{
3772 return xrdb_get_resource (dpyinfo->xrdb,
3773 attribute, class, component, subclass);
3774}
3775
3776/* Used when C code wants a resource value. */
3777
3778char *
3779x_get_resource_string (attribute, class)
3780 char *attribute, *class;
3781{
3782 char *name_key;
3783 char *class_key;
3784 struct frame *sf = SELECTED_FRAME ();
3785
3786 /* Allocate space for the components, the dots which separate them,
3787 and the final '\0'. */
3788 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3789 + strlen (attribute) + 2);
3790 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3791 + strlen (class) + 2);
3792
3793 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3794 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3795
3796 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3797 name_key, class_key);
3798}
3799
3800
3801/* Return the value of parameter PARAM.
3802
3803 First search ALIST, then Vdefault_frame_alist, then the X defaults
3804 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3805
3806 Convert the resource to the type specified by desired_type.
3807
3808 If no default is specified, return Qunbound. If you call
3809 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3810 and don't let it get stored in any Lisp-visible variables! */
3811
3812Lisp_Object
3813x_get_arg (dpyinfo, alist, param, attribute, class, type)
b5251fe7 3814 Display_Info *dpyinfo;
972f4259
KS
3815 Lisp_Object alist, param;
3816 char *attribute;
3817 char *class;
3818 enum resource_types type;
3819{
3820 register Lisp_Object tem;
3821
3822 tem = Fassq (param, alist);
3823 if (EQ (tem, Qnil))
3824 tem = Fassq (param, Vdefault_frame_alist);
3825 if (EQ (tem, Qnil))
3826 {
3827 if (attribute)
3828 {
3829 tem = display_x_get_resource (dpyinfo,
3830 build_string (attribute),
3831 build_string (class),
3832 Qnil, Qnil);
3833
3834 if (NILP (tem))
3835 return Qunbound;
3836
3837 switch (type)
3838 {
3839 case RES_TYPE_NUMBER:
3840 return make_number (atoi (SDATA (tem)));
3841
3842 case RES_TYPE_FLOAT:
3843 return make_float (atof (SDATA (tem)));
3844
3845 case RES_TYPE_BOOLEAN:
3846 tem = Fdowncase (tem);
3847 if (!strcmp (SDATA (tem), "on")
3848 || !strcmp (SDATA (tem), "true"))
3849 return Qt;
3850 else
3851 return Qnil;
3852
3853 case RES_TYPE_STRING:
3854 return tem;
3855
3856 case RES_TYPE_SYMBOL:
3857 /* As a special case, we map the values `true' and `on'
3858 to Qt, and `false' and `off' to Qnil. */
3859 {
3860 Lisp_Object lower;
3861 lower = Fdowncase (tem);
3862 if (!strcmp (SDATA (lower), "on")
3863 || !strcmp (SDATA (lower), "true"))
3864 return Qt;
3865 else if (!strcmp (SDATA (lower), "off")
3866 || !strcmp (SDATA (lower), "false"))
3867 return Qnil;
3868 else
3869 return Fintern (tem, Qnil);
3870 }
3871
3872 default:
3873 abort ();
3874 }
3875 }
3876 else
3877 return Qunbound;
3878 }
3879 return Fcdr (tem);
3880}
3881
3882Lisp_Object
3883x_frame_get_arg (f, alist, param, attribute, class, type)
3884 struct frame *f;
3885 Lisp_Object alist, param;
3886 char *attribute;
3887 char *class;
3888 enum resource_types type;
3889{
3890 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3891 alist, param, attribute, class, type);
3892}
3893
3894/* Like x_frame_get_arg, but also record the value in f->param_alist. */
3895
3896Lisp_Object
3897x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
3898 struct frame *f;
3899 Lisp_Object alist, param;
3900 char *attribute;
3901 char *class;
3902 enum resource_types type;
3903{
3904 Lisp_Object value;
3905
3906 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3907 attribute, class, type);
3908 if (! NILP (value))
3909 store_frame_param (f, param, value);
3910
3911 return value;
3912}
3913
3914
3915/* Record in frame F the specified or default value according to ALIST
3916 of the parameter named PROP (a Lisp symbol).
3917 If no value is specified for PROP, look for an X default for XPROP
3918 on the frame named NAME.
3919 If that is not found either, use the value DEFLT. */
3920
3921Lisp_Object
3922x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
3923 struct frame *f;
3924 Lisp_Object alist;
3925 Lisp_Object prop;
3926 Lisp_Object deflt;
3927 char *xprop;
3928 char *xclass;
3929 enum resource_types type;
3930{
3931 Lisp_Object tem;
3932
3933 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3934 if (EQ (tem, Qunbound))
3935 tem = deflt;
3936 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
3937 return tem;
3938}
3939
3940
3941
3942\f
3943DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
3944 doc: /* Parse an X-style geometry string STRING.
3945Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3946The properties returned may include `top', `left', `height', and `width'.
3947The value of `left' or `top' may be an integer,
3948or a list (+ N) meaning N pixels relative to top/left corner,
3949or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3950 (string)
3951 Lisp_Object string;
3952{
3953 int geometry, x, y;
3954 unsigned int width, height;
3955 Lisp_Object result;
3956
3957 CHECK_STRING (string);
3958
3959 geometry = XParseGeometry ((char *) SDATA (string),
3960 &x, &y, &width, &height);
3961
3962#if 0
3963 if (!!(geometry & XValue) != !!(geometry & YValue))
3964 error ("Must specify both x and y position, or neither");
3965#endif
3966
3967 result = Qnil;
3968 if (geometry & XValue)
3969 {
3970 Lisp_Object element;
3971
3972 if (x >= 0 && (geometry & XNegative))
3973 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
3974 else if (x < 0 && ! (geometry & XNegative))
3975 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
3976 else
3977 element = Fcons (Qleft, make_number (x));
3978 result = Fcons (element, result);
3979 }
3980
3981 if (geometry & YValue)
3982 {
3983 Lisp_Object element;
3984
3985 if (y >= 0 && (geometry & YNegative))
3986 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
3987 else if (y < 0 && ! (geometry & YNegative))
3988 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
3989 else
3990 element = Fcons (Qtop, make_number (y));
3991 result = Fcons (element, result);
3992 }
3993
3994 if (geometry & WidthValue)
3995 result = Fcons (Fcons (Qwidth, make_number (width)), result);
3996 if (geometry & HeightValue)
3997 result = Fcons (Fcons (Qheight, make_number (height)), result);
3998
3999 return result;
4000}
4001
4002/* Calculate the desired size and position of frame F.
4003 Return the flags saying which aspects were specified.
4004
4005 Also set the win_gravity and size_hint_flags of F.
4006
4007 Adjust height for toolbar if TOOLBAR_P is 1.
4008
4009 This function does not make the coordinates positive. */
4010
4011#define DEFAULT_ROWS 40
4012#define DEFAULT_COLS 80
4013
4014int
4015x_figure_window_size (f, parms, toolbar_p)
4016 struct frame *f;
4017 Lisp_Object parms;
4018 int toolbar_p;
4019{
4020 register Lisp_Object tem0, tem1, tem2;
4021 long window_prompting = 0;
4022 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4023
4024 /* Default values if we fall through.
4025 Actually, if that happens we should get
4026 window manager prompting. */
5af5757b
KS
4027 SET_FRAME_COLS (f, DEFAULT_COLS);
4028 FRAME_LINES (f) = DEFAULT_ROWS;
972f4259
KS
4029 /* Window managers expect that if program-specified
4030 positions are not (0,0), they're intentional, not defaults. */
5af5757b
KS
4031 f->top_pos = 0;
4032 f->left_pos = 0;
972f4259 4033
5af5757b 4034 /* Ensure that old new_text_cols and new_text_lines will not override the
972f4259
KS
4035 values set here. */
4036 /* ++KFS: This was specific to W32, but seems ok for all platforms */
5af5757b 4037 f->new_text_cols = f->new_text_lines = 0;
972f4259
KS
4038
4039 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4040 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4041 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4042 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4043 {
4044 if (!EQ (tem0, Qunbound))
4045 {
4046 CHECK_NUMBER (tem0);
5af5757b 4047 FRAME_LINES (f) = XINT (tem0);
972f4259
KS
4048 }
4049 if (!EQ (tem1, Qunbound))
4050 {
4051 CHECK_NUMBER (tem1);
5af5757b 4052 SET_FRAME_COLS (f, XINT (tem1));
972f4259
KS
4053 }
4054 if (!NILP (tem2) && !EQ (tem2, Qunbound))
4055 window_prompting |= USSize;
4056 else
4057 window_prompting |= PSize;
4058 }
4059
5af5757b
KS
4060 f->scroll_bar_actual_width
4061 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
972f4259
KS
4062
4063 /* This used to be done _before_ calling x_figure_window_size, but
4064 since the height is reset here, this was really a no-op. I
4065 assume that moving it here does what Gerd intended (although he
4066 no longer can remember what that was... ++KFS, 2003-03-25. */
4067
4068 /* Add the tool-bar height to the initial frame height so that the
4069 user gets a text display area of the size he specified with -g or
4070 via .Xdefaults. Later changes of the tool-bar height don't
4071 change the frame size. This is done so that users can create
4072 tall Emacs frames without having to guess how tall the tool-bar
4073 will get. */
4074 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4075 {
4076 int margin, relief, bar_height;
4077
4078 relief = (tool_bar_button_relief >= 0
4079 ? tool_bar_button_relief
4080 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4081
4082 if (INTEGERP (Vtool_bar_button_margin)
4083 && XINT (Vtool_bar_button_margin) > 0)
4084 margin = XFASTINT (Vtool_bar_button_margin);
4085 else if (CONSP (Vtool_bar_button_margin)
4086 && INTEGERP (XCDR (Vtool_bar_button_margin))
4087 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
4088 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4089 else
4090 margin = 0;
4091
4092 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
5af5757b 4093 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
972f4259
KS
4094 }
4095
4096 compute_fringe_widths (f, 0);
4097
5af5757b
KS
4098 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
4099 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
972f4259
KS
4100
4101 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4102 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4103 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4104 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4105 {
4106 if (EQ (tem0, Qminus))
4107 {
5af5757b 4108 f->top_pos = 0;
972f4259
KS
4109 window_prompting |= YNegative;
4110 }
4111 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
4112 && CONSP (XCDR (tem0))
4113 && INTEGERP (XCAR (XCDR (tem0))))
4114 {
5af5757b 4115 f->top_pos = - XINT (XCAR (XCDR (tem0)));
972f4259
KS
4116 window_prompting |= YNegative;
4117 }
4118 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
4119 && CONSP (XCDR (tem0))
4120 && INTEGERP (XCAR (XCDR (tem0))))
4121 {
5af5757b 4122 f->top_pos = XINT (XCAR (XCDR (tem0)));
972f4259
KS
4123 }
4124 else if (EQ (tem0, Qunbound))
5af5757b 4125 f->top_pos = 0;
972f4259
KS
4126 else
4127 {
4128 CHECK_NUMBER (tem0);
5af5757b
KS
4129 f->top_pos = XINT (tem0);
4130 if (f->top_pos < 0)
972f4259
KS
4131 window_prompting |= YNegative;
4132 }
4133
4134 if (EQ (tem1, Qminus))
4135 {
5af5757b 4136 f->left_pos = 0;
972f4259
KS
4137 window_prompting |= XNegative;
4138 }
4139 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
4140 && CONSP (XCDR (tem1))
4141 && INTEGERP (XCAR (XCDR (tem1))))
4142 {
5af5757b 4143 f->left_pos = - XINT (XCAR (XCDR (tem1)));
972f4259
KS
4144 window_prompting |= XNegative;
4145 }
4146 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
4147 && CONSP (XCDR (tem1))
4148 && INTEGERP (XCAR (XCDR (tem1))))
4149 {
5af5757b 4150 f->left_pos = XINT (XCAR (XCDR (tem1)));
972f4259
KS
4151 }
4152 else if (EQ (tem1, Qunbound))
5af5757b 4153 f->left_pos = 0;
972f4259
KS
4154 else
4155 {
4156 CHECK_NUMBER (tem1);
5af5757b
KS
4157 f->left_pos = XINT (tem1);
4158 if (f->left_pos < 0)
972f4259
KS
4159 window_prompting |= XNegative;
4160 }
4161
4162 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
4163 window_prompting |= USPosition;
4164 else
4165 window_prompting |= PPosition;
4166 }
4167
5af5757b 4168 if (f->want_fullscreen != FULLSCREEN_NONE)
972f4259
KS
4169 {
4170 int left, top;
4171 int width, height;
4172
4173 /* It takes both for some WM:s to place it where we want */
4174 window_prompting = USPosition | PPosition;
4175 x_fullscreen_adjust (f, &width, &height, &top, &left);
5af5757b
KS
4176 FRAME_COLS (f) = width;
4177 FRAME_LINES (f) = height;
4178 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
4179 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
4180 f->left_pos = left;
4181 f->top_pos = top;
972f4259
KS
4182 }
4183
4184 if (window_prompting & XNegative)
4185 {
4186 if (window_prompting & YNegative)
5af5757b 4187 f->win_gravity = SouthEastGravity;
972f4259 4188 else
5af5757b 4189 f->win_gravity = NorthEastGravity;
972f4259
KS
4190 }
4191 else
4192 {
4193 if (window_prompting & YNegative)
5af5757b 4194 f->win_gravity = SouthWestGravity;
972f4259 4195 else
5af5757b 4196 f->win_gravity = NorthWestGravity;
972f4259
KS
4197 }
4198
5af5757b 4199 f->size_hint_flags = window_prompting;
972f4259
KS
4200
4201 return window_prompting;
4202}
4203
4204
4205
4206#endif /* HAVE_WINDOW_SYSTEM */
4207
4208
4209\f
4210/***********************************************************************
4211 Initialization
4212 ***********************************************************************/
4213
4214void
4215syms_of_frame ()
4216{
4217 Qframep = intern ("framep");
4218 staticpro (&Qframep);
4219 Qframe_live_p = intern ("frame-live-p");
4220 staticpro (&Qframe_live_p);
4221 Qheight = intern ("height");
4222 staticpro (&Qheight);
4223 Qicon = intern ("icon");
4224 staticpro (&Qicon);
4225 Qminibuffer = intern ("minibuffer");
4226 staticpro (&Qminibuffer);
4227 Qmodeline = intern ("modeline");
4228 staticpro (&Qmodeline);
4229 Qonly = intern ("only");
4230 staticpro (&Qonly);
4231 Qwidth = intern ("width");
4232 staticpro (&Qwidth);
4233 Qgeometry = intern ("geometry");
4234 staticpro (&Qgeometry);
4235 Qicon_left = intern ("icon-left");
4236 staticpro (&Qicon_left);
4237 Qicon_top = intern ("icon-top");
4238 staticpro (&Qicon_top);
4239 Qleft = intern ("left");
4240 staticpro (&Qleft);
4241 Qright = intern ("right");
4242 staticpro (&Qright);
4243 Quser_position = intern ("user-position");
4244 staticpro (&Quser_position);
4245 Quser_size = intern ("user-size");
4246 staticpro (&Quser_size);
4247 Qwindow_id = intern ("window-id");
4248 staticpro (&Qwindow_id);
4249#ifdef HAVE_X_WINDOWS
4250 Qouter_window_id = intern ("outer-window-id");
4251 staticpro (&Qouter_window_id);
4252#endif
4253 Qparent_id = intern ("parent-id");
4254 staticpro (&Qparent_id);
4255 Qx = intern ("x");
4256 staticpro (&Qx);
4257 Qw32 = intern ("w32");
4258 staticpro (&Qw32);
4259 Qpc = intern ("pc");
4260 staticpro (&Qpc);
4261 Qmac = intern ("mac");
4262 staticpro (&Qmac);
4263 Qvisible = intern ("visible");
4264 staticpro (&Qvisible);
4265 Qbuffer_predicate = intern ("buffer-predicate");
4266 staticpro (&Qbuffer_predicate);
4267 Qbuffer_list = intern ("buffer-list");
4268 staticpro (&Qbuffer_list);
a18b8cb5
KL
4269 Qburied_buffer_list = intern ("buried-buffer-list");
4270 staticpro (&Qburied_buffer_list);
972f4259
KS
4271 Qdisplay_type = intern ("display-type");
4272 staticpro (&Qdisplay_type);
4273 Qbackground_mode = intern ("background-mode");
4274 staticpro (&Qbackground_mode);
4275 Qtty_color_mode = intern ("tty-color-mode");
4276 staticpro (&Qtty_color_mode);
28d440ab
KL
4277 Qtty = intern ("tty");
4278 staticpro (&Qtty);
4279 Qtty_type = intern ("tty-type");
4280 staticpro (&Qtty_type);
7f19e125
KL
4281 Qwindow_system = intern ("window-system");
4282 staticpro (&Qwindow_system);
da8e8fc1
KL
4283 Qenvironment = intern ("environment");
4284 staticpro (&Qenvironment);
7f19e125 4285
972f4259
KS
4286 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
4287 staticpro (&Qface_set_after_frame_default);
4288
4289 Qfullwidth = intern ("fullwidth");
4290 staticpro (&Qfullwidth);
4291 Qfullheight = intern ("fullheight");
4292 staticpro (&Qfullheight);
4293 Qfullboth = intern ("fullboth");
4294 staticpro (&Qfullboth);
4295 Qx_resource_name = intern ("x-resource-name");
4296 staticpro (&Qx_resource_name);
4297
4298 Qx_frame_parameter = intern ("x-frame-parameter");
4299 staticpro (&Qx_frame_parameter);
4300
6ed8eeff
KL
4301 Qterminal = intern ("terminal");
4302 staticpro (&Qterminal);
4303 Qterminal_live_p = intern ("terminal-live-p");
4304 staticpro (&Qterminal_live_p);
b6660415 4305
972f4259
KS
4306 {
4307 int i;
4308
4309 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4310 {
4311 Lisp_Object v = intern (frame_parms[i].name);
4312 if (frame_parms[i].variable)
4313 {
4314 *frame_parms[i].variable = v;
4315 staticpro (frame_parms[i].variable);
4316 }
4317 Fput (v, Qx_frame_parameter, make_number (i));
4318 }
4319 }
4320
2731a0ad 4321#ifdef HAVE_WINDOW_SYSTEM
972f4259
KS
4322 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4323 doc: /* The name Emacs uses to look up X resources.
4324`x-get-resource' uses this as the first component of the instance name
4325when requesting resource values.
4326Emacs initially sets `x-resource-name' to the name under which Emacs
4327was invoked, or to the value specified with the `-name' or `-rn'
4328switches, if present.
4329
4330It may be useful to bind this variable locally around a call
4331to `x-get-resource'. See also the variable `x-resource-class'. */);
4332 Vx_resource_name = Qnil;
4333
4334 DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4335 doc: /* The class Emacs uses to look up X resources.
4336`x-get-resource' uses this as the first component of the instance class
4337when requesting resource values.
4338
4339Emacs initially sets `x-resource-class' to "Emacs".
4340
4341Setting this variable permanently is not a reasonable thing to do,
4342but binding this variable locally around a call to `x-get-resource'
4343is a reasonable practice. See also the variable `x-resource-name'. */);
4344 Vx_resource_class = build_string (EMACS_CLASS);
2731a0ad 4345#endif
972f4259
KS
4346
4347 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
4348 doc: /* Alist of default values for frame creation.
4349These may be set in your init file, like this:
5ff00c42 4350 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
972f4259
KS
4351These override values given in window system configuration data,
4352 including X Windows' defaults database.
4353For values specific to the first Emacs frame, see `initial-frame-alist'.
4354For values specific to the separate minibuffer frame, see
4355 `minibuffer-frame-alist'.
4356The `menu-bar-lines' element of the list controls whether new frames
4357 have menu bars; `menu-bar-mode' works by altering this element.
4358Setting this variable does not affect existing frames, only new ones. */);
4359 Vdefault_frame_alist = Qnil;
4360
a6e20602
KS
4361 DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
4362 doc: /* Default position of scroll bars on this window-system. */);
4363#ifdef HAVE_WINDOW_SYSTEM
b15325b2 4364#if defined(HAVE_NTGUI) || defined(MAC_OS)
a6e20602
KS
4365 /* MS-Windows has scroll bars on the right by default. */
4366 Vdefault_frame_scroll_bars = Qright;
4367#else
4368 Vdefault_frame_scroll_bars = Qleft;
4369#endif
4370#else
4371 Vdefault_frame_scroll_bars = Qnil;
4372#endif
4373
972f4259
KS
4374 Qinhibit_default_face_x_resources
4375 = intern ("inhibit-default-face-x-resources");
4376 staticpro (&Qinhibit_default_face_x_resources);
4377
daf01701
KL
4378 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
4379 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4380
972f4259
KS
4381 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
4382 doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */);
4383 Vemacs_iconified = Qnil;
4384
4385 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
4386 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4387`mouse-position' calls this function, passing its usual return value as
4388argument, and returns whatever this function returns.
4389This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4390which need to do mouse handling at the Lisp level. */);
4391 Vmouse_position_function = Qnil;
4392
4393 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
4394 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4395If the value is an integer, highlighting is only shown after moving the
4396mouse, while keyboard input turns off the highlight even when the mouse
4397is over the clickable text. However, the mouse shape still indicates
4398when the mouse is over clickable text. */);
4399 Vmouse_highlight = Qt;
4400
4401 DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
4402 doc: /* Functions to be run before deleting a frame.
4403The functions are run with one arg, the frame to be deleted.
e519a50b
KL
4404See `delete-frame'.
4405
4406Note that functions in this list may be called twice on the same
4407frame. In the second invocation, the frame is already deleted, and
4408the function should do nothing. (You can use `frame-live-p' to check
4409for this.) This wrinkle happens when an earlier function in
4410`delete-frame-functions' (indirectly) calls delete-frame
4411recursively. */);
972f4259
KS
4412 Vdelete_frame_functions = Qnil;
4413
4414 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4415 doc: /* Minibufferless frames use this frame's minibuffer.
4416
4417Emacs cannot create minibufferless frames unless this is set to an
4418appropriate surrogate.
4419
4420Emacs consults this variable only when creating minibufferless
4421frames; once the frame is created, it sticks with its assigned
4422minibuffer, no matter what this variable is set to. This means that
4423this variable doesn't necessarily say anything meaningful about the
4424current set of frames, or where the minibuffer is currently being
4425displayed.
4426
4427This variable is local to the current terminal and cannot be buffer-local. */);
4428
4429 staticpro (&Vframe_list);
4430
4431 defsubr (&Sactive_minibuffer_window);
4432 defsubr (&Sframep);
4433 defsubr (&Sframe_live_p);
428a555e 4434 defsubr (&Swindow_system);
972f4259
KS
4435 defsubr (&Smake_terminal_frame);
4436 defsubr (&Shandle_switch_frame);
972f4259
KS
4437 defsubr (&Sselect_frame);
4438 defsubr (&Sselected_frame);
4439 defsubr (&Swindow_frame);
4440 defsubr (&Sframe_root_window);
4441 defsubr (&Sframe_first_window);
4442 defsubr (&Sframe_selected_window);
4443 defsubr (&Sset_frame_selected_window);
4444 defsubr (&Sframe_list);
4445 defsubr (&Snext_frame);
4446 defsubr (&Sprevious_frame);
4447 defsubr (&Sdelete_frame);
4448 defsubr (&Smouse_position);
4449 defsubr (&Smouse_pixel_position);
4450 defsubr (&Sset_mouse_position);
4451 defsubr (&Sset_mouse_pixel_position);
4452#if 0
4453 defsubr (&Sframe_configuration);
4454 defsubr (&Srestore_frame_configuration);
4455#endif
4456 defsubr (&Smake_frame_visible);
4457 defsubr (&Smake_frame_invisible);
4458 defsubr (&Siconify_frame);
4459 defsubr (&Sframe_visible_p);
4460 defsubr (&Svisible_frame_list);
4461 defsubr (&Sraise_frame);
4462 defsubr (&Slower_frame);
4463 defsubr (&Sredirect_frame_focus);
4464 defsubr (&Sframe_focus);
4465 defsubr (&Sframe_parameters);
4466 defsubr (&Sframe_parameter);
4467 defsubr (&Smodify_frame_parameters);
da8e8fc1 4468 defsubr (&Sframe_with_environment);
972f4259
KS
4469 defsubr (&Sframe_char_height);
4470 defsubr (&Sframe_char_width);
4471 defsubr (&Sframe_pixel_height);
4472 defsubr (&Sframe_pixel_width);
4473 defsubr (&Sset_frame_height);
4474 defsubr (&Sset_frame_width);
4475 defsubr (&Sset_frame_size);
4476 defsubr (&Sset_frame_position);
4477
4478#ifdef HAVE_WINDOW_SYSTEM
4479 defsubr (&Sx_get_resource);
4480 defsubr (&Sx_parse_geometry);
4481#endif
4482
dc6f92b8 4483}
ab5796a9
MB
4484
4485/* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039
4486 (do not change this comment) */