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