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