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