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