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