Use STRING_BYTES and SET_STRING_BYTES.
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
fa54c6ae 2 Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation.
dc6f92b8
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
1113d9db 8the Free Software Foundation; either version 2, or (at your option)
dc6f92b8
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
dc6f92b8 20
18160b98 21#include <config.h>
565620a5
RS
22
23#include <stdio.h>
e5317d61
EZ
24#ifdef HAVE_STDLIB_H
25#include <stdlib.h>
26#endif
cc38027b 27#include "lisp.h"
71025e5e
KH
28#include "charset.h"
29#ifdef HAVE_WINDOW_SYSTEM
30#include "fontset.h"
31#endif
cc38027b 32#include "frame.h"
bc1ed486 33#include "termhooks.h"
f769f1b2 34#include "window.h"
87485d6f
MW
35#ifdef MSDOS
36#include "msdos.h"
37#endif
e5d77022 38
fd0c2bd1
JB
39/* Evaluate this expression to rebuild the section of syms_of_frame
40 that initializes and staticpros the symbols declared below. Note
41 that Emacs 18 has a bug that keeps C-x C-e from being able to
42 evaluate this expression.
43
44(progn
45 ;; Accumulate a list of the symbols we want to initialize from the
46 ;; declarations at the top of the file.
47 (goto-char (point-min))
48 (search-forward "/\*&&& symbols declared here &&&*\/\n")
49 (let (symbol-list)
50 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
51 (setq symbol-list
52 (cons (buffer-substring (match-beginning 1) (match-end 1))
53 symbol-list))
54 (forward-line 1))
55 (setq symbol-list (nreverse symbol-list))
56 ;; Delete the section of syms_of_... where we initialize the symbols.
57 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
58 (let ((start (point)))
59 (while (looking-at "^ Q")
60 (forward-line 2))
61 (kill-region start (point)))
62 ;; Write a new symbol initialization section.
63 (while symbol-list
64 (insert (format " %s = intern (\"" (car symbol-list)))
65 (let ((start (point)))
66 (insert (substring (car symbol-list) 1))
67 (subst-char-in-region start (point) ?_ ?-))
68 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
69 (setq symbol-list (cdr symbol-list)))))
70 */
71
72/*&&& symbols declared here &&&*/
73Lisp_Object Qframep;
dbc4e1c1 74Lisp_Object Qframe_live_p;
fd0c2bd1
JB
75Lisp_Object Qheight;
76Lisp_Object Qicon;
bc93c097 77Lisp_Object Qminibuffer;
fd0c2bd1
JB
78Lisp_Object Qmodeline;
79Lisp_Object Qname;
fd0c2bd1
JB
80Lisp_Object Qonly;
81Lisp_Object Qunsplittable;
fa8fdbf9 82Lisp_Object Qmenu_bar_lines;
fd0c2bd1
JB
83Lisp_Object Qwidth;
84Lisp_Object Qx;
fbd6baed 85Lisp_Object Qw32;
bb221971 86Lisp_Object Qpc;
f7af3f7b 87Lisp_Object Qvisible;
329ca574 88Lisp_Object Qbuffer_predicate;
fa54c6ae 89Lisp_Object Qbuffer_list;
61eaa912 90Lisp_Object Qtitle;
dc6f92b8 91
a249de79 92Lisp_Object Vterminal_frame;
a1aaa23f 93Lisp_Object Vdefault_frame_alist;
a249de79
RS
94
95static void
96syms_of_frame_1 ()
97{
98 /*&&& init symbols here &&&*/
99 Qframep = intern ("framep");
100 staticpro (&Qframep);
101 Qframe_live_p = intern ("frame-live-p");
102 staticpro (&Qframe_live_p);
103 Qheight = intern ("height");
104 staticpro (&Qheight);
105 Qicon = intern ("icon");
106 staticpro (&Qicon);
107 Qminibuffer = intern ("minibuffer");
108 staticpro (&Qminibuffer);
109 Qmodeline = intern ("modeline");
110 staticpro (&Qmodeline);
111 Qname = intern ("name");
112 staticpro (&Qname);
113 Qonly = intern ("only");
114 staticpro (&Qonly);
115 Qunsplittable = intern ("unsplittable");
116 staticpro (&Qunsplittable);
117 Qmenu_bar_lines = intern ("menu-bar-lines");
118 staticpro (&Qmenu_bar_lines);
119 Qwidth = intern ("width");
120 staticpro (&Qwidth);
121 Qx = intern ("x");
122 staticpro (&Qx);
fbd6baed
GV
123 Qw32 = intern ("w32");
124 staticpro (&Qw32);
bb221971
RS
125 Qpc = intern ("pc");
126 staticpro (&Qpc);
a249de79
RS
127 Qvisible = intern ("visible");
128 staticpro (&Qvisible);
129 Qbuffer_predicate = intern ("buffer-predicate");
130 staticpro (&Qbuffer_predicate);
fa54c6ae
RS
131 Qbuffer_list = intern ("buffer-list");
132 staticpro (&Qbuffer_list);
61eaa912
RS
133 Qtitle = intern ("title");
134 staticpro (&Qtitle);
e05169e2 135
a1aaa23f
RS
136 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
137 "Alist of default values for frame creation.\n\
138These may be set in your init file, like this:\n\
139 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
140These override values given in window system configuration data,\n\
141 including X Windows' defaults database.\n\
142For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
143For values specific to the separate minibuffer frame, see\n\
144 `minibuffer-frame-alist'.\n\
145The `menu-bar-lines' element of the list controls whether new frames\n\
146 have menu bars; `menu-bar-mode' works by altering this element.");
147 Vdefault_frame_alist = Qnil;
a249de79
RS
148}
149\f
150static void
151set_menu_bar_lines_1 (window, n)
152 Lisp_Object window;
153 int n;
154{
155 struct window *w = XWINDOW (window);
156
57aeea1e 157 XSETFASTINT (w->last_modified, 0);
a249de79
RS
158 XSETFASTINT (w->top, XFASTINT (w->top) + n);
159 XSETFASTINT (w->height, XFASTINT (w->height) - n);
160
161 /* Handle just the top child in a vertical split. */
162 if (!NILP (w->vchild))
163 set_menu_bar_lines_1 (w->vchild, n);
164
165 /* Adjust all children in a horizontal split. */
166 for (window = w->hchild; !NILP (window); window = w->next)
167 {
168 w = XWINDOW (window);
169 set_menu_bar_lines_1 (window, n);
170 }
171}
172
e48f782c 173void
a249de79
RS
174set_menu_bar_lines (f, value, oldval)
175 struct frame *f;
176 Lisp_Object value, oldval;
177{
178 int nlines;
179 int olines = FRAME_MENU_BAR_LINES (f);
180
181 /* Right now, menu bars don't work properly in minibuf-only frames;
182 most of the commands try to apply themselves to the minibuffer
e3678b64 183 frame itself, and get an error because you can't switch buffers
a249de79
RS
184 in or split the minibuffer window. */
185 if (FRAME_MINIBUF_ONLY_P (f))
186 return;
187
188 if (INTEGERP (value))
189 nlines = XINT (value);
190 else
191 nlines = 0;
192
57aeea1e
RS
193 if (nlines != olines)
194 {
195 windows_or_buffers_changed++;
196 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
197 FRAME_MENU_BAR_LINES (f) = nlines;
198 set_menu_bar_lines_1 (f->root_window, nlines - olines);
199 }
a249de79
RS
200}
201\f
a249de79
RS
202#include "buffer.h"
203
204/* These help us bind and responding to switch-frame events. */
205#include "commands.h"
206#include "keyboard.h"
207
208Lisp_Object Vemacs_iconified;
209Lisp_Object Vframe_list;
a249de79 210
dc6f92b8
JB
211extern Lisp_Object Vminibuffer_list;
212extern Lisp_Object get_minibuffer ();
84386599
RS
213extern Lisp_Object Fhandle_switch_frame ();
214extern Lisp_Object Fredirect_frame_focus ();
a54d3a73 215extern Lisp_Object x_get_focus_frame ();
dc6f92b8 216\f
ff11dfa1
JB
217DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
218 "Return non-nil if OBJECT is a frame.\n\
219Value is t for a termcap frame (a character-only terminal),\n\
87485d6f
MW
220`x' for an Emacs frame that is really an X window,\n\
221`pc' for a direct-write MS-DOS frame.\n\
e6b27a8f 222See also `frame-live-p'.")
f9898cc6
JB
223 (object)
224 Lisp_Object object;
dc6f92b8 225{
e35d291d 226 if (!FRAMEP (object))
dc6f92b8 227 return Qnil;
ff11dfa1 228 switch (XFRAME (object)->output_method)
dc6f92b8
JB
229 {
230 case output_termcap:
231 return Qt;
232 case output_x_window:
fd0c2bd1 233 return Qx;
fbd6baed
GV
234 case output_w32:
235 return Qw32;
bb221971
RS
236 case output_msdos_raw:
237 return Qpc;
dc6f92b8
JB
238 default:
239 abort ();
240 }
241}
242
dbc4e1c1 243DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
ff11dfa1
JB
244 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
245Value is nil if OBJECT is not a live frame. If object is a live\n\
246frame, the return value indicates what sort of output device it is\n\
247displayed on. Value is t for a termcap frame (a character-only\n\
248terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
249 (object)
250 Lisp_Object object;
251{
ff11dfa1
JB
252 return ((FRAMEP (object)
253 && FRAME_LIVE_P (XFRAME (object)))
254 ? Fframep (object)
f9898cc6
JB
255 : Qnil);
256}
257
ff11dfa1
JB
258struct frame *
259make_frame (mini_p)
dc6f92b8
JB
260 int mini_p;
261{
ff11dfa1
JB
262 Lisp_Object frame;
263 register struct frame *f;
dc6f92b8
JB
264 register Lisp_Object root_window;
265 register Lisp_Object mini_window;
36af7d69
KH
266 register struct Lisp_Vector *vec;
267 int i;
268
269 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
270 for (i = 0; i < VECSIZE (struct frame); i++)
271 XSETFASTINT (vec->contents[i], 0);
272 vec->size = VECSIZE (struct frame);
273 f = (struct frame *)vec;
274 XSETFRAME (frame, f);
ff11dfa1
JB
275
276 f->cursor_x = 0;
277 f->cursor_y = 0;
278 f->current_glyphs = 0;
279 f->desired_glyphs = 0;
280 f->visible = 0;
323405de 281 f->async_visible = 0;
7556890b 282 f->output_data.nothing = 0;
ff11dfa1 283 f->iconified = 0;
323405de 284 f->async_iconified = 0;
ff11dfa1
JB
285 f->wants_modeline = 1;
286 f->auto_raise = 0;
287 f->auto_lower = 0;
288 f->no_split = 0;
289 f->garbaged = 0;
290 f->has_minibuffer = mini_p;
a42e9724 291 f->focus_frame = Qnil;
804518aa 292 f->explicit_name = 0;
fd2777e0 293 f->can_have_scroll_bars = 0;
3a43d2dd 294 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
ff11dfa1 295 f->param_alist = Qnil;
fd2777e0
JB
296 f->scroll_bars = Qnil;
297 f->condemned_scroll_bars = Qnil;
306cc902 298 f->face_alist = Qnil;
9dd935ee 299 f->menu_bar_items = Qnil;
c8b8e7e3
RS
300 f->menu_bar_vector = Qnil;
301 f->menu_bar_items_used = 0;
329ca574 302 f->buffer_predicate = Qnil;
fa54c6ae 303 f->buffer_list = Qnil;
b4f0ee5d
KH
304#ifdef MULTI_KBOARD
305 f->kboard = initial_kboard;
306#endif
aec6e486 307 f->namebuf = 0;
2b1c9cfb 308 f->title = Qnil;
dc6f92b8 309
cc38027b 310 root_window = make_window ();
dc6f92b8
JB
311 if (mini_p)
312 {
cc38027b 313 mini_window = make_window ();
dc6f92b8
JB
314 XWINDOW (root_window)->next = mini_window;
315 XWINDOW (mini_window)->prev = root_window;
316 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
317 XWINDOW (mini_window)->frame = frame;
318 f->minibuffer_window = mini_window;
dc6f92b8
JB
319 }
320 else
321 {
322 mini_window = Qnil;
323 XWINDOW (root_window)->next = Qnil;
ff11dfa1 324 f->minibuffer_window = Qnil;
dc6f92b8
JB
325 }
326
ff11dfa1 327 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
328
329 /* 10 is arbitrary,
330 just so that there is "something there."
ff11dfa1 331 Correct size will be set up later with change_frame_size. */
dc6f92b8 332
3a43d2dd 333 SET_FRAME_WIDTH (f, 10);
ff11dfa1 334 f->height = 10;
dc6f92b8 335
f4e93c40
KH
336 XSETFASTINT (XWINDOW (root_window)->width, 10);
337 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
dc6f92b8
JB
338
339 if (mini_p)
340 {
f4e93c40
KH
341 XSETFASTINT (XWINDOW (mini_window)->width, 10);
342 XSETFASTINT (XWINDOW (mini_window)->top, 9);
343 XSETFASTINT (XWINDOW (mini_window)->height, 1);
dc6f92b8
JB
344 }
345
ff11dfa1 346 /* Choose a buffer for the frame's root window. */
5bce042c
JB
347 {
348 Lisp_Object buf;
349
350 XWINDOW (root_window)->buffer = Qt;
351 buf = Fcurrent_buffer ();
352 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
353 a space), try to find another one. */
354 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 355 buf = Fother_buffer (buf, Qnil);
5bce042c 356 Fset_window_buffer (root_window, buf);
fa54c6ae
RS
357
358 f->buffer_list = Fcons (buf, Qnil);
5bce042c
JB
359 }
360
dc6f92b8
JB
361 if (mini_p)
362 {
363 XWINDOW (mini_window)->buffer = Qt;
364 Fset_window_buffer (mini_window,
265a9e55 365 (NILP (Vminibuffer_list)
dc6f92b8
JB
366 ? get_minibuffer (0)
367 : Fcar (Vminibuffer_list)));
368 }
369
ff11dfa1
JB
370 f->root_window = root_window;
371 f->selected_window = root_window;
d5e7c279
JB
372 /* Make sure this window seems more recently used than
373 a newly-created, never-selected window. */
f4e93c40 374 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
dc6f92b8 375
71025e5e
KH
376#ifdef HAVE_WINDOW_SYSTEM
377 f->fontset_data = alloc_fontset_data ();
378#endif
379
ff11dfa1 380 return f;
dc6f92b8
JB
381}
382\f
ff11dfa1 383/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
384 MINI_WINDOW is the minibuffer window to use. nil means use the
385 default (the global minibuffer). */
386
ff11dfa1 387struct frame *
b0660239 388make_frame_without_minibuffer (mini_window, kb, display)
dc6f92b8 389 register Lisp_Object mini_window;
662ac59a 390 KBOARD *kb;
b0660239 391 Lisp_Object display;
dc6f92b8 392{
ff11dfa1 393 register struct frame *f;
363b873b 394 struct gcpro gcpro1;
dc6f92b8 395
b0660239
KH
396 if (!NILP (mini_window))
397 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8 398
662ac59a 399#ifdef MULTI_KBOARD
b0660239
KH
400 if (!NILP (mini_window)
401 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
662ac59a
KH
402 error ("frame and minibuffer must be on the same display");
403#endif
404
ff11dfa1
JB
405 /* Make a frame containing just a root window. */
406 f = make_frame (0);
dc6f92b8 407
b0660239
KH
408 if (NILP (mini_window))
409 {
410 /* Use default-minibuffer-frame if possible. */
411 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
412 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
413 {
363b873b
RS
414 Lisp_Object frame_dummy;
415
416 XSETFRAME (frame_dummy, f);
417 GCPRO1 (frame_dummy);
b0660239 418 /* If there's no minibuffer frame to use, create one. */
363b873b
RS
419 kb->Vdefault_minibuffer_frame =
420 call1 (intern ("make-initial-minibuffer-frame"), display);
421 UNGCPRO;
b0660239 422 }
363b873b 423
b0660239
KH
424 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
425 }
a2812a26 426
ff11dfa1 427 f->minibuffer_window = mini_window;
a2812a26
RS
428
429 /* Make the chosen minibuffer window display the proper minibuffer,
430 unless it is already showing a minibuffer. */
431 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
432 Fset_window_buffer (mini_window,
433 (NILP (Vminibuffer_list)
434 ? get_minibuffer (0)
435 : Fcar (Vminibuffer_list)));
ff11dfa1 436 return f;
dc6f92b8
JB
437}
438
ff11dfa1 439/* Make a frame containing only a minibuffer window. */
dc6f92b8 440
ff11dfa1
JB
441struct frame *
442make_minibuffer_frame ()
dc6f92b8 443{
ff11dfa1 444 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 445
ff11dfa1 446 register struct frame *f = make_frame (0);
dc6f92b8 447 register Lisp_Object mini_window;
ff11dfa1 448 register Lisp_Object frame;
dc6f92b8 449
2d80a27a 450 XSETFRAME (frame, f);
dc6f92b8 451
804518aa 452 f->auto_raise = 0;
ff11dfa1
JB
453 f->auto_lower = 0;
454 f->no_split = 1;
455 f->wants_modeline = 0;
456 f->has_minibuffer = 1;
dc6f92b8
JB
457
458 /* Now label the root window as also being the minibuffer.
459 Avoid infinite looping on the window chain by marking next pointer
460 as nil. */
461
ff11dfa1 462 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
463 XWINDOW (mini_window)->mini_p = Qt;
464 XWINDOW (mini_window)->next = Qnil;
804518aa 465 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 466 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
467
468 /* Put the proper buffer in that window. */
469
470 Fset_window_buffer (mini_window,
265a9e55 471 (NILP (Vminibuffer_list)
dc6f92b8
JB
472 ? get_minibuffer (0)
473 : Fcar (Vminibuffer_list)));
ff11dfa1 474 return f;
dc6f92b8
JB
475}
476\f
ff11dfa1 477/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 478
bb1513c9
RS
479static int terminal_frame_count;
480
ff11dfa1
JB
481struct frame *
482make_terminal_frame ()
dc6f92b8 483{
ff11dfa1 484 register struct frame *f;
d063751a 485 Lisp_Object frame;
bb1513c9
RS
486 char name[20];
487
b4f0ee5d
KH
488#ifdef MULTI_KBOARD
489 if (!initial_kboard)
490 {
491 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
492 init_kboard (initial_kboard);
a1b658dd
KH
493 initial_kboard->next_kboard = all_kboards;
494 all_kboards = initial_kboard;
b4f0ee5d
KH
495 }
496#endif
497
bb1513c9
RS
498 /* The first call must initialize Vframe_list. */
499 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
500 Vframe_list = Qnil;
ff11dfa1 501
ff11dfa1 502 f = make_frame (1);
d063751a 503
2d80a27a 504 XSETFRAME (frame, f);
d063751a
RS
505 Vframe_list = Fcons (frame, Vframe_list);
506
bb1513c9 507 terminal_frame_count++;
0303e8da
RS
508 sprintf (name, "F%d", terminal_frame_count);
509 f->name = build_string (name);
bb1513c9 510
bb1513c9
RS
511 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
512 f->async_visible = 1; /* Don't let visible be cleared later. */
bb221971
RS
513#ifdef MSDOS
514 f->output_data.x = &the_only_x_display;
515 f->output_method = output_msdos_raw;
516 init_frame_faces (f);
517#else /* not MSDOS */
7556890b 518 f->output_data.nothing = 1; /* Nonzero means frame isn't deleted. */
bb221971 519#endif
ff11dfa1 520 return f;
dc6f92b8 521}
bb1513c9
RS
522
523DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
4bc7e3ad
RS
524 1, 1, 0, "Create an additional terminal frame.\n\
525You can create multiple frames on a text-only terminal in this way.\n\
526Only the selected terminal frame is actually displayed.\n\
527This function takes one argument, an alist specifying frame parameters.\n\
528In practice, generally you don't need to specify any parameters.\n\
529Note that changing the size of one terminal frame automatically affects all.")
bb1513c9
RS
530 (parms)
531 Lisp_Object parms;
532{
533 struct frame *f;
534 Lisp_Object frame;
535
541580aa 536#ifdef MSDOS
bb221971
RS
537 if (selected_frame->output_method != output_msdos_raw)
538 abort ();
539#else
bb1513c9
RS
540 if (selected_frame->output_method != output_termcap)
541 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
bb221971 542#endif
bb1513c9
RS
543
544 f = make_terminal_frame ();
545 change_frame_size (f, FRAME_HEIGHT (selected_frame),
546 FRAME_WIDTH (selected_frame), 0, 0);
547 remake_frame_glyphs (f);
548 calculate_costs (f);
549 XSETFRAME (frame, f);
8adfc1ec 550 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
bb1513c9 551 Fmodify_frame_parameters (frame, parms);
133c7a8a 552 f->face_alist = selected_frame->face_alist;
bb1513c9
RS
553 return frame;
554}
dc6f92b8 555\f
61f94483 556Lisp_Object
0aed85f4 557do_switch_frame (frame, no_enter, track)
ff11dfa1 558 Lisp_Object frame, no_enter;
0aed85f4 559 int track;
dc6f92b8 560{
2f0b07e0
JB
561 /* If FRAME is a switch-frame event, extract the frame we should
562 switch to. */
563 if (CONSP (frame)
564 && EQ (XCONS (frame)->car, Qswitch_frame)
565 && CONSP (XCONS (frame)->cdr))
566 frame = XCONS (XCONS (frame)->cdr)->car;
567
09907c3a
KH
568 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
569 a switch-frame event to arrive after a frame is no longer live,
570 especially when deleting the initial frame during startup. */
571 CHECK_FRAME (frame, 0);
572 if (! FRAME_LIVE_P (XFRAME (frame)))
573 return Qnil;
dc6f92b8 574
ff11dfa1
JB
575 if (selected_frame == XFRAME (frame))
576 return frame;
dc6f92b8 577
0aed85f4
KH
578 /* This is too greedy; it causes inappropriate focus redirection
579 that's hard to get rid of. */
580#if 0
a42e9724
JB
581 /* If a frame's focus has been redirected toward the currently
582 selected frame, we should change the redirection to point to the
583 newly selected frame. This means that if the focus is redirected
584 from a minibufferless frame to a surrogate minibuffer frame, we
585 can use `other-window' to switch between all the frames using
586 that minibuffer frame, and the focus redirection will follow us
587 around. */
0aed85f4
KH
588 if (track)
589 {
590 Lisp_Object tail;
a42e9724 591
0aed85f4
KH
592 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
593 {
594 Lisp_Object focus;
a42e9724 595
e35d291d 596 if (!FRAMEP (XCONS (tail)->car))
0aed85f4 597 abort ();
a42e9724 598
0aed85f4 599 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
a42e9724 600
e35d291d 601 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
0aed85f4
KH
602 Fredirect_frame_focus (XCONS (tail)->car, frame);
603 }
604 }
605#else /* ! 0 */
606 /* Instead, apply it only to the frame we're pointing to. */
032d78fe
GV
607#ifdef HAVE_WINDOW_SYSTEM
608 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
0aed85f4
KH
609 {
610 Lisp_Object focus, xfocus;
611
d7266360 612 xfocus = x_get_focus_frame (XFRAME (frame));
0aed85f4
KH
613 if (FRAMEP (xfocus))
614 {
615 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
616 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
617 Fredirect_frame_focus (xfocus, frame);
618 }
619 }
620#endif /* HAVE_X_WINDOWS */
621#endif /* ! 0 */
a42e9724 622
ff11dfa1
JB
623 selected_frame = XFRAME (frame);
624 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
625 last_nonminibuf_frame = selected_frame;
d5e7c279 626
ff11dfa1 627 Fselect_window (XFRAME (frame)->selected_window);
dc6f92b8 628
074577b8 629 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 630 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
631 before you take it out, make sure that evaluating something like
632 (select-window (frame-root-window (new-frame))) doesn't end up
633 with your typing being interpreted in the new frame instead of
634 the one you're actually typing in. */
ef352596 635 internal_last_event_frame = Qnil;
074577b8 636
ff11dfa1 637 return frame;
dc6f92b8
JB
638}
639
0aed85f4
KH
640DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
641 "Select the frame FRAME.\n\
642Subsequent editing commands apply to its selected window.\n\
643The selection of FRAME lasts until the next time the user does\n\
644something to select a different frame, or until the next time this\n\
645function is called.")
646 (frame, no_enter)
647 Lisp_Object frame, no_enter;
648{
649 return do_switch_frame (frame, no_enter, 1);
650}
651
652
653DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
654 "Handle a switch-frame event EVENT.\n\
655Switch-frame events are usually bound to this function.\n\
656A switch-frame event tells Emacs that the window manager has requested\n\
657that the user's events be directed to the frame mentioned in the event.\n\
658This function selects the selected window of the frame of EVENT.\n\
659\n\
660If EVENT is frame object, handle it as if it were a switch-frame event\n\
661to that frame.")
735eeca3
EN
662 (event, no_enter)
663 Lisp_Object event, no_enter;
0aed85f4 664{
6951cd71
KH
665 /* Preserve prefix arg that the command loop just cleared. */
666 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
e05169e2 667 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
735eeca3 668 return do_switch_frame (event, no_enter, 0);
0aed85f4
KH
669}
670
1c212787
KH
671DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
672 "Do nothing, but preserve any prefix argument already specified.\n\
673This is a suitable binding for iconify-frame and make-frame-visible.")
674 ()
675{
676 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
677 return Qnil;
678}
0aed85f4 679
ff11dfa1
JB
680DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
681 "Return the frame that is now selected.")
dc6f92b8
JB
682 ()
683{
684 Lisp_Object tem;
2d80a27a 685 XSETFRAME (tem, selected_frame);
dc6f92b8
JB
686 return tem;
687}
4a7cfafc 688\f
ff11dfa1
JB
689DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
690 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
691 (window)
692 Lisp_Object window;
693{
774910eb 694 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 695 return XWINDOW (window)->frame;
dc6f92b8
JB
696}
697
ba32f2db
KH
698DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
699 "Returns the topmost, leftmost window of FRAME.\n\
700If omitted, FRAME defaults to the currently selected frame.")
701 (frame)
702 Lisp_Object frame;
703{
704 Lisp_Object w;
705
706 if (NILP (frame))
707 w = selected_frame->root_window;
708 else
709 {
710 CHECK_LIVE_FRAME (frame, 0);
711 w = XFRAME (frame)->root_window;
712 }
713 while (NILP (XWINDOW (w)->buffer))
714 {
715 if (! NILP (XWINDOW (w)->hchild))
716 w = XWINDOW (w)->hchild;
717 else if (! NILP (XWINDOW (w)->vchild))
718 w = XWINDOW (w)->vchild;
719 else
720 abort ();
721 }
722 return w;
723}
724
5add3885
RS
725DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
726 Sactive_minibuffer_window, 0, 0, 0,
727 "Return the currently active minibuffer window, or nil if none.")
728 ()
729{
730 return minibuf_level ? minibuf_window : Qnil;
731}
732
ff11dfa1 733DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
734 "Returns the root-window of FRAME.\n\
735If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
736 (frame)
737 Lisp_Object frame;
dc6f92b8 738{
ff11dfa1 739 if (NILP (frame))
2d80a27a 740 XSETFRAME (frame, selected_frame);
f9898cc6 741 else
ff11dfa1 742 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 743
ff11dfa1 744 return XFRAME (frame)->root_window;
dc6f92b8
JB
745}
746
ff11dfa1
JB
747DEFUN ("frame-selected-window", Fframe_selected_window,
748 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
749 "Return the selected window of frame object FRAME.\n\
750If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
751 (frame)
752 Lisp_Object frame;
dc6f92b8 753{
ff11dfa1 754 if (NILP (frame))
2d80a27a 755 XSETFRAME (frame, selected_frame);
f9898cc6 756 else
ff11dfa1 757 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 758
ff11dfa1 759 return XFRAME (frame)->selected_window;
dc6f92b8
JB
760}
761
4a7cfafc
RS
762DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
763 Sset_frame_selected_window, 2, 2, 0,
764 "Set the selected window of frame object FRAME to WINDOW.\n\
765If FRAME is nil, the selected frame is used.\n\
766If FRAME is the selected frame, this makes WINDOW the selected window.")
767 (frame, window)
768 Lisp_Object frame, window;
769{
770 if (NILP (frame))
2d80a27a 771 XSETFRAME (frame, selected_frame);
4a7cfafc
RS
772 else
773 CHECK_LIVE_FRAME (frame, 0);
774
775 CHECK_LIVE_WINDOW (window, 1);
776
777 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
778 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
779
780 if (XFRAME (frame) == selected_frame)
781 return Fselect_window (window);
782
783 return XFRAME (frame)->selected_window = window;
784}
785\f
ff11dfa1 786DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 787 0, 0, 0,
ff11dfa1 788 "Return a list of all frames.")
dc6f92b8
JB
789 ()
790{
ff11dfa1 791 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
792}
793
ff11dfa1 794/* Return the next frame in the frame list after FRAME.
ff11dfa1 795 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
796 If MINIBUF is a window, include only its own frame
797 and any frame now using that window as the minibuffer.
f7af3f7b 798 If MINIBUF is `visible', include all visible frames.
a9986780 799 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
800 Otherwise, include all frames. */
801
dc6f92b8 802Lisp_Object
ff11dfa1
JB
803next_frame (frame, minibuf)
804 Lisp_Object frame;
f9898cc6 805 Lisp_Object minibuf;
dc6f92b8
JB
806{
807 Lisp_Object tail;
808 int passed = 0;
809
ff11dfa1
JB
810 /* There must always be at least one frame in Vframe_list. */
811 if (! CONSP (Vframe_list))
f9898cc6
JB
812 abort ();
813
dbc4e1c1
JB
814 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
815 forever. Forestall that. */
816 CHECK_LIVE_FRAME (frame, 0);
817
dc6f92b8 818 while (1)
ff11dfa1 819 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 820 {
ab9f008d 821 Lisp_Object f;
d06a8a56 822
ab9f008d 823 f = XCONS (tail)->car;
06537cc8
RS
824
825 if (passed
826 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
d5e7c279 827 {
d06a8a56
JB
828 /* Decide whether this frame is eligible to be returned. */
829
830 /* If we've looped all the way around without finding any
831 eligible frames, return the original frame. */
832 if (EQ (f, frame))
833 return f;
834
835 /* Let minibuf decide if this frame is acceptable. */
836 if (NILP (minibuf))
837 {
838 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
839 return f;
840 }
f7af3f7b
RS
841 else if (EQ (minibuf, Qvisible))
842 {
843 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
844 if (FRAME_VISIBLE_P (XFRAME (f)))
845 return f;
846 }
a9986780
RS
847 else if (XFASTINT (minibuf) == 0)
848 {
849 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
850 if (FRAME_VISIBLE_P (XFRAME (f))
851 || FRAME_ICONIFIED_P (XFRAME (f)))
852 return f;
853 }
f7af3f7b 854 else if (WINDOWP (minibuf))
d06a8a56 855 {
a9986780
RS
856 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
857 /* Check that F either is, or has forwarded its focus to,
858 MINIBUF's frame. */
859 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
860 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
861 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
862 return f;
863 }
864 else
ff11dfa1 865 return f;
d5e7c279 866 }
dc6f92b8 867
d06a8a56 868 if (EQ (frame, f))
dc6f92b8
JB
869 passed++;
870 }
871}
872
ff11dfa1 873/* Return the previous frame in the frame list before FRAME.
ff11dfa1 874 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
875 If MINIBUF is a window, include only its own frame
876 and any frame now using that window as the minibuffer.
f7af3f7b 877 If MINIBUF is `visible', include all visible frames.
a9986780 878 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
879 Otherwise, include all frames. */
880
dc6f92b8 881Lisp_Object
ff11dfa1
JB
882prev_frame (frame, minibuf)
883 Lisp_Object frame;
f9898cc6 884 Lisp_Object minibuf;
dc6f92b8
JB
885{
886 Lisp_Object tail;
887 Lisp_Object prev;
888
ff11dfa1
JB
889 /* There must always be at least one frame in Vframe_list. */
890 if (! CONSP (Vframe_list))
f9898cc6
JB
891 abort ();
892
dc6f92b8 893 prev = Qnil;
d06a8a56 894 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 895 {
ab9f008d 896 Lisp_Object f;
f9898cc6 897
ab9f008d 898 f = XCONS (tail)->car;
e35d291d 899 if (!FRAMEP (f))
d06a8a56 900 abort ();
f9898cc6 901
d06a8a56
JB
902 if (EQ (frame, f) && !NILP (prev))
903 return prev;
f9898cc6 904
06537cc8 905 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
f7af3f7b 906 {
06537cc8
RS
907 /* Decide whether this frame is eligible to be returned,
908 according to minibuf. */
909 if (NILP (minibuf))
910 {
911 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
912 prev = f;
913 }
914 else if (WINDOWP (minibuf))
915 {
916 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
917 /* Check that F either is, or has forwarded its focus to,
918 MINIBUF's frame. */
919 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
920 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
921 FRAME_FOCUS_FRAME (XFRAME (f)))))
922 prev = f;
923 }
924 else if (EQ (minibuf, Qvisible))
925 {
926 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
927 if (FRAME_VISIBLE_P (XFRAME (f)))
928 prev = f;
929 }
930 else if (XFASTINT (minibuf) == 0)
931 {
932 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
933 if (FRAME_VISIBLE_P (XFRAME (f))
934 || FRAME_ICONIFIED_P (XFRAME (f)))
935 prev = f;
936 }
937 else
a9986780
RS
938 prev = f;
939 }
f9898cc6 940 }
d06a8a56
JB
941
942 /* We've scanned the entire list. */
943 if (NILP (prev))
944 /* We went through the whole frame list without finding a single
945 acceptable frame. Return the original frame. */
946 return frame;
947 else
948 /* There were no acceptable frames in the list before FRAME; otherwise,
949 we would have returned directly from the loop. Since PREV is the last
950 acceptable frame in the list, return it. */
951 return prev;
dc6f92b8
JB
952}
953
ef2c57ac 954
ff11dfa1
JB
955DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
956 "Return the next frame in the frame list after FRAME.\n\
06537cc8 957It considers only frames on the same terminal as FRAME.\n\
a42e9724 958By default, skip minibuffer-only frames.\n\
d06a8a56 959If omitted, FRAME defaults to the selected frame.\n\
c08c95c7 960If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 961If MINIFRAME is a window, include only its own frame\n\
a9986780 962and any frame now using that window as the minibuffer.\n\
f7af3f7b 963If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 964If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 965Otherwise, include all frames.")
ff11dfa1 966 (frame, miniframe)
8693ca83 967 Lisp_Object frame, miniframe;
dc6f92b8
JB
968{
969 Lisp_Object tail;
970
ff11dfa1 971 if (NILP (frame))
2d80a27a 972 XSETFRAME (frame, selected_frame);
f9898cc6 973 else
ff11dfa1 974 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 975
ff11dfa1 976 return next_frame (frame, miniframe);
dc6f92b8 977}
dbc4e1c1 978
ef2c57ac
RM
979DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
980 "Return the previous frame in the frame list before FRAME.\n\
06537cc8 981It considers only frames on the same terminal as FRAME.\n\
ef2c57ac
RM
982By default, skip minibuffer-only frames.\n\
983If omitted, FRAME defaults to the selected frame.\n\
984If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 985If MINIFRAME is a window, include only its own frame\n\
a9986780 986and any frame now using that window as the minibuffer.\n\
f7af3f7b 987If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 988If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 989Otherwise, include all frames.")
ef2c57ac
RM
990 (frame, miniframe)
991 Lisp_Object frame, miniframe;
992{
993 Lisp_Object tail;
994
995 if (NILP (frame))
2d80a27a 996 XSETFRAME (frame, selected_frame);
ef2c57ac
RM
997 else
998 CHECK_LIVE_FRAME (frame, 0);
999
1000 return prev_frame (frame, miniframe);
1001}
dc6f92b8 1002\f
808c0f20
RS
1003/* Return 1 if it is ok to delete frame F;
1004 0 if all frames aside from F are invisible.
1005 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 1006
d56b45eb 1007int
808c0f20
RS
1008other_visible_frames (f)
1009 FRAME_PTR f;
1010{
1011 /* We know the selected frame is visible,
1012 so if F is some other frame, it can't be the sole visible one. */
1013 if (f == selected_frame)
c08c95c7
RS
1014 {
1015 Lisp_Object frames;
1016 int count = 0;
1017
1018 for (frames = Vframe_list;
1019 CONSP (frames);
1020 frames = XCONS (frames)->cdr)
1021 {
ab9f008d 1022 Lisp_Object this;
c08c95c7 1023
ab9f008d 1024 this = XCONS (frames)->car;
808c0f20
RS
1025 /* Verify that the frame's window still exists
1026 and we can still talk to it. And note any recent change
1027 in visibility. */
032d78fe
GV
1028#ifdef HAVE_WINDOW_SYSTEM
1029 if (FRAME_WINDOW_P (XFRAME (this)))
5e7b7c5b 1030 {
b0509a40 1031 x_sync (XFRAME (this));
5e7b7c5b
RS
1032 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1033 }
1034#endif
1035
c08c95c7
RS
1036 if (FRAME_VISIBLE_P (XFRAME (this))
1037 || FRAME_ICONIFIED_P (XFRAME (this))
1038 /* Allow deleting the terminal frame when at least
1039 one X frame exists! */
032d78fe 1040 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
c08c95c7
RS
1041 count++;
1042 }
808c0f20 1043 return count > 1;
c08c95c7 1044 }
808c0f20
RS
1045 return 1;
1046}
1047
1048DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1049 "Delete FRAME, permanently eliminating it from use.\n\
1050If omitted, FRAME defaults to the selected frame.\n\
1051A frame may not be deleted if its minibuffer is used by other frames.\n\
1052Normally, you may not delete a frame if all other frames are invisible,\n\
1053but if the second optional argument FORCE is non-nil, you may do so.")
1054 (frame, force)
1055 Lisp_Object frame, force;
1056{
1057 struct frame *f;
99b92e64 1058 int minibuffer_selected;
808c0f20
RS
1059
1060 if (EQ (frame, Qnil))
1061 {
1062 f = selected_frame;
2d80a27a 1063 XSETFRAME (frame, f);
808c0f20
RS
1064 }
1065 else
1066 {
1067 CHECK_FRAME (frame, 0);
1068 f = XFRAME (frame);
1069 }
1070
1071 if (! FRAME_LIVE_P (f))
1072 return Qnil;
1073
1074 if (NILP (force) && !other_visible_frames (f))
1075 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 1076
00c5fd51
RS
1077#if 0
1078 /* This is a nice idea, but x_connection_closed needs to be able
1079 to delete the last frame, if it is gone. */
e9687ee8
RS
1080 if (NILP (XCONS (Vframe_list)->cdr))
1081 error ("Attempt to delete the only frame");
00c5fd51 1082#endif
e9687ee8 1083
ff11dfa1
JB
1084 /* Does this frame have a minibuffer, and is it the surrogate
1085 minibuffer for any other frame? */
fd0c2bd1 1086 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 1087 {
ff11dfa1 1088 Lisp_Object frames;
1113d9db 1089
ff11dfa1
JB
1090 for (frames = Vframe_list;
1091 CONSP (frames);
1092 frames = XCONS (frames)->cdr)
1113d9db 1093 {
7a8cc307
RS
1094 Lisp_Object this;
1095 this = XCONS (frames)->car;
1113d9db 1096
ff11dfa1
JB
1097 if (! EQ (this, frame)
1098 && EQ (frame,
7a8cc307
RS
1099 WINDOW_FRAME (XWINDOW
1100 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 1101 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 1102 }
dc6f92b8
JB
1103 }
1104
99b92e64
RS
1105 minibuffer_selected = EQ (minibuf_window, selected_window);
1106
ff11dfa1
JB
1107 /* Don't let the frame remain selected. */
1108 if (f == selected_frame)
06537cc8
RS
1109 {
1110 Lisp_Object tail, frame1;
1111
1112 /* Look for another visible frame on the same terminal. */
1113 frame1 = next_frame (frame, Qvisible);
1114
1115 /* If there is none, find *some* other frame. */
1116 if (NILP (frame1) || EQ (frame1, frame))
1117 {
1118 FOR_EACH_FRAME (tail, frame1)
1119 {
1120 if (! EQ (frame, frame1))
1121 break;
1122 }
1123 }
1124
1125 do_switch_frame (frame1, Qnil, 0);
1126 }
dc6f92b8 1127
ff11dfa1
JB
1128 /* Don't allow minibuf_window to remain on a deleted frame. */
1129 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 1130 {
ff11dfa1 1131 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1132 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1133 minibuf_window = selected_frame->minibuffer_window;
99b92e64
RS
1134
1135 /* If the dying minibuffer window was selected,
1136 select the new one. */
1137 if (minibuffer_selected)
1138 Fselect_window (minibuf_window);
dc6f92b8
JB
1139 }
1140
bb2a0a65
RS
1141 /* Clear any X selections for this frame. */
1142#ifdef HAVE_X_WINDOWS
1143 if (FRAME_X_P (f))
1144 x_clear_frame_selections (f);
1145#endif
1146
4a88b3b0
JB
1147 /* Mark all the windows that used to be on FRAME as deleted, and then
1148 remove the reference to them. */
1149 delete_all_subwindows (XWINDOW (f->root_window));
1150 f->root_window = Qnil;
1151
ff11dfa1 1152 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 1153 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 1154
1fe3648d
RS
1155 if (echo_area_glyphs == FRAME_MESSAGE_BUF (f))
1156 {
1157 echo_area_glyphs = 0;
1158 previous_echo_glyphs = 0;
1159 }
1160
60a8823e
KH
1161 if (f->namebuf)
1162 free (f->namebuf);
d2bee99e
RS
1163 if (FRAME_CURRENT_GLYPHS (f))
1164 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
1165 if (FRAME_DESIRED_GLYPHS (f))
1166 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
1167 if (FRAME_TEMP_GLYPHS (f))
1168 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
1169 if (FRAME_INSERT_COST (f))
1170 free (FRAME_INSERT_COST (f));
1171 if (FRAME_DELETEN_COST (f))
09d1d7e2 1172 free (FRAME_DELETEN_COST (f));
d2bee99e 1173 if (FRAME_INSERTN_COST (f))
09d1d7e2 1174 free (FRAME_INSERTN_COST (f));
d2bee99e 1175 if (FRAME_DELETE_COST (f))
09d1d7e2 1176 free (FRAME_DELETE_COST (f));
25734faf
RS
1177 if (FRAME_MESSAGE_BUF (f))
1178 free (FRAME_MESSAGE_BUF (f));
d2bee99e 1179
71025e5e
KH
1180#ifdef HAVE_WINDOW_SYSTEM
1181 /* Free all fontset data. */
1182 free_fontset_data (FRAME_FONTSET_DATA (f));
1183#endif
1184
8678b9cc
JB
1185 /* Since some events are handled at the interrupt level, we may get
1186 an event for f at any time; if we zero out the frame's display
1187 now, then we may trip up the event-handling code. Instead, we'll
1188 promise that the display of the frame must be valid until we have
1189 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
1190
1191 /* I think this should be done with a hook. */
032d78fe
GV
1192#ifdef HAVE_WINDOW_SYSTEM
1193 if (FRAME_WINDOW_P (f))
8678b9cc 1194 x_destroy_window (f);
d5e7c279
JB
1195#endif
1196
7556890b 1197 f->output_data.nothing = 0;
8678b9cc 1198
ff11dfa1 1199 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1200 another one. */
ff11dfa1 1201 if (f == last_nonminibuf_frame)
d5e7c279 1202 {
ff11dfa1 1203 Lisp_Object frames;
1113d9db 1204
ff11dfa1 1205 last_nonminibuf_frame = 0;
d5e7c279 1206
ff11dfa1
JB
1207 for (frames = Vframe_list;
1208 CONSP (frames);
1209 frames = XCONS (frames)->cdr)
d5e7c279 1210 {
ff11dfa1
JB
1211 f = XFRAME (XCONS (frames)->car);
1212 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1213 {
ff11dfa1 1214 last_nonminibuf_frame = f;
d5e7c279
JB
1215 break;
1216 }
1217 }
1218 }
dc6f92b8 1219
c4c6d073
KH
1220 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1221 find another one. Prefer minibuffer-only frames, but also notice
1222 frames with other windows. */
c60f3a6a 1223 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1113d9db 1224 {
ff11dfa1 1225 Lisp_Object frames;
1113d9db 1226
ff11dfa1 1227 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1228 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1229 /* Some frame we found on the same kboard, or nil if there are none. */
1230 Lisp_Object frame_on_same_kboard;
1113d9db 1231
32fda9ba 1232 frame_on_same_kboard = Qnil;
ab9f008d 1233 frame_with_minibuf = Qnil;
32fda9ba 1234
ff11dfa1
JB
1235 for (frames = Vframe_list;
1236 CONSP (frames);
1237 frames = XCONS (frames)->cdr)
1113d9db 1238 {
ab9f008d 1239 Lisp_Object this;
c4c6d073 1240 struct frame *f1;
1113d9db 1241
ab9f008d 1242 this = XCONS (frames)->car;
e35d291d 1243 if (!FRAMEP (this))
1113d9db 1244 abort ();
c4c6d073 1245 f1 = XFRAME (this);
1113d9db 1246
c4c6d073
KH
1247 /* Consider only frames on the same kboard
1248 and only those with minibuffers. */
1249 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1250 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1251 {
ff11dfa1 1252 frame_with_minibuf = this;
c4c6d073 1253 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1254 break;
1255 }
32fda9ba
RS
1256
1257 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1258 frame_on_same_kboard = this;
1113d9db
JB
1259 }
1260
32fda9ba
RS
1261 if (!NILP (frame_on_same_kboard))
1262 {
1263 /* We know that there must be some frame with a minibuffer out
1264 there. If this were not true, all of the frames present
1265 would have to be minibufferless, which implies that at some
1266 point their minibuffer frames must have been deleted, but
1267 that is prohibited at the top; you can't delete surrogate
1268 minibuffer frames. */
1269 if (NILP (frame_with_minibuf))
1270 abort ();
1113d9db 1271
32fda9ba
RS
1272 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1273 }
1274 else
1275 /* No frames left on this kboard--say no minibuffer either. */
1276 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1277 }
1278
e681c92a
RS
1279 /* Cause frame titles to update--necessary if we now have just one frame. */
1280 update_mode_lines = 1;
1281
dc6f92b8
JB
1282 return Qnil;
1283}
1284\f
1285/* Return mouse position in character cell units. */
1286
f9898cc6 1287DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 1288 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
1289The position is given in character cells, where (0, 0) is the\n\
1290upper-left corner.\n\
f9898cc6 1291If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 1292to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
1293and nil for X and Y.")
1294 ()
dc6f92b8 1295{
ff11dfa1 1296 FRAME_PTR f;
dbc4e1c1 1297 Lisp_Object lispy_dummy;
fd2777e0 1298 enum scroll_bar_part party_dummy;
dbc4e1c1 1299 Lisp_Object x, y;
5384466a 1300 int col, row;
dbc4e1c1 1301 unsigned long long_dummy;
dc6f92b8 1302
c5074d8c
RS
1303 f = selected_frame;
1304 x = y = Qnil;
1305
f443c170 1306#ifdef HAVE_MOUSE
c5074d8c 1307 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1308 if (mouse_position_hook)
66e827dc 1309 (*mouse_position_hook) (&f, -1,
dbc4e1c1
JB
1310 &lispy_dummy, &party_dummy,
1311 &x, &y,
1312 &long_dummy);
76db7eb4
KH
1313 if (! NILP (x))
1314 {
1315 col = XINT (x);
1316 row = XINT (y);
8126c3b4 1317 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1318 XSETINT (x, col);
1319 XSETINT (y, row);
1320 }
f443c170 1321#endif
2d80a27a 1322 XSETFRAME (lispy_dummy, f);
c5074d8c 1323 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1324}
1325
152e6c70
RS
1326DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1327 Smouse_pixel_position, 0, 0, 0,
1328 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1329The position is given in pixel units, where (0, 0) is the\n\
1330upper-left corner.\n\
1331If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1332to read the mouse position, it returns the selected frame for FRAME\n\
1333and nil for X and Y.")
1334 ()
1335{
1336 FRAME_PTR f;
1337 Lisp_Object lispy_dummy;
1338 enum scroll_bar_part party_dummy;
1339 Lisp_Object x, y;
1340 int col, row;
1341 unsigned long long_dummy;
1342
1343 f = selected_frame;
1344 x = y = Qnil;
1345
0c5c1cf7 1346#ifdef HAVE_MOUSE
152e6c70
RS
1347 /* It's okay for the hook to refrain from storing anything. */
1348 if (mouse_position_hook)
66e827dc 1349 (*mouse_position_hook) (&f, -1,
152e6c70
RS
1350 &lispy_dummy, &party_dummy,
1351 &x, &y,
1352 &long_dummy);
0c5c1cf7 1353#endif
2d80a27a 1354 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1355 return Fcons (lispy_dummy, Fcons (x, y));
1356}
1357
dc6f92b8 1358DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1359 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
efb57f43
RS
1360Note, this is a no-op for an X frame that is not visible.\n\
1361If you have just created a frame, you must wait for it to become visible\n\
1362before calling this function on it, like this.\n\
1363 (while (not (frame-visible-p frame)) (sleep-for .5))")
ff11dfa1
JB
1364 (frame, x, y)
1365 Lisp_Object frame, x, y;
dc6f92b8 1366{
ff11dfa1 1367 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1368 CHECK_NUMBER (x, 2);
1369 CHECK_NUMBER (y, 1);
1370
dbc4e1c1 1371 /* I think this should be done with a hook. */
032d78fe
GV
1372#ifdef HAVE_WINDOW_SYSTEM
1373 if (FRAME_WINDOW_P (XFRAME (frame)))
dc6f92b8 1374 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 1375 x_set_mouse_position (XFRAME (frame), x, y);
bb221971 1376#else
be625e00 1377#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1378 if (FRAME_MSDOS_P (XFRAME (frame)))
1379 {
1380 Fselect_frame (frame, Qnil);
1381 mouse_moveto (XINT (x), XINT (y));
1382 }
1383#endif
dc6f92b8
JB
1384#endif
1385
1386 return Qnil;
1387}
152e6c70
RS
1388
1389DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1390 Sset_mouse_pixel_position, 3, 3, 0,
1391 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
efb57f43
RS
1392Note, this is a no-op for an X frame that is not visible.\n\
1393If you have just created a frame, you must wait for it to become visible\n\
1394before calling this function on it, like this.\n\
1395 (while (not (frame-visible-p frame)) (sleep-for .5))")
152e6c70
RS
1396 (frame, x, y)
1397 Lisp_Object frame, x, y;
1398{
1399 CHECK_LIVE_FRAME (frame, 0);
1400 CHECK_NUMBER (x, 2);
1401 CHECK_NUMBER (y, 1);
1402
1403 /* I think this should be done with a hook. */
032d78fe
GV
1404#ifdef HAVE_WINDOW_SYSTEM
1405 if (FRAME_WINDOW_P (XFRAME (frame)))
152e6c70
RS
1406 /* Warping the mouse will cause enternotify and focus events. */
1407 x_set_mouse_pixel_position (XFRAME (frame), x, y);
bb221971 1408#else
be625e00 1409#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1410 if (FRAME_MSDOS_P (XFRAME (frame)))
1411 {
1412 Fselect_frame (frame, Qnil);
1413 mouse_moveto (XINT (x), XINT (y));
1414 }
1415#endif
152e6c70
RS
1416#endif
1417
1418 return Qnil;
1419}
dc6f92b8 1420\f
ff11dfa1 1421DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1422 0, 1, "",
ff11dfa1 1423 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1424If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1425 (frame)
1426 Lisp_Object frame;
dc6f92b8 1427{
1aa66088 1428 if (NILP (frame))
2d80a27a 1429 XSETFRAME (frame, selected_frame);
1aa66088 1430
ff11dfa1 1431 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1432
dbc4e1c1 1433 /* I think this should be done with a hook. */
032d78fe
GV
1434#ifdef HAVE_WINDOW_SYSTEM
1435 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1436 {
1437 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1438 x_make_frame_visible (XFRAME (frame));
1439 }
fd0c2bd1 1440#endif
dc6f92b8 1441
565620a5
RS
1442 /* Make menu bar update for the Buffers and Frams menus. */
1443 windows_or_buffers_changed++;
1444
ff11dfa1 1445 return frame;
dc6f92b8
JB
1446}
1447
ff11dfa1 1448DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1449 0, 2, "",
8693ca83 1450 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1451If omitted, FRAME defaults to the currently selected frame.\n\
1452Normally you may not make FRAME invisible if all other frames are invisible,\n\
1453but if the second optional argument FORCE is non-nil, you may do so.")
1454 (frame, force)
1455 Lisp_Object frame, force;
dc6f92b8 1456{
1aa66088 1457 if (NILP (frame))
2d80a27a 1458 XSETFRAME (frame, selected_frame);
1aa66088 1459
ff11dfa1 1460 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1461
808c0f20
RS
1462 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1463 error ("Attempt to make invisible the sole visible or iconified frame");
1464
3d378fdf 1465#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1466 /* Don't let the frame remain selected. */
1467 if (XFRAME (frame) == selected_frame)
61f94483 1468 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
3d378fdf 1469#endif
9c394f17
RS
1470
1471 /* Don't allow minibuf_window to remain on a deleted frame. */
1472 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1473 {
1474 Fset_window_buffer (selected_frame->minibuffer_window,
1475 XWINDOW (minibuf_window)->buffer);
1476 minibuf_window = selected_frame->minibuffer_window;
1477 }
1478
dbc4e1c1 1479 /* I think this should be done with a hook. */
032d78fe
GV
1480#ifdef HAVE_WINDOW_SYSTEM
1481 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1482 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1483#endif
dc6f92b8 1484
565620a5
RS
1485 /* Make menu bar update for the Buffers and Frams menus. */
1486 windows_or_buffers_changed++;
1487
dc6f92b8
JB
1488 return Qnil;
1489}
1490
ff11dfa1 1491DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1492 0, 1, "",
8693ca83
JB
1493 "Make the frame FRAME into an icon.\n\
1494If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1495 (frame)
1496 Lisp_Object frame;
dc6f92b8 1497{
1aa66088 1498 if (NILP (frame))
2d80a27a 1499 XSETFRAME (frame, selected_frame);
1aa66088 1500
ff11dfa1 1501 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1502
3d378fdf 1503#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1504 /* Don't let the frame remain selected. */
1505 if (XFRAME (frame) == selected_frame)
1506 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1507#endif
9c394f17
RS
1508
1509 /* Don't allow minibuf_window to remain on a deleted frame. */
1510 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1511 {
1512 Fset_window_buffer (selected_frame->minibuffer_window,
1513 XWINDOW (minibuf_window)->buffer);
1514 minibuf_window = selected_frame->minibuffer_window;
1515 }
1516
dbc4e1c1 1517 /* I think this should be done with a hook. */
032d78fe
GV
1518#ifdef HAVE_WINDOW_SYSTEM
1519 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1520 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1521#endif
dc6f92b8 1522
565620a5
RS
1523 /* Make menu bar update for the Buffers and Frams menus. */
1524 windows_or_buffers_changed++;
1525
dc6f92b8
JB
1526 return Qnil;
1527}
1528
ff11dfa1 1529DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1530 1, 1, 0,
ff11dfa1
JB
1531 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1532A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1533a window system, it may not show at all.\n\
fd0c2bd1 1534Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1535 (frame)
1536 Lisp_Object frame;
dc6f92b8 1537{
ff11dfa1 1538 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1539
5c044f55
RS
1540 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1541
a42e9724 1542 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1543 return Qt;
a42e9724 1544 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1545 return Qicon;
dc6f92b8
JB
1546 return Qnil;
1547}
1548
ff11dfa1 1549DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1550 0, 0, 0,
ff11dfa1 1551 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1552 ()
1553{
ff11dfa1
JB
1554 Lisp_Object tail, frame;
1555 struct frame *f;
dc6f92b8
JB
1556 Lisp_Object value;
1557
1558 value = Qnil;
ff11dfa1 1559 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1560 {
ff11dfa1 1561 frame = XCONS (tail)->car;
e35d291d 1562 if (!FRAMEP (frame))
dc6f92b8 1563 continue;
ff11dfa1 1564 f = XFRAME (frame);
a42e9724 1565 if (FRAME_VISIBLE_P (f))
ff11dfa1 1566 value = Fcons (frame, value);
dc6f92b8
JB
1567 }
1568 return value;
1569}
d5e7c279
JB
1570
1571
e518d5e1 1572DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
dbc4e1c1
JB
1573 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1574If FRAME is invisible, make it visible.\n\
828ac693 1575If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1576If Emacs is displaying on an ordinary terminal or some other device which\n\
1577doesn't support multiple overlapping frames, this function does nothing.")
1578 (frame)
1579 Lisp_Object frame;
1580{
828ac693
RS
1581 if (NILP (frame))
1582 XSETFRAME (frame, selected_frame);
1583
dbc4e1c1 1584 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1585
1586 /* Do like the documentation says. */
1587 Fmake_frame_visible (frame);
1588
dbc4e1c1
JB
1589 if (frame_raise_lower_hook)
1590 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1591
1592 return Qnil;
1593}
1594
b49f5578 1595/* Should we have a corresponding function called Flower_Power? */
e518d5e1 1596DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
dbc4e1c1 1597 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
828ac693 1598If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1599If Emacs is displaying on an ordinary terminal or some other device which\n\
1600doesn't support multiple overlapping frames, this function does nothing.")
1601 (frame)
1602 Lisp_Object frame;
1603{
828ac693
RS
1604 if (NILP (frame))
1605 XSETFRAME (frame, selected_frame);
1606
dbc4e1c1
JB
1607 CHECK_LIVE_FRAME (frame, 0);
1608
1609 if (frame_raise_lower_hook)
1610 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1611
1612 return Qnil;
1613}
1614
d5e7c279 1615\f
ff11dfa1 1616DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1617 1, 2, 0,
ff11dfa1 1618 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1619In other words, switch-frame events caused by events in FRAME will\n\
1620request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1621FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1622\n\
a42e9724 1623If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1624cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1625\n\
a42e9724
JB
1626Focus redirection is useful for temporarily redirecting keystrokes to\n\
1627a surrogate minibuffer frame when a frame doesn't have its own\n\
1628minibuffer window.\n\
d5e7c279 1629\n\
a42e9724
JB
1630A frame's focus redirection can be changed by select-frame. If frame\n\
1631FOO is selected, and then a different frame BAR is selected, any\n\
1632frames redirecting their focus to FOO are shifted to redirect their\n\
1633focus to BAR. This allows focus redirection to work properly when the\n\
1634user switches from one frame to another using `select-window'.\n\
1635\n\
1636This means that a frame whose focus is redirected to itself is treated\n\
1637differently from a frame whose focus is redirected to nil; the former\n\
1638is affected by select-frame, while the latter is not.\n\
1639\n\
1640The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1641 (frame, focus_frame)
1642 Lisp_Object frame, focus_frame;
d5e7c279 1643{
13144095
JB
1644 /* Note that we don't check for a live frame here. It's reasonable
1645 to redirect the focus of a frame you're about to delete, if you
1646 know what other frame should receive those keystrokes. */
1647 CHECK_FRAME (frame, 0);
f9898cc6 1648
a42e9724 1649 if (! NILP (focus_frame))
ff11dfa1 1650 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1651
ff11dfa1 1652 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1653
ff11dfa1 1654 if (frame_rehighlight_hook)
dc0700f6 1655 (*frame_rehighlight_hook) (XFRAME (frame));
d5e7c279
JB
1656
1657 return Qnil;
1658}
1659
1660
ff11dfa1
JB
1661DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1662 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1663This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1664See `redirect-frame-focus'.")
1665 (frame)
1666 Lisp_Object frame;
d5e7c279 1667{
ff11dfa1 1668 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1669
ff11dfa1 1670 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1671}
1672
1673
dc6f92b8 1674\f
329ca574
RS
1675/* Return the value of frame parameter PROP in frame FRAME. */
1676
dc6f92b8 1677Lisp_Object
ff11dfa1
JB
1678get_frame_param (frame, prop)
1679 register struct frame *frame;
dc6f92b8
JB
1680 Lisp_Object prop;
1681{
1682 register Lisp_Object tem;
1683
ff11dfa1 1684 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1685 if (EQ (tem, Qnil))
1686 return tem;
1687 return Fcdr (tem);
1688}
1689
329ca574
RS
1690/* Return the buffer-predicate of the selected frame. */
1691
1692Lisp_Object
1693frame_buffer_predicate ()
1694{
1695 return selected_frame->buffer_predicate;
1696}
1697
fa54c6ae
RS
1698/* Return the buffer-list of the selected frame. */
1699
1700Lisp_Object
1701frame_buffer_list ()
1702{
1703 return selected_frame->buffer_list;
1704}
1705
1706/* Set the buffer-list of the selected frame. */
1707
1708void
1709set_frame_buffer_list (list)
1710 Lisp_Object list;
1711{
1712 selected_frame->buffer_list = list;
1713}
1714
1715/* Discard BUFFER from the buffer-list of each frame. */
1716
1717void
1718frames_discard_buffer (buffer)
1719 Lisp_Object buffer;
1720{
1721 Lisp_Object frame, tail;
1722
1723 FOR_EACH_FRAME (tail, frame)
1724 {
1725 XFRAME (frame)->buffer_list
1726 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1727 }
1728}
1729
214b3216
RS
1730/* Move BUFFER to the end of the buffer-list of each frame. */
1731
1732void
1733frames_bury_buffer (buffer)
1734 Lisp_Object buffer;
1735{
1736 Lisp_Object frame, tail;
1737
1738 FOR_EACH_FRAME (tail, frame)
1739 {
1740 XFRAME (frame)->buffer_list
1741 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1742 Fcons (buffer, Qnil));
1743 }
1744}
1745
329ca574
RS
1746/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1747 If the alist already has an element for PROP, we change it. */
1748
dc6f92b8 1749void
fd0c2bd1 1750store_in_alist (alistptr, prop, val)
dc6f92b8 1751 Lisp_Object *alistptr, val;
fd0c2bd1 1752 Lisp_Object prop;
dc6f92b8
JB
1753{
1754 register Lisp_Object tem;
dc6f92b8 1755
dc6f92b8
JB
1756 tem = Fassq (prop, *alistptr);
1757 if (EQ (tem, Qnil))
1758 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1759 else
1760 Fsetcdr (tem, val);
1761}
1762
e5317d61
EZ
1763static int
1764frame_name_fnn_p (str, len)
1765 char *str;
1766 int len;
1767{
1768 if (len > 1 && str[0] == 'F')
1769 {
1770 char *end_ptr;
1771 long num = strtol (str + 1, &end_ptr, 10);
1772
1773 if (end_ptr == str + len)
1774 return 1;
1775 }
1776 return 0;
1777}
1778
1779/* Set the name of the terminal frame. Also used by MSDOS frames.
1780 Modeled after x_set_name which is used for WINDOW frames. */
1781
1782void
1783set_term_frame_name (f, name)
1784 struct frame *f;
1785 Lisp_Object name;
1786{
1787 f->explicit_name = ! NILP (name);
1788
1789 /* If NAME is nil, set the name to F<num>. */
1790 if (NILP (name))
1791 {
1792 char namebuf[20];
1793
1794 /* Check for no change needed in this very common case
1795 before we do any consing. */
e34c5c7d 1796 if (frame_name_fnn_p (XSTRING (f->name)->data,
fc932ac6 1797 STRING_BYTES (XSTRING (f->name))))
e5317d61
EZ
1798 return;
1799
1800 terminal_frame_count++;
1801 sprintf (namebuf, "F%d", terminal_frame_count);
1802 name = build_string (namebuf);
1803 }
1804 else
1805 {
1806 CHECK_STRING (name, 0);
1807
1808 /* Don't change the name if it's already NAME. */
1809 if (! NILP (Fstring_equal (name, f->name)))
1810 return;
1811
1812 /* Don't allow the user to set the frame name to F<num>, so it
1813 doesn't clash with the names we generate for terminal frames. */
fc932ac6 1814 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
e5317d61
EZ
1815 error ("Frame names of the form F<num> are usurped by Emacs");
1816 }
1817
1818 f->name = name;
1819 update_mode_lines = 1;
1820}
1821
dc6f92b8 1822void
ff11dfa1
JB
1823store_frame_param (f, prop, val)
1824 struct frame *f;
dc6f92b8
JB
1825 Lisp_Object prop, val;
1826{
1827 register Lisp_Object tem;
1828
fa54c6ae
RS
1829 if (EQ (prop, Qbuffer_list))
1830 {
1831 f->buffer_list = val;
1832 return;
1833 }
1834
ff11dfa1 1835 tem = Fassq (prop, f->param_alist);
dc6f92b8 1836 if (EQ (tem, Qnil))
ff11dfa1 1837 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1838 else
1839 Fsetcdr (tem, val);
bc93c097 1840
329ca574
RS
1841 if (EQ (prop, Qbuffer_predicate))
1842 f->buffer_predicate = val;
1843
032d78fe 1844 if (! FRAME_WINDOW_P (f))
e5317d61
EZ
1845 {
1846 if (EQ (prop, Qmenu_bar_lines))
1847 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1848 else if (EQ (prop, Qname))
1849 set_term_frame_name (f, val);
1850 }
a249de79 1851
e35d291d 1852 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1853 {
1854 if (! MINI_WINDOW_P (XWINDOW (val)))
1855 error ("Surrogate minibuffer windows must be minibuffer windows.");
1856
7af7ef38
KH
1857 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1858 && !EQ (val, f->minibuffer_window))
1859 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1860
1861 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1862 f->minibuffer_window = val;
bc93c097 1863 }
dc6f92b8
JB
1864}
1865
ff11dfa1
JB
1866DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1867 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1868It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1869The meaningful PARMs depend on the kind of frame.\n\
1870If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1871 (frame)
1872 Lisp_Object frame;
dc6f92b8
JB
1873{
1874 Lisp_Object alist;
f769f1b2 1875 FRAME_PTR f;
dd10ec4f 1876 int height, width;
dc6f92b8 1877
ff11dfa1
JB
1878 if (EQ (frame, Qnil))
1879 f = selected_frame;
dc6f92b8
JB
1880 else
1881 {
ff11dfa1
JB
1882 CHECK_FRAME (frame, 0);
1883 f = XFRAME (frame);
dc6f92b8
JB
1884 }
1885
f769f1b2 1886 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
1887 return Qnil;
1888
ff11dfa1 1889 alist = Fcopy_alist (f->param_alist);
bb221971
RS
1890#ifdef MSDOS
1891 if (FRAME_MSDOS_P (f))
1892 {
1893 static char *colornames[16] =
1894 {
1895 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1896 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1897 "lightred", "lightmagenta", "yellow", "white"
1898 };
1899 store_in_alist (&alist, intern ("foreground-color"),
1900 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
1901 store_in_alist (&alist, intern ("background-color"),
1902 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
1903 }
1904 store_in_alist (&alist, intern ("font"), build_string ("default"));
1905#endif
fd0c2bd1 1906 store_in_alist (&alist, Qname, f->name);
dd10ec4f
RS
1907 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
1908 store_in_alist (&alist, Qheight, make_number (height));
1909 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
1910 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 1911 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 1912 store_in_alist (&alist, Qminibuffer,
39acc701 1913 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
1914 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1915 : FRAME_MINIBUF_WINDOW (f)));
1916 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
fa54c6ae 1917 store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
fd0c2bd1 1918
dbc4e1c1 1919 /* I think this should be done with a hook. */
032d78fe
GV
1920#ifdef HAVE_WINDOW_SYSTEM
1921 if (FRAME_WINDOW_P (f))
ff11dfa1 1922 x_report_frame_params (f, &alist);
b6dd20ed 1923 else
fd0c2bd1 1924#endif
16a3738c
KH
1925 {
1926 /* This ought to be correct in f->param_alist for an X frame. */
1927 Lisp_Object lines;
f4e93c40 1928 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
1929 store_in_alist (&alist, Qmenu_bar_lines, lines);
1930 }
dc6f92b8
JB
1931 return alist;
1932}
1933
ff11dfa1
JB
1934DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1935 Smodify_frame_parameters, 2, 2, 0,
1936 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1937ALIST is an alist of parameters to change and their new values.\n\
1938Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
e80f3932
RS
1939The meaningful PARMs depend on the kind of frame.\n\
1940Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1941so that `frame-parameters' will return them.")
ff11dfa1
JB
1942 (frame, alist)
1943 Lisp_Object frame, alist;
dc6f92b8 1944{
fd0c2bd1 1945 FRAME_PTR f;
dc6f92b8
JB
1946 register Lisp_Object tail, elt, prop, val;
1947
ff11dfa1
JB
1948 if (EQ (frame, Qnil))
1949 f = selected_frame;
dc6f92b8
JB
1950 else
1951 {
ff11dfa1
JB
1952 CHECK_LIVE_FRAME (frame, 0);
1953 f = XFRAME (frame);
dc6f92b8
JB
1954 }
1955
dbc4e1c1 1956 /* I think this should be done with a hook. */
032d78fe
GV
1957#ifdef HAVE_WINDOW_SYSTEM
1958 if (FRAME_WINDOW_P (f))
fd0c2bd1 1959 x_set_frame_parameters (f, alist);
329ca574 1960 else
bb221971
RS
1961#endif
1962#ifdef MSDOS
1963 if (FRAME_MSDOS_P (f))
1964 IT_set_frame_parameters (f, alist);
1965 else
329ca574 1966#endif
41d44f1f
RS
1967 {
1968 int length = XINT (Flength (alist));
1969 int i;
1970 Lisp_Object *parms
1971 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1972 Lisp_Object *values
1973 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1974
1975 /* Extract parm names and values into those vectors. */
1976
1977 i = 0;
1978 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
1979 {
1980 Lisp_Object elt, prop, val;
1981
1982 elt = Fcar (tail);
1983 parms[i] = Fcar (elt);
1984 values[i] = Fcdr (elt);
1985 i++;
1986 }
1987
1988 /* Now process them in reverse of specified order. */
1989 for (i--; i >= 0; i--)
1990 {
1991 prop = parms[i];
1992 val = values[i];
1993 store_frame_param (f, prop, val);
1994 }
1995 }
dc6f92b8
JB
1996
1997 return Qnil;
1998}
1999\f
a26a1f95
RS
2000DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2001 0, 1, 0,
2002 "Height in pixels of a line in the font in frame FRAME.\n\
2003If FRAME is omitted, the selected frame is used.\n\
2004For a terminal frame, the value is always 1.")
ff11dfa1
JB
2005 (frame)
2006 Lisp_Object frame;
dc6f92b8 2007{
a26a1f95 2008 struct frame *f;
dc6f92b8 2009
a26a1f95
RS
2010 if (NILP (frame))
2011 f = selected_frame;
2012 else
2013 {
2014 CHECK_FRAME (frame, 0);
2015 f = XFRAME (frame);
2016 }
2017
032d78fe
GV
2018#ifdef HAVE_WINDOW_SYSTEM
2019 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2020 return make_number (x_char_height (f));
2021 else
dc6d9681 2022#endif
a26a1f95
RS
2023 return make_number (1);
2024}
dc6d9681 2025
dc6f92b8 2026
a26a1f95
RS
2027DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2028 0, 1, 0,
2029 "Width in pixels of characters in the font in frame FRAME.\n\
2030If FRAME is omitted, the selected frame is used.\n\
2031The width is the same for all characters, because\n\
2032currently Emacs supports only fixed-width fonts.\n\
2033For a terminal screen, the value is always 1.")
2034 (frame)
2035 Lisp_Object frame;
dc6f92b8 2036{
a26a1f95
RS
2037 struct frame *f;
2038
2039 if (NILP (frame))
2040 f = selected_frame;
2041 else
2042 {
2043 CHECK_FRAME (frame, 0);
2044 f = XFRAME (frame);
2045 }
2046
032d78fe
GV
2047#ifdef HAVE_WINDOW_SYSTEM
2048 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2049 return make_number (x_char_width (f));
2050 else
2051#endif
2052 return make_number (1);
dc6f92b8
JB
2053}
2054
a26a1f95
RS
2055DEFUN ("frame-pixel-height", Fframe_pixel_height,
2056 Sframe_pixel_height, 0, 1, 0,
164a14ef 2057 "Return a FRAME's height in pixels.\n\
07822795
RS
2058This counts only the height available for text lines,\n\
2059not menu bars on window-system Emacs frames.\n\
164a14ef 2060For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
2061If FRAME is omitted, the selected frame is used.")
2062 (frame)
2063 Lisp_Object frame;
dc6f92b8 2064{
a26a1f95
RS
2065 struct frame *f;
2066
2067 if (NILP (frame))
2068 f = selected_frame;
2069 else
2070 {
2071 CHECK_FRAME (frame, 0);
2072 f = XFRAME (frame);
2073 }
2074
032d78fe
GV
2075#ifdef HAVE_WINDOW_SYSTEM
2076 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2077 return make_number (x_pixel_height (f));
2078 else
dc6d9681 2079#endif
a26a1f95
RS
2080 return make_number (FRAME_HEIGHT (f));
2081}
2082
2083DEFUN ("frame-pixel-width", Fframe_pixel_width,
2084 Sframe_pixel_width, 0, 1, 0,
2085 "Return FRAME's width in pixels.\n\
164a14ef 2086For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
2087If FRAME is omitted, the selected frame is used.")
2088 (frame)
2089 Lisp_Object frame;
2090{
2091 struct frame *f;
2092
2093 if (NILP (frame))
2094 f = selected_frame;
2095 else
2096 {
2097 CHECK_FRAME (frame, 0);
2098 f = XFRAME (frame);
2099 }
dc6f92b8 2100
032d78fe
GV
2101#ifdef HAVE_WINDOW_SYSTEM
2102 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2103 return make_number (x_pixel_width (f));
2104 else
2105#endif
2106 return make_number (FRAME_WIDTH (f));
2107}
2108\f
ff11dfa1
JB
2109DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2110 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 2111Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1 2112but that the idea of the actual height of the frame should not be changed.")
735eeca3
EN
2113 (frame, lines, pretend)
2114 Lisp_Object frame, lines, pretend;
dc6f92b8 2115{
ff11dfa1 2116 register struct frame *f;
dc6f92b8 2117
735eeca3 2118 CHECK_NUMBER (lines, 0);
ff11dfa1
JB
2119 if (NILP (frame))
2120 f = selected_frame;
dc6f92b8
JB
2121 else
2122 {
ff11dfa1
JB
2123 CHECK_LIVE_FRAME (frame, 0);
2124 f = XFRAME (frame);
dc6f92b8
JB
2125 }
2126
dbc4e1c1 2127 /* I think this should be done with a hook. */
032d78fe
GV
2128#ifdef HAVE_WINDOW_SYSTEM
2129 if (FRAME_WINDOW_P (f))
dc6f92b8 2130 {
735eeca3
EN
2131 if (XINT (lines) != f->height)
2132 x_set_window_size (f, 1, f->width, XINT (lines));
dc6f92b8
JB
2133 }
2134 else
fd0c2bd1 2135#endif
735eeca3 2136 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
dc6f92b8
JB
2137 return Qnil;
2138}
2139
ff11dfa1
JB
2140DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2141 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 2142Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
2143but that the idea of the actual width of the frame should not be changed.")
2144 (frame, cols, pretend)
fd0c2bd1 2145 Lisp_Object frame, cols, pretend;
dc6f92b8 2146{
ff11dfa1 2147 register struct frame *f;
dc6f92b8 2148 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
2149 if (NILP (frame))
2150 f = selected_frame;
dc6f92b8
JB
2151 else
2152 {
ff11dfa1
JB
2153 CHECK_LIVE_FRAME (frame, 0);
2154 f = XFRAME (frame);
dc6f92b8
JB
2155 }
2156
dbc4e1c1 2157 /* I think this should be done with a hook. */
032d78fe
GV
2158#ifdef HAVE_WINDOW_SYSTEM
2159 if (FRAME_WINDOW_P (f))
dc6f92b8 2160 {
ff11dfa1 2161 if (XINT (cols) != f->width)
808c0f20 2162 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
2163 }
2164 else
fd0c2bd1
JB
2165#endif
2166 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
2167 return Qnil;
2168}
2169
ff11dfa1
JB
2170DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2171 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2172 (frame, cols, rows)
2173 Lisp_Object frame, cols, rows;
dc6f92b8 2174{
ff11dfa1 2175 register struct frame *f;
dc6f92b8
JB
2176 int mask;
2177
ff11dfa1 2178 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2179 CHECK_NUMBER (cols, 2);
2180 CHECK_NUMBER (rows, 1);
ff11dfa1 2181 f = XFRAME (frame);
dc6f92b8 2182
dbc4e1c1 2183 /* I think this should be done with a hook. */
032d78fe
GV
2184#ifdef HAVE_WINDOW_SYSTEM
2185 if (FRAME_WINDOW_P (f))
dc6f92b8 2186 {
29824ce2
RS
2187 if (XINT (rows) != f->height || XINT (cols) != f->width
2188 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
808c0f20 2189 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
2190 }
2191 else
fd0c2bd1
JB
2192#endif
2193 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
2194
2195 return Qnil;
2196}
2197
ff11dfa1
JB
2198DEFUN ("set-frame-position", Fset_frame_position,
2199 Sset_frame_position, 3, 3, 0,
2200 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
2201This is actually the position of the upper left corner of the frame.\n\
2202Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 2203the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
2204 (frame, xoffset, yoffset)
2205 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2206{
ff11dfa1 2207 register struct frame *f;
dc6f92b8
JB
2208 int mask;
2209
ff11dfa1 2210 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2211 CHECK_NUMBER (xoffset, 1);
2212 CHECK_NUMBER (yoffset, 2);
ff11dfa1 2213 f = XFRAME (frame);
dc6f92b8 2214
dbc4e1c1 2215 /* I think this should be done with a hook. */
032d78fe
GV
2216#ifdef HAVE_WINDOW_SYSTEM
2217 if (FRAME_WINDOW_P (f))
c7c70761 2218 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2219#endif
dc6f92b8
JB
2220
2221 return Qt;
2222}
dc6d9681 2223
dc6f92b8 2224\f
ff11dfa1 2225syms_of_frame ()
dc6f92b8 2226{
a249de79 2227 syms_of_frame_1 ();
dc6f92b8 2228
ff11dfa1 2229 staticpro (&Vframe_list);
dc6f92b8 2230
ff11dfa1
JB
2231 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2232 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
2233
2234 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 2235 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
2236 Vemacs_iconified = Qnil;
2237
c60f3a6a 2238 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
ff11dfa1 2239 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 2240\n\
ff11dfa1 2241Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
2242appropriate surrogate.\n\
2243\n\
2244Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 2245frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
2246minibuffer, no matter what this variable is set to. This means that\n\
2247this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 2248current set of frames, or where the minibuffer is currently being\n\
f9898cc6 2249displayed.");
dc6f92b8 2250
5add3885 2251 defsubr (&Sactive_minibuffer_window);
ff11dfa1 2252 defsubr (&Sframep);
dbc4e1c1 2253 defsubr (&Sframe_live_p);
bb1513c9 2254 defsubr (&Smake_terminal_frame);
0f85737c 2255 defsubr (&Shandle_switch_frame);
1c212787 2256 defsubr (&Signore_event);
ff11dfa1
JB
2257 defsubr (&Sselect_frame);
2258 defsubr (&Sselected_frame);
2259 defsubr (&Swindow_frame);
2260 defsubr (&Sframe_root_window);
d446a856 2261 defsubr (&Sframe_first_window);
ff11dfa1 2262 defsubr (&Sframe_selected_window);
4a7cfafc 2263 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
2264 defsubr (&Sframe_list);
2265 defsubr (&Snext_frame);
ef2c57ac 2266 defsubr (&Sprevious_frame);
ff11dfa1 2267 defsubr (&Sdelete_frame);
f9898cc6 2268 defsubr (&Smouse_position);
152e6c70 2269 defsubr (&Smouse_pixel_position);
dc6f92b8 2270 defsubr (&Sset_mouse_position);
152e6c70 2271 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 2272#if 0
ff11dfa1
JB
2273 defsubr (&Sframe_configuration);
2274 defsubr (&Srestore_frame_configuration);
dc6f92b8 2275#endif
ff11dfa1
JB
2276 defsubr (&Smake_frame_visible);
2277 defsubr (&Smake_frame_invisible);
2278 defsubr (&Siconify_frame);
2279 defsubr (&Sframe_visible_p);
2280 defsubr (&Svisible_frame_list);
b49f5578
JB
2281 defsubr (&Sraise_frame);
2282 defsubr (&Slower_frame);
ff11dfa1
JB
2283 defsubr (&Sredirect_frame_focus);
2284 defsubr (&Sframe_focus);
2285 defsubr (&Sframe_parameters);
2286 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
2287 defsubr (&Sframe_char_height);
2288 defsubr (&Sframe_char_width);
2289 defsubr (&Sframe_pixel_height);
2290 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
2291 defsubr (&Sset_frame_height);
2292 defsubr (&Sset_frame_width);
2293 defsubr (&Sset_frame_size);
2294 defsubr (&Sset_frame_position);
dc6f92b8 2295}
e5d77022 2296
2f0b07e0
JB
2297keys_of_frame ()
2298{
0f85737c 2299 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 2300 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1c212787
KH
2301 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2302 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2f0b07e0 2303}