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