(dired-do-copy): Remove spurios character.`n'
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999 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 "frame.h"
33 #ifdef HAVE_WINDOW_SYSTEM
34 #include "fontset.h"
35 #endif
36 #include "termhooks.h"
37 #include "dispextern.h"
38 #include "window.h"
39 #ifdef MSDOS
40 #include "msdos.h"
41 #include "dosfns.h"
42 #endif
43
44 #ifdef macintosh
45 extern struct mac_output *NewMacWindow ();
46 extern void DisposeMacWindow (struct mac_output *);
47 #endif
48
49 /* Evaluate this expression to rebuild the section of syms_of_frame
50 that initializes and staticpros the symbols declared below. Note
51 that Emacs 18 has a bug that keeps C-x C-e from being able to
52 evaluate this expression.
53
54 (progn
55 ;; Accumulate a list of the symbols we want to initialize from the
56 ;; declarations at the top of the file.
57 (goto-char (point-min))
58 (search-forward "/\*&&& symbols declared here &&&*\/\n")
59 (let (symbol-list)
60 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
61 (setq symbol-list
62 (cons (buffer-substring (match-beginning 1) (match-end 1))
63 symbol-list))
64 (forward-line 1))
65 (setq symbol-list (nreverse symbol-list))
66 ;; Delete the section of syms_of_... where we initialize the symbols.
67 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
68 (let ((start (point)))
69 (while (looking-at "^ Q")
70 (forward-line 2))
71 (kill-region start (point)))
72 ;; Write a new symbol initialization section.
73 (while symbol-list
74 (insert (format " %s = intern (\"" (car symbol-list)))
75 (let ((start (point)))
76 (insert (substring (car symbol-list) 1))
77 (subst-char-in-region start (point) ?_ ?-))
78 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
79 (setq symbol-list (cdr symbol-list)))))
80 */
81
82 /*&&& symbols declared here &&&*/
83 Lisp_Object Qframep;
84 Lisp_Object Qframe_live_p;
85 Lisp_Object Qheight;
86 Lisp_Object Qicon;
87 Lisp_Object Qminibuffer;
88 Lisp_Object Qmodeline;
89 Lisp_Object Qname;
90 Lisp_Object Qonly;
91 Lisp_Object Qunsplittable;
92 Lisp_Object Qmenu_bar_lines;
93 Lisp_Object Qtool_bar_lines;
94 Lisp_Object Qwidth;
95 Lisp_Object Qx;
96 Lisp_Object Qw32;
97 Lisp_Object Qpc;
98 Lisp_Object Qmac;
99 Lisp_Object Qvisible;
100 Lisp_Object Qbuffer_predicate;
101 Lisp_Object Qbuffer_list;
102 Lisp_Object Qtitle;
103
104 Lisp_Object Vterminal_frame;
105 Lisp_Object Vdefault_frame_alist;
106
107 static void
108 syms_of_frame_1 ()
109 {
110 /*&&& init symbols here &&&*/
111 Qframep = intern ("framep");
112 staticpro (&Qframep);
113 Qframe_live_p = intern ("frame-live-p");
114 staticpro (&Qframe_live_p);
115 Qheight = intern ("height");
116 staticpro (&Qheight);
117 Qicon = intern ("icon");
118 staticpro (&Qicon);
119 Qminibuffer = intern ("minibuffer");
120 staticpro (&Qminibuffer);
121 Qmodeline = intern ("modeline");
122 staticpro (&Qmodeline);
123 Qname = intern ("name");
124 staticpro (&Qname);
125 Qonly = intern ("only");
126 staticpro (&Qonly);
127 Qunsplittable = intern ("unsplittable");
128 staticpro (&Qunsplittable);
129 Qmenu_bar_lines = intern ("menu-bar-lines");
130 staticpro (&Qmenu_bar_lines);
131 Qtool_bar_lines = intern ("tool-bar-lines");
132 staticpro (&Qtool_bar_lines);
133 Qwidth = intern ("width");
134 staticpro (&Qwidth);
135 Qx = intern ("x");
136 staticpro (&Qx);
137 Qw32 = intern ("w32");
138 staticpro (&Qw32);
139 Qpc = intern ("pc");
140 staticpro (&Qpc);
141 Qmac = intern ("mac");
142 staticpro (&Qmac);
143 Qvisible = intern ("visible");
144 staticpro (&Qvisible);
145 Qbuffer_predicate = intern ("buffer-predicate");
146 staticpro (&Qbuffer_predicate);
147 Qbuffer_list = intern ("buffer-list");
148 staticpro (&Qbuffer_list);
149 Qtitle = intern ("title");
150 staticpro (&Qtitle);
151
152 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
153 "Alist of default values for frame creation.\n\
154 These may be set in your init file, like this:\n\
155 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
156 These override values given in window system configuration data,\n\
157 including X Windows' defaults database.\n\
158 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
159 For values specific to the separate minibuffer frame, see\n\
160 `minibuffer-frame-alist'.\n\
161 The `menu-bar-lines' element of the list controls whether new frames\n\
162 have menu bars; `menu-bar-mode' works by altering this element.");
163 Vdefault_frame_alist = Qnil;
164 }
165 \f
166 static void
167 set_menu_bar_lines_1 (window, n)
168 Lisp_Object window;
169 int n;
170 {
171 struct window *w = XWINDOW (window);
172
173 XSETFASTINT (w->last_modified, 0);
174 XSETFASTINT (w->top, XFASTINT (w->top) + n);
175 XSETFASTINT (w->height, XFASTINT (w->height) - n);
176
177 /* Handle just the top child in a vertical split. */
178 if (!NILP (w->vchild))
179 set_menu_bar_lines_1 (w->vchild, n);
180
181 /* Adjust all children in a horizontal split. */
182 for (window = w->hchild; !NILP (window); window = w->next)
183 {
184 w = XWINDOW (window);
185 set_menu_bar_lines_1 (window, n);
186 }
187 }
188
189 void
190 set_menu_bar_lines (f, value, oldval)
191 struct frame *f;
192 Lisp_Object value, oldval;
193 {
194 int nlines;
195 int olines = FRAME_MENU_BAR_LINES (f);
196
197 /* Right now, menu bars don't work properly in minibuf-only frames;
198 most of the commands try to apply themselves to the minibuffer
199 frame itself, and get an error because you can't switch buffers
200 in or split the minibuffer window. */
201 if (FRAME_MINIBUF_ONLY_P (f))
202 return;
203
204 if (INTEGERP (value))
205 nlines = XINT (value);
206 else
207 nlines = 0;
208
209 if (nlines != olines)
210 {
211 windows_or_buffers_changed++;
212 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
213 FRAME_MENU_BAR_LINES (f) = nlines;
214 set_menu_bar_lines_1 (f->root_window, nlines - olines);
215 adjust_glyphs (f);
216 }
217 }
218 \f
219 #include "buffer.h"
220
221 /* These help us bind and responding to switch-frame events. */
222 #include "commands.h"
223 #include "keyboard.h"
224
225 Lisp_Object Vemacs_iconified;
226 Lisp_Object Vframe_list;
227
228 struct x_output tty_display;
229
230 extern Lisp_Object Vminibuffer_list;
231 extern Lisp_Object get_minibuffer ();
232 extern Lisp_Object Fhandle_switch_frame ();
233 extern Lisp_Object Fredirect_frame_focus ();
234 extern Lisp_Object x_get_focus_frame ();
235 \f
236 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
237 "Return non-nil if OBJECT is a frame.\n\
238 Value is t for a termcap frame (a character-only terminal),\n\
239 `x' for an Emacs frame that is really an X window,\n\
240 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
241 `mac' for an Emacs frame on a Macintosh display,\n\
242 `pc' for a direct-write MS-DOS frame.\n\
243 See also `frame-live-p'.")
244 (object)
245 Lisp_Object object;
246 {
247 if (!FRAMEP (object))
248 return Qnil;
249 switch (XFRAME (object)->output_method)
250 {
251 case output_termcap:
252 return Qt;
253 case output_x_window:
254 return Qx;
255 case output_w32:
256 return Qw32;
257 case output_msdos_raw:
258 return Qpc;
259 case output_mac:
260 return Qmac;
261 default:
262 abort ();
263 }
264 }
265
266 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
267 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
268 Value is nil if OBJECT is not a live frame. If object is a live\n\
269 frame, the return value indicates what sort of output device it is\n\
270 displayed on. Value is t for a termcap frame (a character-only\n\
271 terminal), `x' for an Emacs frame being displayed in an X window.")
272 (object)
273 Lisp_Object object;
274 {
275 return ((FRAMEP (object)
276 && FRAME_LIVE_P (XFRAME (object)))
277 ? Fframep (object)
278 : Qnil);
279 }
280
281 struct frame *
282 make_frame (mini_p)
283 int mini_p;
284 {
285 Lisp_Object frame;
286 register struct frame *f;
287 register Lisp_Object root_window;
288 register Lisp_Object mini_window;
289 register struct Lisp_Vector *vec;
290 int i;
291
292 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
293 for (i = 0; i < VECSIZE (struct frame); i++)
294 XSETFASTINT (vec->contents[i], 0);
295 vec->size = VECSIZE (struct frame);
296 f = (struct frame *)vec;
297 XSETFRAME (frame, f);
298
299 f->desired_matrix = 0;
300 f->current_matrix = 0;
301 f->desired_pool = 0;
302 f->current_pool = 0;
303 f->glyphs_initialized_p = 0;
304 f->decode_mode_spec_buffer = 0;
305 f->visible = 0;
306 f->async_visible = 0;
307 f->output_data.nothing = 0;
308 f->iconified = 0;
309 f->async_iconified = 0;
310 f->wants_modeline = 1;
311 f->auto_raise = 0;
312 f->auto_lower = 0;
313 f->no_split = 0;
314 f->garbaged = 0;
315 f->has_minibuffer = mini_p;
316 f->focus_frame = Qnil;
317 f->explicit_name = 0;
318 f->can_have_scroll_bars = 0;
319 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
320 f->param_alist = Qnil;
321 f->scroll_bars = Qnil;
322 f->condemned_scroll_bars = Qnil;
323 f->face_alist = Qnil;
324 f->face_cache = NULL;
325 f->menu_bar_items = Qnil;
326 f->menu_bar_vector = Qnil;
327 f->menu_bar_items_used = 0;
328 f->buffer_predicate = Qnil;
329 f->buffer_list = Qnil;
330 #ifdef MULTI_KBOARD
331 f->kboard = initial_kboard;
332 #endif
333 f->namebuf = 0;
334 f->title = Qnil;
335 f->menu_bar_window = Qnil;
336 f->tool_bar_window = Qnil;
337 f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
338 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
339 f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
340
341 root_window = make_window ();
342 if (mini_p)
343 {
344 mini_window = make_window ();
345 XWINDOW (root_window)->next = mini_window;
346 XWINDOW (mini_window)->prev = root_window;
347 XWINDOW (mini_window)->mini_p = Qt;
348 XWINDOW (mini_window)->frame = frame;
349 f->minibuffer_window = mini_window;
350 }
351 else
352 {
353 mini_window = Qnil;
354 XWINDOW (root_window)->next = Qnil;
355 f->minibuffer_window = Qnil;
356 }
357
358 XWINDOW (root_window)->frame = frame;
359
360 /* 10 is arbitrary,
361 just so that there is "something there."
362 Correct size will be set up later with change_frame_size. */
363
364 SET_FRAME_WIDTH (f, 10);
365 f->height = 10;
366
367 XSETFASTINT (XWINDOW (root_window)->width, 10);
368 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
369
370 if (mini_p)
371 {
372 XSETFASTINT (XWINDOW (mini_window)->width, 10);
373 XSETFASTINT (XWINDOW (mini_window)->top, 9);
374 XSETFASTINT (XWINDOW (mini_window)->height, 1);
375 }
376
377 /* Choose a buffer for the frame's root window. */
378 {
379 Lisp_Object buf;
380
381 XWINDOW (root_window)->buffer = Qt;
382 buf = Fcurrent_buffer ();
383 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
384 a space), try to find another one. */
385 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
386 buf = Fother_buffer (buf, Qnil, Qnil);
387
388 /* Use set_window_buffer, not Fset_window_buffer, and don't let
389 hooks be run by it. The reason is that the whole frame/window
390 arrangement is not yet fully intialized at this point. Windows
391 don't have the right size, glyph matrices aren't initialized
392 etc. Running Lisp functions at this point surely ends in a
393 SEGV. */
394 set_window_buffer (root_window, buf, 0);
395 f->buffer_list = Fcons (buf, Qnil);
396 }
397
398 if (mini_p)
399 {
400 XWINDOW (mini_window)->buffer = Qt;
401 set_window_buffer (mini_window,
402 (NILP (Vminibuffer_list)
403 ? get_minibuffer (0)
404 : Fcar (Vminibuffer_list)),
405 0);
406 }
407
408 f->root_window = root_window;
409 f->selected_window = root_window;
410 /* Make sure this window seems more recently used than
411 a newly-created, never-selected window. */
412 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
413
414 #ifdef HAVE_WINDOW_SYSTEM
415 f->fontset_data = alloc_fontset_data ();
416 #endif
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 (XFASTINT (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 /* Check that F either is, or has forwarded its focus to,
946 MINIBUF's frame. */
947 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
948 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
949 FRAME_FOCUS_FRAME (XFRAME (f)))))
950 return f;
951 }
952 else
953 return f;
954 }
955
956 if (EQ (frame, f))
957 passed++;
958 }
959 }
960
961 /* Return the previous frame in the frame list before FRAME.
962 If MINIBUF is nil, exclude minibuffer-only frames.
963 If MINIBUF is a window, include only its own frame
964 and any frame now using that window as the minibuffer.
965 If MINIBUF is `visible', include all visible frames.
966 If MINIBUF is 0, include all visible and iconified frames.
967 Otherwise, include all frames. */
968
969 Lisp_Object
970 prev_frame (frame, minibuf)
971 Lisp_Object frame;
972 Lisp_Object minibuf;
973 {
974 Lisp_Object tail;
975 Lisp_Object prev;
976
977 /* There must always be at least one frame in Vframe_list. */
978 if (! CONSP (Vframe_list))
979 abort ();
980
981 prev = Qnil;
982 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
983 {
984 Lisp_Object f;
985
986 f = XCAR (tail);
987 if (!FRAMEP (f))
988 abort ();
989
990 if (EQ (frame, f) && !NILP (prev))
991 return prev;
992
993 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
994 {
995 /* Decide whether this frame is eligible to be returned,
996 according to minibuf. */
997 if (NILP (minibuf))
998 {
999 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1000 prev = f;
1001 }
1002 else if (WINDOWP (minibuf))
1003 {
1004 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1005 /* Check that F either is, or has forwarded its focus to,
1006 MINIBUF's frame. */
1007 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1008 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1009 FRAME_FOCUS_FRAME (XFRAME (f)))))
1010 prev = f;
1011 }
1012 else if (EQ (minibuf, Qvisible))
1013 {
1014 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1015 if (FRAME_VISIBLE_P (XFRAME (f)))
1016 prev = f;
1017 }
1018 else if (XFASTINT (minibuf) == 0)
1019 {
1020 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1021 if (FRAME_VISIBLE_P (XFRAME (f))
1022 || FRAME_ICONIFIED_P (XFRAME (f)))
1023 prev = f;
1024 }
1025 else
1026 prev = f;
1027 }
1028 }
1029
1030 /* We've scanned the entire list. */
1031 if (NILP (prev))
1032 /* We went through the whole frame list without finding a single
1033 acceptable frame. Return the original frame. */
1034 return frame;
1035 else
1036 /* There were no acceptable frames in the list before FRAME; otherwise,
1037 we would have returned directly from the loop. Since PREV is the last
1038 acceptable frame in the list, return it. */
1039 return prev;
1040 }
1041
1042
1043 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1044 "Return the next frame in the frame list after FRAME.\n\
1045 It considers only frames on the same terminal as FRAME.\n\
1046 By default, skip minibuffer-only frames.\n\
1047 If omitted, FRAME defaults to the selected frame.\n\
1048 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1049 If MINIFRAME is a window, include only its own frame\n\
1050 and any frame now using that window as the minibuffer.\n\
1051 If MINIFRAME is `visible', include all visible frames.\n\
1052 If MINIFRAME is 0, include all visible and iconified frames.\n\
1053 Otherwise, include all frames.")
1054 (frame, miniframe)
1055 Lisp_Object frame, miniframe;
1056 {
1057 if (NILP (frame))
1058 frame = selected_frame;
1059
1060 CHECK_LIVE_FRAME (frame, 0);
1061 return next_frame (frame, miniframe);
1062 }
1063
1064 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1065 "Return the previous frame in the frame list before FRAME.\n\
1066 It considers only frames on the same terminal as FRAME.\n\
1067 By default, skip minibuffer-only frames.\n\
1068 If omitted, FRAME defaults to the selected frame.\n\
1069 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1070 If MINIFRAME is a window, include only its own frame\n\
1071 and any frame now using that window as the minibuffer.\n\
1072 If MINIFRAME is `visible', include all visible frames.\n\
1073 If MINIFRAME is 0, include all visible and iconified frames.\n\
1074 Otherwise, include all frames.")
1075 (frame, miniframe)
1076 Lisp_Object frame, miniframe;
1077 {
1078 if (NILP (frame))
1079 frame = selected_frame;
1080 CHECK_LIVE_FRAME (frame, 0);
1081 return prev_frame (frame, miniframe);
1082 }
1083 \f
1084 /* Return 1 if it is ok to delete frame F;
1085 0 if all frames aside from F are invisible.
1086 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1087
1088 int
1089 other_visible_frames (f)
1090 FRAME_PTR f;
1091 {
1092 /* We know the selected frame is visible,
1093 so if F is some other frame, it can't be the sole visible one. */
1094 if (f == SELECTED_FRAME ())
1095 {
1096 Lisp_Object frames;
1097 int count = 0;
1098
1099 for (frames = Vframe_list;
1100 CONSP (frames);
1101 frames = XCDR (frames))
1102 {
1103 Lisp_Object this;
1104
1105 this = XCAR (frames);
1106 /* Verify that the frame's window still exists
1107 and we can still talk to it. And note any recent change
1108 in visibility. */
1109 #ifdef HAVE_WINDOW_SYSTEM
1110 if (FRAME_WINDOW_P (XFRAME (this)))
1111 {
1112 x_sync (XFRAME (this));
1113 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1114 }
1115 #endif
1116
1117 if (FRAME_VISIBLE_P (XFRAME (this))
1118 || FRAME_ICONIFIED_P (XFRAME (this))
1119 /* Allow deleting the terminal frame when at least
1120 one X frame exists! */
1121 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1122 count++;
1123 }
1124 return count > 1;
1125 }
1126 return 1;
1127 }
1128
1129 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1130 "Delete FRAME, permanently eliminating it from use.\n\
1131 If omitted, FRAME defaults to the selected frame.\n\
1132 A frame may not be deleted if its minibuffer is used by other frames.\n\
1133 Normally, you may not delete a frame if all other frames are invisible,\n\
1134 but if the second optional argument FORCE is non-nil, you may do so.")
1135 (frame, force)
1136 Lisp_Object frame, force;
1137 {
1138 struct frame *f;
1139 struct frame *sf = SELECTED_FRAME ();
1140 int minibuffer_selected;
1141
1142 if (EQ (frame, Qnil))
1143 {
1144 f = sf;
1145 XSETFRAME (frame, f);
1146 }
1147 else
1148 {
1149 CHECK_FRAME (frame, 0);
1150 f = XFRAME (frame);
1151 }
1152
1153 if (! FRAME_LIVE_P (f))
1154 return Qnil;
1155
1156 if (NILP (force) && !other_visible_frames (f))
1157 error ("Attempt to delete the sole visible or iconified frame");
1158
1159 #if 0
1160 /* This is a nice idea, but x_connection_closed needs to be able
1161 to delete the last frame, if it is gone. */
1162 if (NILP (XCDR (Vframe_list)))
1163 error ("Attempt to delete the only frame");
1164 #endif
1165
1166 /* Does this frame have a minibuffer, and is it the surrogate
1167 minibuffer for any other frame? */
1168 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1169 {
1170 Lisp_Object frames;
1171
1172 for (frames = Vframe_list;
1173 CONSP (frames);
1174 frames = XCDR (frames))
1175 {
1176 Lisp_Object this;
1177 this = XCAR (frames);
1178
1179 if (! EQ (this, frame)
1180 && EQ (frame,
1181 WINDOW_FRAME (XWINDOW
1182 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1183 error ("Attempt to delete a surrogate minibuffer frame");
1184 }
1185 }
1186
1187 minibuffer_selected = EQ (minibuf_window, selected_window);
1188
1189 /* Don't let the frame remain selected. */
1190 if (f == sf)
1191 {
1192 Lisp_Object tail, frame1;
1193
1194 /* Look for another visible frame on the same terminal. */
1195 frame1 = next_frame (frame, Qvisible);
1196
1197 /* If there is none, find *some* other frame. */
1198 if (NILP (frame1) || EQ (frame1, frame))
1199 {
1200 FOR_EACH_FRAME (tail, frame1)
1201 {
1202 if (! EQ (frame, frame1))
1203 break;
1204 }
1205 }
1206
1207 do_switch_frame (frame1, Qnil, 0);
1208 sf = SELECTED_FRAME ();
1209 }
1210
1211 /* Don't allow minibuf_window to remain on a deleted frame. */
1212 if (EQ (f->minibuffer_window, minibuf_window))
1213 {
1214 Fset_window_buffer (sf->minibuffer_window,
1215 XWINDOW (minibuf_window)->buffer);
1216 minibuf_window = sf->minibuffer_window;
1217
1218 /* If the dying minibuffer window was selected,
1219 select the new one. */
1220 if (minibuffer_selected)
1221 Fselect_window (minibuf_window);
1222 }
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 #ifdef HAVE_WINDOW_SYSTEM
1258 /* Free all fontset data. */
1259 free_fontset_data (FRAME_FONTSET_DATA (f));
1260 #endif
1261
1262 /* Since some events are handled at the interrupt level, we may get
1263 an event for f at any time; if we zero out the frame's display
1264 now, then we may trip up the event-handling code. Instead, we'll
1265 promise that the display of the frame must be valid until we have
1266 called the window-system-dependent frame destruction routine. */
1267
1268 /* I think this should be done with a hook. */
1269 #ifdef HAVE_WINDOW_SYSTEM
1270 if (FRAME_WINDOW_P (f))
1271 x_destroy_window (f);
1272 #endif
1273
1274 /* Done by x_destroy_window above already */
1275 #if 0
1276 #ifdef macintosh
1277 if (FRAME_MAC_P (f))
1278 DisposeMacWindow (f->output_data.mac);
1279 #endif
1280 #endif
1281
1282 f->output_data.nothing = 0;
1283
1284 /* If we've deleted the last_nonminibuf_frame, then try to find
1285 another one. */
1286 if (f == last_nonminibuf_frame)
1287 {
1288 Lisp_Object frames;
1289
1290 last_nonminibuf_frame = 0;
1291
1292 for (frames = Vframe_list;
1293 CONSP (frames);
1294 frames = XCDR (frames))
1295 {
1296 f = XFRAME (XCAR (frames));
1297 if (!FRAME_MINIBUF_ONLY_P (f))
1298 {
1299 last_nonminibuf_frame = f;
1300 break;
1301 }
1302 }
1303 }
1304
1305 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1306 find another one. Prefer minibuffer-only frames, but also notice
1307 frames with other windows. */
1308 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1309 {
1310 Lisp_Object frames;
1311
1312 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1313 Lisp_Object frame_with_minibuf;
1314 /* Some frame we found on the same kboard, or nil if there are none. */
1315 Lisp_Object frame_on_same_kboard;
1316
1317 frame_on_same_kboard = Qnil;
1318 frame_with_minibuf = Qnil;
1319
1320 for (frames = Vframe_list;
1321 CONSP (frames);
1322 frames = XCDR (frames))
1323 {
1324 Lisp_Object this;
1325 struct frame *f1;
1326
1327 this = XCAR (frames);
1328 if (!FRAMEP (this))
1329 abort ();
1330 f1 = XFRAME (this);
1331
1332 /* Consider only frames on the same kboard
1333 and only those with minibuffers. */
1334 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1335 && FRAME_HAS_MINIBUF_P (f1))
1336 {
1337 frame_with_minibuf = this;
1338 if (FRAME_MINIBUF_ONLY_P (f1))
1339 break;
1340 }
1341
1342 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1343 frame_on_same_kboard = this;
1344 }
1345
1346 if (!NILP (frame_on_same_kboard))
1347 {
1348 /* We know that there must be some frame with a minibuffer out
1349 there. If this were not true, all of the frames present
1350 would have to be minibufferless, which implies that at some
1351 point their minibuffer frames must have been deleted, but
1352 that is prohibited at the top; you can't delete surrogate
1353 minibuffer frames. */
1354 if (NILP (frame_with_minibuf))
1355 abort ();
1356
1357 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1358 }
1359 else
1360 /* No frames left on this kboard--say no minibuffer either. */
1361 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1362 }
1363
1364 /* Cause frame titles to update--necessary if we now have just one frame. */
1365 update_mode_lines = 1;
1366
1367 return Qnil;
1368 }
1369 \f
1370 /* Return mouse position in character cell units. */
1371
1372 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1373 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1374 The position is given in character cells, where (0, 0) is the\n\
1375 upper-left corner.\n\
1376 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1377 to read the mouse position, it returns the selected frame for FRAME\n\
1378 and nil for X and Y.")
1379 ()
1380 {
1381 FRAME_PTR f;
1382 Lisp_Object lispy_dummy;
1383 enum scroll_bar_part party_dummy;
1384 Lisp_Object x, y;
1385 int col, row;
1386 unsigned long long_dummy;
1387
1388 f = SELECTED_FRAME ();
1389 x = y = Qnil;
1390
1391 #ifdef HAVE_MOUSE
1392 /* It's okay for the hook to refrain from storing anything. */
1393 if (mouse_position_hook)
1394 (*mouse_position_hook) (&f, -1,
1395 &lispy_dummy, &party_dummy,
1396 &x, &y,
1397 &long_dummy);
1398 if (! NILP (x))
1399 {
1400 col = XINT (x);
1401 row = XINT (y);
1402 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1403 XSETINT (x, col);
1404 XSETINT (y, row);
1405 }
1406 #endif
1407 XSETFRAME (lispy_dummy, f);
1408 return Fcons (lispy_dummy, Fcons (x, y));
1409 }
1410
1411 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1412 Smouse_pixel_position, 0, 0, 0,
1413 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1414 The position is given in pixel units, where (0, 0) is the\n\
1415 upper-left corner.\n\
1416 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1417 to read the mouse position, it returns the selected frame for FRAME\n\
1418 and nil for X and Y.")
1419 ()
1420 {
1421 FRAME_PTR f;
1422 Lisp_Object lispy_dummy;
1423 enum scroll_bar_part party_dummy;
1424 Lisp_Object x, y;
1425 unsigned long long_dummy;
1426
1427 f = SELECTED_FRAME ();
1428 x = y = Qnil;
1429
1430 #ifdef HAVE_MOUSE
1431 /* It's okay for the hook to refrain from storing anything. */
1432 if (mouse_position_hook)
1433 (*mouse_position_hook) (&f, -1,
1434 &lispy_dummy, &party_dummy,
1435 &x, &y,
1436 &long_dummy);
1437 #endif
1438 XSETFRAME (lispy_dummy, f);
1439 return Fcons (lispy_dummy, Fcons (x, y));
1440 }
1441
1442 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1443 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1444 Coordinates are relative to the frame, not a window,\n\
1445 so the coordinates of the top left character in the frame\n\
1446 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1447 \n\
1448 This function is a no-op for an X frame that is not visible.\n\
1449 If you have just created a frame, you must wait for it to become visible\n\
1450 before calling this function on it, like this.\n\
1451 (while (not (frame-visible-p frame)) (sleep-for .5))")
1452 (frame, x, y)
1453 Lisp_Object frame, x, y;
1454 {
1455 CHECK_LIVE_FRAME (frame, 0);
1456 CHECK_NUMBER (x, 2);
1457 CHECK_NUMBER (y, 1);
1458
1459 /* I think this should be done with a hook. */
1460 #ifdef HAVE_WINDOW_SYSTEM
1461 if (FRAME_WINDOW_P (XFRAME (frame)))
1462 /* Warping the mouse will cause enternotify and focus events. */
1463 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1464 #else
1465 #if defined (MSDOS) && defined (HAVE_MOUSE)
1466 if (FRAME_MSDOS_P (XFRAME (frame)))
1467 {
1468 Fselect_frame (frame, Qnil);
1469 mouse_moveto (XINT (x), XINT (y));
1470 }
1471 #endif
1472 #endif
1473
1474 return Qnil;
1475 }
1476
1477 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1478 Sset_mouse_pixel_position, 3, 3, 0,
1479 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1480 Note, this is a no-op for an X frame that is not visible.\n\
1481 If you have just created a frame, you must wait for it to become visible\n\
1482 before calling this function on it, like this.\n\
1483 (while (not (frame-visible-p frame)) (sleep-for .5))")
1484 (frame, x, y)
1485 Lisp_Object frame, x, y;
1486 {
1487 CHECK_LIVE_FRAME (frame, 0);
1488 CHECK_NUMBER (x, 2);
1489 CHECK_NUMBER (y, 1);
1490
1491 /* I think this should be done with a hook. */
1492 #ifdef HAVE_WINDOW_SYSTEM
1493 if (FRAME_WINDOW_P (XFRAME (frame)))
1494 /* Warping the mouse will cause enternotify and focus events. */
1495 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1496 #else
1497 #if defined (MSDOS) && defined (HAVE_MOUSE)
1498 if (FRAME_MSDOS_P (XFRAME (frame)))
1499 {
1500 Fselect_frame (frame, Qnil);
1501 mouse_moveto (XINT (x), XINT (y));
1502 }
1503 #endif
1504 #endif
1505
1506 return Qnil;
1507 }
1508 \f
1509 static void make_frame_visible_1 P_ ((Lisp_Object));
1510
1511 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1512 0, 1, "",
1513 "Make the frame FRAME visible (assuming it is an X-window).\n\
1514 If omitted, FRAME defaults to the currently selected frame.")
1515 (frame)
1516 Lisp_Object frame;
1517 {
1518 if (NILP (frame))
1519 frame = selected_frame;
1520
1521 CHECK_LIVE_FRAME (frame, 0);
1522
1523 /* I think this should be done with a hook. */
1524 #ifdef HAVE_WINDOW_SYSTEM
1525 if (FRAME_WINDOW_P (XFRAME (frame)))
1526 {
1527 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1528 x_make_frame_visible (XFRAME (frame));
1529 }
1530 #endif
1531
1532 make_frame_visible_1 (XFRAME (frame)->root_window);
1533
1534 /* Make menu bar update for the Buffers and Frams menus. */
1535 windows_or_buffers_changed++;
1536
1537 return frame;
1538 }
1539
1540 /* Update the display_time slot of the buffers shown in WINDOW
1541 and all its descendents. */
1542
1543 static void
1544 make_frame_visible_1 (window)
1545 Lisp_Object window;
1546 {
1547 struct window *w;
1548
1549 for (;!NILP (window); window = w->next)
1550 {
1551 w = XWINDOW (window);
1552
1553 if (!NILP (w->buffer))
1554 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1555
1556 if (!NILP (w->vchild))
1557 make_frame_visible_1 (w->vchild);
1558 if (!NILP (w->hchild))
1559 make_frame_visible_1 (w->hchild);
1560 }
1561 }
1562
1563 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1564 0, 2, "",
1565 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1566 If omitted, FRAME defaults to the currently selected frame.\n\
1567 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1568 but if the second optional argument FORCE is non-nil, you may do so.")
1569 (frame, force)
1570 Lisp_Object frame, force;
1571 {
1572 if (NILP (frame))
1573 frame = selected_frame;
1574
1575 CHECK_LIVE_FRAME (frame, 0);
1576
1577 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1578 error ("Attempt to make invisible the sole visible or iconified frame");
1579
1580 #if 0 /* This isn't logically necessary, and it can do GC. */
1581 /* Don't let the frame remain selected. */
1582 if (EQ (frame, selected_frame))
1583 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1584 #endif
1585
1586 /* Don't allow minibuf_window to remain on a deleted frame. */
1587 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1588 {
1589 struct frame *sf = XFRAME (selected_frame);
1590 Fset_window_buffer (sf->minibuffer_window,
1591 XWINDOW (minibuf_window)->buffer);
1592 minibuf_window = sf->minibuffer_window;
1593 }
1594
1595 /* I think this should be done with a hook. */
1596 #ifdef HAVE_WINDOW_SYSTEM
1597 if (FRAME_WINDOW_P (XFRAME (frame)))
1598 x_make_frame_invisible (XFRAME (frame));
1599 #endif
1600
1601 /* Make menu bar update for the Buffers and Frams menus. */
1602 windows_or_buffers_changed++;
1603
1604 return Qnil;
1605 }
1606
1607 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1608 0, 1, "",
1609 "Make the frame FRAME into an icon.\n\
1610 If omitted, FRAME defaults to the currently selected frame.")
1611 (frame)
1612 Lisp_Object frame;
1613 {
1614 if (NILP (frame))
1615 frame = selected_frame;
1616
1617 CHECK_LIVE_FRAME (frame, 0);
1618
1619 #if 0 /* This isn't logically necessary, and it can do GC. */
1620 /* Don't let the frame remain selected. */
1621 if (EQ (frame, selected_frame))
1622 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1623 #endif
1624
1625 /* Don't allow minibuf_window to remain on a deleted frame. */
1626 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1627 {
1628 struct frame *sf = XFRAME (selected_frame);
1629 Fset_window_buffer (sf->minibuffer_window,
1630 XWINDOW (minibuf_window)->buffer);
1631 minibuf_window = sf->minibuffer_window;
1632 }
1633
1634 /* I think this should be done with a hook. */
1635 #ifdef HAVE_WINDOW_SYSTEM
1636 if (FRAME_WINDOW_P (XFRAME (frame)))
1637 x_iconify_frame (XFRAME (frame));
1638 #endif
1639
1640 /* Make menu bar update for the Buffers and Frams menus. */
1641 windows_or_buffers_changed++;
1642
1643 return Qnil;
1644 }
1645
1646 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1647 1, 1, 0,
1648 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1649 A frame that is not \"visible\" is not updated and, if it works through\n\
1650 a window system, it may not show at all.\n\
1651 Return the symbol `icon' if frame is visible only as an icon.")
1652 (frame)
1653 Lisp_Object frame;
1654 {
1655 CHECK_LIVE_FRAME (frame, 0);
1656
1657 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1658
1659 if (FRAME_VISIBLE_P (XFRAME (frame)))
1660 return Qt;
1661 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1662 return Qicon;
1663 return Qnil;
1664 }
1665
1666 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1667 0, 0, 0,
1668 "Return a list of all frames now \"visible\" (being updated).")
1669 ()
1670 {
1671 Lisp_Object tail, frame;
1672 struct frame *f;
1673 Lisp_Object value;
1674
1675 value = Qnil;
1676 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1677 {
1678 frame = XCAR (tail);
1679 if (!FRAMEP (frame))
1680 continue;
1681 f = XFRAME (frame);
1682 if (FRAME_VISIBLE_P (f))
1683 value = Fcons (frame, value);
1684 }
1685 return value;
1686 }
1687
1688
1689 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1690 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1691 If FRAME is invisible, make it visible.\n\
1692 If you don't specify a frame, the selected frame is used.\n\
1693 If Emacs is displaying on an ordinary terminal or some other device which\n\
1694 doesn't support multiple overlapping frames, this function does nothing.")
1695 (frame)
1696 Lisp_Object frame;
1697 {
1698 if (NILP (frame))
1699 frame = selected_frame;
1700
1701 CHECK_LIVE_FRAME (frame, 0);
1702
1703 /* Do like the documentation says. */
1704 Fmake_frame_visible (frame);
1705
1706 if (frame_raise_lower_hook)
1707 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1708
1709 return Qnil;
1710 }
1711
1712 /* Should we have a corresponding function called Flower_Power? */
1713 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1714 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1715 If you don't specify a frame, the selected frame is used.\n\
1716 If Emacs is displaying on an ordinary terminal or some other device which\n\
1717 doesn't support multiple overlapping frames, this function does nothing.")
1718 (frame)
1719 Lisp_Object frame;
1720 {
1721 if (NILP (frame))
1722 frame = selected_frame;
1723
1724 CHECK_LIVE_FRAME (frame, 0);
1725
1726 if (frame_raise_lower_hook)
1727 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1728
1729 return Qnil;
1730 }
1731
1732 \f
1733 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1734 1, 2, 0,
1735 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1736 In other words, switch-frame events caused by events in FRAME will\n\
1737 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1738 FOCUS-FRAME after reading an event typed at FRAME.\n\
1739 \n\
1740 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1741 cancelled, and the frame again receives its own keystrokes.\n\
1742 \n\
1743 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1744 a surrogate minibuffer frame when a frame doesn't have its own\n\
1745 minibuffer window.\n\
1746 \n\
1747 A frame's focus redirection can be changed by select-frame. If frame\n\
1748 FOO is selected, and then a different frame BAR is selected, any\n\
1749 frames redirecting their focus to FOO are shifted to redirect their\n\
1750 focus to BAR. This allows focus redirection to work properly when the\n\
1751 user switches from one frame to another using `select-window'.\n\
1752 \n\
1753 This means that a frame whose focus is redirected to itself is treated\n\
1754 differently from a frame whose focus is redirected to nil; the former\n\
1755 is affected by select-frame, while the latter is not.\n\
1756 \n\
1757 The redirection lasts until `redirect-frame-focus' is called to change it.")
1758 (frame, focus_frame)
1759 Lisp_Object frame, focus_frame;
1760 {
1761 /* Note that we don't check for a live frame here. It's reasonable
1762 to redirect the focus of a frame you're about to delete, if you
1763 know what other frame should receive those keystrokes. */
1764 CHECK_FRAME (frame, 0);
1765
1766 if (! NILP (focus_frame))
1767 CHECK_LIVE_FRAME (focus_frame, 1);
1768
1769 XFRAME (frame)->focus_frame = focus_frame;
1770
1771 if (frame_rehighlight_hook)
1772 (*frame_rehighlight_hook) (XFRAME (frame));
1773
1774 return Qnil;
1775 }
1776
1777
1778 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1779 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1780 This returns nil if FRAME's focus is not redirected.\n\
1781 See `redirect-frame-focus'.")
1782 (frame)
1783 Lisp_Object frame;
1784 {
1785 CHECK_LIVE_FRAME (frame, 0);
1786
1787 return FRAME_FOCUS_FRAME (XFRAME (frame));
1788 }
1789
1790
1791 \f
1792 /* Return the value of frame parameter PROP in frame FRAME. */
1793
1794 Lisp_Object
1795 get_frame_param (frame, prop)
1796 register struct frame *frame;
1797 Lisp_Object prop;
1798 {
1799 register Lisp_Object tem;
1800
1801 tem = Fassq (prop, frame->param_alist);
1802 if (EQ (tem, Qnil))
1803 return tem;
1804 return Fcdr (tem);
1805 }
1806
1807 /* Return the buffer-predicate of the selected frame. */
1808
1809 Lisp_Object
1810 frame_buffer_predicate (frame)
1811 Lisp_Object frame;
1812 {
1813 return XFRAME (frame)->buffer_predicate;
1814 }
1815
1816 /* Return the buffer-list of the selected frame. */
1817
1818 Lisp_Object
1819 frame_buffer_list (frame)
1820 Lisp_Object frame;
1821 {
1822 return XFRAME (frame)->buffer_list;
1823 }
1824
1825 /* Set the buffer-list of the selected frame. */
1826
1827 void
1828 set_frame_buffer_list (frame, list)
1829 Lisp_Object frame, list;
1830 {
1831 XFRAME (frame)->buffer_list = list;
1832 }
1833
1834 /* Discard BUFFER from the buffer-list of each frame. */
1835
1836 void
1837 frames_discard_buffer (buffer)
1838 Lisp_Object buffer;
1839 {
1840 Lisp_Object frame, tail;
1841
1842 FOR_EACH_FRAME (tail, frame)
1843 {
1844 XFRAME (frame)->buffer_list
1845 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1846 }
1847 }
1848
1849 /* Move BUFFER to the end of the buffer-list of each frame. */
1850
1851 void
1852 frames_bury_buffer (buffer)
1853 Lisp_Object buffer;
1854 {
1855 Lisp_Object frame, tail;
1856
1857 FOR_EACH_FRAME (tail, frame)
1858 {
1859 XFRAME (frame)->buffer_list
1860 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1861 Fcons (buffer, Qnil));
1862 }
1863 }
1864
1865 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1866 If the alist already has an element for PROP, we change it. */
1867
1868 void
1869 store_in_alist (alistptr, prop, val)
1870 Lisp_Object *alistptr, val;
1871 Lisp_Object prop;
1872 {
1873 register Lisp_Object tem;
1874
1875 tem = Fassq (prop, *alistptr);
1876 if (EQ (tem, Qnil))
1877 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1878 else
1879 Fsetcdr (tem, val);
1880 }
1881
1882 static int
1883 frame_name_fnn_p (str, len)
1884 char *str;
1885 int len;
1886 {
1887 if (len > 1 && str[0] == 'F')
1888 {
1889 char *end_ptr;
1890
1891 strtol (str + 1, &end_ptr, 10);
1892
1893 if (end_ptr == str + len)
1894 return 1;
1895 }
1896 return 0;
1897 }
1898
1899 /* Set the name of the terminal frame. Also used by MSDOS frames.
1900 Modeled after x_set_name which is used for WINDOW frames. */
1901
1902 void
1903 set_term_frame_name (f, name)
1904 struct frame *f;
1905 Lisp_Object name;
1906 {
1907 f->explicit_name = ! NILP (name);
1908
1909 /* If NAME is nil, set the name to F<num>. */
1910 if (NILP (name))
1911 {
1912 char namebuf[20];
1913
1914 /* Check for no change needed in this very common case
1915 before we do any consing. */
1916 if (frame_name_fnn_p (XSTRING (f->name)->data,
1917 STRING_BYTES (XSTRING (f->name))))
1918 return;
1919
1920 terminal_frame_count++;
1921 sprintf (namebuf, "F%d", terminal_frame_count);
1922 name = build_string (namebuf);
1923 }
1924 else
1925 {
1926 CHECK_STRING (name, 0);
1927
1928 /* Don't change the name if it's already NAME. */
1929 if (! NILP (Fstring_equal (name, f->name)))
1930 return;
1931
1932 /* Don't allow the user to set the frame name to F<num>, so it
1933 doesn't clash with the names we generate for terminal frames. */
1934 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1935 error ("Frame names of the form F<num> are usurped by Emacs");
1936 }
1937
1938 f->name = name;
1939 update_mode_lines = 1;
1940 }
1941
1942 void
1943 store_frame_param (f, prop, val)
1944 struct frame *f;
1945 Lisp_Object prop, val;
1946 {
1947 register Lisp_Object tem;
1948
1949 if (EQ (prop, Qbuffer_list))
1950 {
1951 f->buffer_list = val;
1952 return;
1953 }
1954
1955 tem = Fassq (prop, f->param_alist);
1956 if (EQ (tem, Qnil))
1957 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1958 else
1959 Fsetcdr (tem, val);
1960
1961 if (EQ (prop, Qbuffer_predicate))
1962 f->buffer_predicate = val;
1963
1964 if (! FRAME_WINDOW_P (f))
1965 {
1966 if (EQ (prop, Qmenu_bar_lines))
1967 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1968 else if (EQ (prop, Qname))
1969 set_term_frame_name (f, val);
1970 }
1971
1972 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1973 {
1974 if (! MINI_WINDOW_P (XWINDOW (val)))
1975 error ("Surrogate minibuffer windows must be minibuffer windows.");
1976
1977 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1978 && !EQ (val, f->minibuffer_window))
1979 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1980
1981 /* Install the chosen minibuffer window, with proper buffer. */
1982 f->minibuffer_window = val;
1983 }
1984 }
1985
1986 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1987 "Return the parameters-alist of frame FRAME.\n\
1988 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1989 The meaningful PARMs depend on the kind of frame.\n\
1990 If FRAME is omitted, return information on the currently selected frame.")
1991 (frame)
1992 Lisp_Object frame;
1993 {
1994 Lisp_Object alist;
1995 FRAME_PTR f;
1996 int height, width;
1997 struct gcpro gcpro1;
1998
1999 if (EQ (frame, Qnil))
2000 frame = selected_frame;
2001
2002 CHECK_FRAME (frame, 0);
2003 f = XFRAME (frame);
2004
2005 if (!FRAME_LIVE_P (f))
2006 return Qnil;
2007
2008 alist = Fcopy_alist (f->param_alist);
2009 GCPRO1 (alist);
2010
2011 if (!FRAME_WINDOW_P (f))
2012 {
2013 int fg = FRAME_FOREGROUND_PIXEL (f);
2014 int bg = FRAME_BACKGROUND_PIXEL (f);
2015
2016 store_in_alist (&alist, intern ("foreground-color"),
2017 tty_color_name (f, fg));
2018 store_in_alist (&alist, intern ("background-color"),
2019 tty_color_name (f, bg));
2020 store_in_alist (&alist, intern ("font"),
2021 build_string (FRAME_MSDOS_P (f)
2022 ? "ms-dos"
2023 : FRAME_W32_P (f) ? "w32term" : "tty"));
2024 }
2025 store_in_alist (&alist, Qname, f->name);
2026 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2027 store_in_alist (&alist, Qheight, make_number (height));
2028 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2029 store_in_alist (&alist, Qwidth, make_number (width));
2030 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2031 store_in_alist (&alist, Qminibuffer,
2032 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2033 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2034 : FRAME_MINIBUF_WINDOW (f)));
2035 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2036 store_in_alist (&alist, Qbuffer_list,
2037 frame_buffer_list (selected_frame));
2038
2039 /* I think this should be done with a hook. */
2040 #ifdef HAVE_WINDOW_SYSTEM
2041 if (FRAME_WINDOW_P (f))
2042 x_report_frame_params (f, &alist);
2043 else
2044 #endif
2045 {
2046 /* This ought to be correct in f->param_alist for an X frame. */
2047 Lisp_Object lines;
2048 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2049 store_in_alist (&alist, Qmenu_bar_lines, lines);
2050 }
2051
2052 UNGCPRO;
2053 return alist;
2054 }
2055
2056 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2057 Smodify_frame_parameters, 2, 2, 0,
2058 "Modify the parameters of frame FRAME according to ALIST.\n\
2059 ALIST is an alist of parameters to change and their new values.\n\
2060 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2061 The meaningful PARMs depend on the kind of frame.\n\
2062 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2063 so that `frame-parameters' will return them.")
2064 (frame, alist)
2065 Lisp_Object frame, alist;
2066 {
2067 FRAME_PTR f;
2068 register Lisp_Object tail, prop, val;
2069
2070 if (EQ (frame, Qnil))
2071 frame = selected_frame;
2072 CHECK_LIVE_FRAME (frame, 0);
2073 f = XFRAME (frame);
2074
2075 /* I think this should be done with a hook. */
2076 #ifdef HAVE_WINDOW_SYSTEM
2077 if (FRAME_WINDOW_P (f))
2078 x_set_frame_parameters (f, alist);
2079 else
2080 #endif
2081 #ifdef MSDOS
2082 if (FRAME_MSDOS_P (f))
2083 IT_set_frame_parameters (f, alist);
2084 else
2085 #endif
2086 #ifdef macintosh
2087 if (FRAME_MAC_P (f))
2088 mac_set_frame_parameters (f, alist);
2089 else
2090 #endif
2091
2092 {
2093 int length = XINT (Flength (alist));
2094 int i;
2095 Lisp_Object *parms
2096 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2097 Lisp_Object *values
2098 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2099
2100 /* Extract parm names and values into those vectors. */
2101
2102 i = 0;
2103 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2104 {
2105 Lisp_Object elt;
2106
2107 elt = Fcar (tail);
2108 parms[i] = Fcar (elt);
2109 values[i] = Fcdr (elt);
2110 i++;
2111 }
2112
2113 /* Now process them in reverse of specified order. */
2114 for (i--; i >= 0; i--)
2115 {
2116 prop = parms[i];
2117 val = values[i];
2118 store_frame_param (f, prop, val);
2119 }
2120 }
2121
2122 return Qnil;
2123 }
2124 \f
2125 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2126 0, 1, 0,
2127 "Height in pixels of a line in the font in frame FRAME.\n\
2128 If FRAME is omitted, the selected frame is used.\n\
2129 For a terminal frame, the value is always 1.")
2130 (frame)
2131 Lisp_Object frame;
2132 {
2133 struct frame *f;
2134
2135 if (NILP (frame))
2136 frame = selected_frame;
2137 CHECK_FRAME (frame, 0);
2138 f = XFRAME (frame);
2139
2140 #ifdef HAVE_WINDOW_SYSTEM
2141 if (FRAME_WINDOW_P (f))
2142 return make_number (x_char_height (f));
2143 else
2144 #endif
2145 return make_number (1);
2146 }
2147
2148
2149 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2150 0, 1, 0,
2151 "Width in pixels of characters in the font in frame FRAME.\n\
2152 If FRAME is omitted, the selected frame is used.\n\
2153 The width is the same for all characters, because\n\
2154 currently Emacs supports only fixed-width fonts.\n\
2155 For a terminal screen, the value is always 1.")
2156 (frame)
2157 Lisp_Object frame;
2158 {
2159 struct frame *f;
2160
2161 if (NILP (frame))
2162 frame = selected_frame;
2163 CHECK_FRAME (frame, 0);
2164 f = XFRAME (frame);
2165
2166 #ifdef HAVE_WINDOW_SYSTEM
2167 if (FRAME_WINDOW_P (f))
2168 return make_number (x_char_width (f));
2169 else
2170 #endif
2171 return make_number (1);
2172 }
2173
2174 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2175 Sframe_pixel_height, 0, 1, 0,
2176 "Return a FRAME's height in pixels.\n\
2177 This counts only the height available for text lines,\n\
2178 not menu bars on window-system Emacs frames.\n\
2179 For a terminal frame, the result really gives the height in characters.\n\
2180 If FRAME is omitted, the selected frame is used.")
2181 (frame)
2182 Lisp_Object frame;
2183 {
2184 struct frame *f;
2185
2186 if (NILP (frame))
2187 frame = selected_frame;
2188 CHECK_FRAME (frame, 0);
2189 f = XFRAME (frame);
2190
2191 #ifdef HAVE_WINDOW_SYSTEM
2192 if (FRAME_WINDOW_P (f))
2193 return make_number (x_pixel_height (f));
2194 else
2195 #endif
2196 return make_number (FRAME_HEIGHT (f));
2197 }
2198
2199 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2200 Sframe_pixel_width, 0, 1, 0,
2201 "Return FRAME's width in pixels.\n\
2202 For a terminal frame, the result really gives the width in characters.\n\
2203 If FRAME is omitted, the selected frame is used.")
2204 (frame)
2205 Lisp_Object frame;
2206 {
2207 struct frame *f;
2208
2209 if (NILP (frame))
2210 frame = selected_frame;
2211 CHECK_FRAME (frame, 0);
2212 f = XFRAME (frame);
2213
2214 #ifdef HAVE_WINDOW_SYSTEM
2215 if (FRAME_WINDOW_P (f))
2216 return make_number (x_pixel_width (f));
2217 else
2218 #endif
2219 return make_number (FRAME_WIDTH (f));
2220 }
2221 \f
2222 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2223 "Specify that the frame FRAME has LINES lines.\n\
2224 Optional third arg non-nil means that redisplay should use LINES lines\n\
2225 but that the idea of the actual height of the frame should not be changed.")
2226 (frame, lines, pretend)
2227 Lisp_Object frame, lines, pretend;
2228 {
2229 register struct frame *f;
2230
2231 CHECK_NUMBER (lines, 0);
2232 if (NILP (frame))
2233 frame = selected_frame;
2234 CHECK_LIVE_FRAME (frame, 0);
2235 f = XFRAME (frame);
2236
2237 /* I think this should be done with a hook. */
2238 #ifdef HAVE_WINDOW_SYSTEM
2239 if (FRAME_WINDOW_P (f))
2240 {
2241 if (XINT (lines) != f->height)
2242 x_set_window_size (f, 1, f->width, XINT (lines));
2243 do_pending_window_change (0);
2244 }
2245 else
2246 #endif
2247 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2248 return Qnil;
2249 }
2250
2251 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2252 "Specify that the frame FRAME has COLS columns.\n\
2253 Optional third arg non-nil means that redisplay should use COLS columns\n\
2254 but that the idea of the actual width of the frame should not be changed.")
2255 (frame, cols, pretend)
2256 Lisp_Object frame, cols, pretend;
2257 {
2258 register struct frame *f;
2259 CHECK_NUMBER (cols, 0);
2260 if (NILP (frame))
2261 frame = selected_frame;
2262 CHECK_LIVE_FRAME (frame, 0);
2263 f = XFRAME (frame);
2264
2265 /* I think this should be done with a hook. */
2266 #ifdef HAVE_WINDOW_SYSTEM
2267 if (FRAME_WINDOW_P (f))
2268 {
2269 if (XINT (cols) != f->width)
2270 x_set_window_size (f, 1, XINT (cols), f->height);
2271 do_pending_window_change (0);
2272 }
2273 else
2274 #endif
2275 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2276 return Qnil;
2277 }
2278
2279 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2280 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2281 (frame, cols, rows)
2282 Lisp_Object frame, cols, rows;
2283 {
2284 register struct frame *f;
2285
2286 CHECK_LIVE_FRAME (frame, 0);
2287 CHECK_NUMBER (cols, 2);
2288 CHECK_NUMBER (rows, 1);
2289 f = XFRAME (frame);
2290
2291 /* I think this should be done with a hook. */
2292 #ifdef HAVE_WINDOW_SYSTEM
2293 if (FRAME_WINDOW_P (f))
2294 {
2295 if (XINT (rows) != f->height || XINT (cols) != f->width
2296 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2297 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2298 do_pending_window_change (0);
2299 }
2300 else
2301 #endif
2302 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2303
2304 return Qnil;
2305 }
2306
2307 DEFUN ("set-frame-position", Fset_frame_position,
2308 Sset_frame_position, 3, 3, 0,
2309 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2310 This is actually the position of the upper left corner of the frame.\n\
2311 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2312 the rightmost or bottommost possible position (that stays within the screen).")
2313 (frame, xoffset, yoffset)
2314 Lisp_Object frame, xoffset, yoffset;
2315 {
2316 register struct frame *f;
2317
2318 CHECK_LIVE_FRAME (frame, 0);
2319 CHECK_NUMBER (xoffset, 1);
2320 CHECK_NUMBER (yoffset, 2);
2321 f = XFRAME (frame);
2322
2323 /* I think this should be done with a hook. */
2324 #ifdef HAVE_WINDOW_SYSTEM
2325 if (FRAME_WINDOW_P (f))
2326 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2327 #endif
2328
2329 return Qt;
2330 }
2331
2332 \f
2333 void
2334 syms_of_frame ()
2335 {
2336 syms_of_frame_1 ();
2337
2338 staticpro (&Vframe_list);
2339
2340 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2341 "The initial frame-object, which represents Emacs's stdout.");
2342
2343 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2344 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2345 Vemacs_iconified = Qnil;
2346
2347 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2348 "Minibufferless frames use this frame's minibuffer.\n\
2349 \n\
2350 Emacs cannot create minibufferless frames unless this is set to an\n\
2351 appropriate surrogate.\n\
2352 \n\
2353 Emacs consults this variable only when creating minibufferless\n\
2354 frames; once the frame is created, it sticks with its assigned\n\
2355 minibuffer, no matter what this variable is set to. This means that\n\
2356 this variable doesn't necessarily say anything meaningful about the\n\
2357 current set of frames, or where the minibuffer is currently being\n\
2358 displayed.");
2359
2360 defsubr (&Sactive_minibuffer_window);
2361 defsubr (&Sframep);
2362 defsubr (&Sframe_live_p);
2363 defsubr (&Smake_terminal_frame);
2364 defsubr (&Shandle_switch_frame);
2365 defsubr (&Signore_event);
2366 defsubr (&Sselect_frame);
2367 defsubr (&Sselected_frame);
2368 defsubr (&Swindow_frame);
2369 defsubr (&Sframe_root_window);
2370 defsubr (&Sframe_first_window);
2371 defsubr (&Sframe_selected_window);
2372 defsubr (&Sset_frame_selected_window);
2373 defsubr (&Sframe_list);
2374 defsubr (&Snext_frame);
2375 defsubr (&Sprevious_frame);
2376 defsubr (&Sdelete_frame);
2377 defsubr (&Smouse_position);
2378 defsubr (&Smouse_pixel_position);
2379 defsubr (&Sset_mouse_position);
2380 defsubr (&Sset_mouse_pixel_position);
2381 #if 0
2382 defsubr (&Sframe_configuration);
2383 defsubr (&Srestore_frame_configuration);
2384 #endif
2385 defsubr (&Smake_frame_visible);
2386 defsubr (&Smake_frame_invisible);
2387 defsubr (&Siconify_frame);
2388 defsubr (&Sframe_visible_p);
2389 defsubr (&Svisible_frame_list);
2390 defsubr (&Sraise_frame);
2391 defsubr (&Slower_frame);
2392 defsubr (&Sredirect_frame_focus);
2393 defsubr (&Sframe_focus);
2394 defsubr (&Sframe_parameters);
2395 defsubr (&Smodify_frame_parameters);
2396 defsubr (&Sframe_char_height);
2397 defsubr (&Sframe_char_width);
2398 defsubr (&Sframe_pixel_height);
2399 defsubr (&Sframe_pixel_width);
2400 defsubr (&Sset_frame_height);
2401 defsubr (&Sset_frame_width);
2402 defsubr (&Sset_frame_size);
2403 defsubr (&Sset_frame_position);
2404 }
2405
2406 void
2407 keys_of_frame ()
2408 {
2409 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2410 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2411 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2412 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2413 }