(Rmail Display): Document rmail-redecode-body.
[emacs.git] / src / frame.c
blobfae6f8c7b3d3063406082c1c0a153e2d7d2a7efe
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000 Free Software Foundation.
4 This file is part of GNU Emacs.
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.
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.
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. */
21 #include <config.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "charset.h"
26 #ifdef HAVE_X_WINDOWS
27 #include "xterm.h"
28 #endif
29 #ifdef WINDOWSNT
30 #include "w32term.h"
31 #endif
32 #ifdef macintosh
33 #include "macterm.h"
34 #endif
35 #include "buffer.h"
36 /* These help us bind and responding to switch-frame events. */
37 #include "commands.h"
38 #include "keyboard.h"
39 #include "frame.h"
40 #ifdef HAVE_WINDOW_SYSTEM
41 #include "fontset.h"
42 #endif
43 #include "termhooks.h"
44 #include "dispextern.h"
45 #include "window.h"
46 #ifdef MSDOS
47 #include "msdos.h"
48 #include "dosfns.h"
49 #endif
51 Lisp_Object Qframep;
52 Lisp_Object Qframe_live_p;
53 Lisp_Object Qheight;
54 Lisp_Object Qicon;
55 Lisp_Object Qminibuffer;
56 Lisp_Object Qmodeline;
57 Lisp_Object Qname;
58 Lisp_Object Qonly;
59 Lisp_Object Qunsplittable;
60 Lisp_Object Qmenu_bar_lines;
61 Lisp_Object Qtool_bar_lines;
62 Lisp_Object Qwidth;
63 Lisp_Object Qx;
64 Lisp_Object Qw32;
65 Lisp_Object Qpc;
66 Lisp_Object Qmac;
67 Lisp_Object Qvisible;
68 Lisp_Object Qbuffer_predicate;
69 Lisp_Object Qbuffer_list;
70 Lisp_Object Qtitle;
71 Lisp_Object Qdisplay_type;
72 Lisp_Object Qbackground_mode;
73 Lisp_Object Qinhibit_default_face_x_resources;
75 Lisp_Object Vterminal_frame;
76 Lisp_Object Vdefault_frame_alist;
77 Lisp_Object Vmouse_position_function;
79 static void
80 set_menu_bar_lines_1 (window, n)
81 Lisp_Object window;
82 int n;
84 struct window *w = XWINDOW (window);
86 XSETFASTINT (w->last_modified, 0);
87 XSETFASTINT (w->top, XFASTINT (w->top) + n);
88 XSETFASTINT (w->height, XFASTINT (w->height) - n);
90 if (INTEGERP (w->orig_top))
91 XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
92 if (INTEGERP (w->orig_height))
93 XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
95 /* Handle just the top child in a vertical split. */
96 if (!NILP (w->vchild))
97 set_menu_bar_lines_1 (w->vchild, n);
99 /* Adjust all children in a horizontal split. */
100 for (window = w->hchild; !NILP (window); window = w->next)
102 w = XWINDOW (window);
103 set_menu_bar_lines_1 (window, n);
107 void
108 set_menu_bar_lines (f, value, oldval)
109 struct frame *f;
110 Lisp_Object value, oldval;
112 int nlines;
113 int olines = FRAME_MENU_BAR_LINES (f);
115 /* Right now, menu bars don't work properly in minibuf-only frames;
116 most of the commands try to apply themselves to the minibuffer
117 frame itself, and get an error because you can't switch buffers
118 in or split the minibuffer window. */
119 if (FRAME_MINIBUF_ONLY_P (f))
120 return;
122 if (INTEGERP (value))
123 nlines = XINT (value);
124 else
125 nlines = 0;
127 if (nlines != olines)
129 windows_or_buffers_changed++;
130 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
131 FRAME_MENU_BAR_LINES (f) = nlines;
132 set_menu_bar_lines_1 (f->root_window, nlines - olines);
133 adjust_glyphs (f);
137 Lisp_Object Vemacs_iconified;
138 Lisp_Object Vframe_list;
140 struct x_output tty_display;
142 extern Lisp_Object Vminibuffer_list;
143 extern Lisp_Object get_minibuffer ();
144 extern Lisp_Object Fhandle_switch_frame ();
145 extern Lisp_Object Fredirect_frame_focus ();
146 extern Lisp_Object x_get_focus_frame ();
148 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
149 "Return non-nil if OBJECT is a frame.\n\
150 Value is t for a termcap frame (a character-only terminal),\n\
151 `x' for an Emacs frame that is really an X window,\n\
152 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
153 `mac' for an Emacs frame on a Macintosh display,\n\
154 `pc' for a direct-write MS-DOS frame.\n\
155 See also `frame-live-p'.")
156 (object)
157 Lisp_Object object;
159 if (!FRAMEP (object))
160 return Qnil;
161 switch (XFRAME (object)->output_method)
163 case output_termcap:
164 return Qt;
165 case output_x_window:
166 return Qx;
167 case output_w32:
168 return Qw32;
169 case output_msdos_raw:
170 return Qpc;
171 case output_mac:
172 return Qmac;
173 default:
174 abort ();
178 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
179 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
180 Value is nil if OBJECT is not a live frame. If object is a live\n\
181 frame, the return value indicates what sort of output device it is\n\
182 displayed on. Value is t for a termcap frame (a character-only\n\
183 terminal), `x' for an Emacs frame being displayed in an X window.")
184 (object)
185 Lisp_Object object;
187 return ((FRAMEP (object)
188 && FRAME_LIVE_P (XFRAME (object)))
189 ? Fframep (object)
190 : Qnil);
193 struct frame *
194 make_frame (mini_p)
195 int mini_p;
197 Lisp_Object frame;
198 register struct frame *f;
199 register Lisp_Object root_window;
200 register Lisp_Object mini_window;
201 register struct Lisp_Vector *vec;
202 int i;
204 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
205 for (i = 0; i < VECSIZE (struct frame); i++)
206 XSETFASTINT (vec->contents[i], 0);
207 vec->size = VECSIZE (struct frame);
208 f = (struct frame *)vec;
209 XSETFRAME (frame, f);
211 f->desired_matrix = 0;
212 f->current_matrix = 0;
213 f->desired_pool = 0;
214 f->current_pool = 0;
215 f->glyphs_initialized_p = 0;
216 f->decode_mode_spec_buffer = 0;
217 f->visible = 0;
218 f->async_visible = 0;
219 f->output_data.nothing = 0;
220 f->iconified = 0;
221 f->async_iconified = 0;
222 f->wants_modeline = 1;
223 f->auto_raise = 0;
224 f->auto_lower = 0;
225 f->no_split = 0;
226 f->garbaged = 1;
227 f->has_minibuffer = mini_p;
228 f->focus_frame = Qnil;
229 f->explicit_name = 0;
230 f->can_have_scroll_bars = 0;
231 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
232 f->param_alist = Qnil;
233 f->scroll_bars = Qnil;
234 f->condemned_scroll_bars = Qnil;
235 f->face_alist = Qnil;
236 f->face_cache = NULL;
237 f->menu_bar_items = Qnil;
238 f->menu_bar_vector = Qnil;
239 f->menu_bar_items_used = 0;
240 f->buffer_predicate = Qnil;
241 f->buffer_list = Qnil;
242 #ifdef MULTI_KBOARD
243 f->kboard = initial_kboard;
244 #endif
245 f->namebuf = 0;
246 f->title = Qnil;
247 f->menu_bar_window = Qnil;
248 f->tool_bar_window = Qnil;
249 f->tool_bar_items = Qnil;
250 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
251 f->n_tool_bar_items = 0;
253 root_window = make_window ();
254 if (mini_p)
256 mini_window = make_window ();
257 XWINDOW (root_window)->next = mini_window;
258 XWINDOW (mini_window)->prev = root_window;
259 XWINDOW (mini_window)->mini_p = Qt;
260 XWINDOW (mini_window)->frame = frame;
261 f->minibuffer_window = mini_window;
263 else
265 mini_window = Qnil;
266 XWINDOW (root_window)->next = Qnil;
267 f->minibuffer_window = Qnil;
270 XWINDOW (root_window)->frame = frame;
272 /* 10 is arbitrary,
273 just so that there is "something there."
274 Correct size will be set up later with change_frame_size. */
276 SET_FRAME_WIDTH (f, 10);
277 f->height = 10;
279 XSETFASTINT (XWINDOW (root_window)->width, 10);
280 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
282 if (mini_p)
284 XSETFASTINT (XWINDOW (mini_window)->width, 10);
285 XSETFASTINT (XWINDOW (mini_window)->top, 9);
286 XSETFASTINT (XWINDOW (mini_window)->height, 1);
289 /* Choose a buffer for the frame's root window. */
291 Lisp_Object buf;
293 XWINDOW (root_window)->buffer = Qt;
294 buf = Fcurrent_buffer ();
295 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
296 a space), try to find another one. */
297 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
298 buf = Fother_buffer (buf, Qnil, Qnil);
300 /* Use set_window_buffer, not Fset_window_buffer, and don't let
301 hooks be run by it. The reason is that the whole frame/window
302 arrangement is not yet fully intialized at this point. Windows
303 don't have the right size, glyph matrices aren't initialized
304 etc. Running Lisp functions at this point surely ends in a
305 SEGV. */
306 set_window_buffer (root_window, buf, 0);
307 f->buffer_list = Fcons (buf, Qnil);
310 if (mini_p)
312 XWINDOW (mini_window)->buffer = Qt;
313 set_window_buffer (mini_window,
314 (NILP (Vminibuffer_list)
315 ? get_minibuffer (0)
316 : Fcar (Vminibuffer_list)),
320 f->root_window = root_window;
321 f->selected_window = root_window;
322 /* Make sure this window seems more recently used than
323 a newly-created, never-selected window. */
324 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
326 return f;
329 #ifdef HAVE_WINDOW_SYSTEM
330 /* Make a frame using a separate minibuffer window on another frame.
331 MINI_WINDOW is the minibuffer window to use. nil means use the
332 default (the global minibuffer). */
334 struct frame *
335 make_frame_without_minibuffer (mini_window, kb, display)
336 register Lisp_Object mini_window;
337 KBOARD *kb;
338 Lisp_Object display;
340 register struct frame *f;
341 struct gcpro gcpro1;
343 if (!NILP (mini_window))
344 CHECK_LIVE_WINDOW (mini_window, 0);
346 #ifdef MULTI_KBOARD
347 if (!NILP (mini_window)
348 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
349 error ("frame and minibuffer must be on the same display");
350 #endif
352 /* Make a frame containing just a root window. */
353 f = make_frame (0);
355 if (NILP (mini_window))
357 /* Use default-minibuffer-frame if possible. */
358 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
359 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
361 Lisp_Object frame_dummy;
363 XSETFRAME (frame_dummy, f);
364 GCPRO1 (frame_dummy);
365 /* If there's no minibuffer frame to use, create one. */
366 kb->Vdefault_minibuffer_frame =
367 call1 (intern ("make-initial-minibuffer-frame"), display);
368 UNGCPRO;
371 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
374 f->minibuffer_window = mini_window;
376 /* Make the chosen minibuffer window display the proper minibuffer,
377 unless it is already showing a minibuffer. */
378 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
379 Fset_window_buffer (mini_window,
380 (NILP (Vminibuffer_list)
381 ? get_minibuffer (0)
382 : Fcar (Vminibuffer_list)));
383 return f;
386 /* Make a frame containing only a minibuffer window. */
388 struct frame *
389 make_minibuffer_frame ()
391 /* First make a frame containing just a root window, no minibuffer. */
393 register struct frame *f = make_frame (0);
394 register Lisp_Object mini_window;
395 register Lisp_Object frame;
397 XSETFRAME (frame, f);
399 f->auto_raise = 0;
400 f->auto_lower = 0;
401 f->no_split = 1;
402 f->wants_modeline = 0;
403 f->has_minibuffer = 1;
405 /* Now label the root window as also being the minibuffer.
406 Avoid infinite looping on the window chain by marking next pointer
407 as nil. */
409 mini_window = f->minibuffer_window = f->root_window;
410 XWINDOW (mini_window)->mini_p = Qt;
411 XWINDOW (mini_window)->next = Qnil;
412 XWINDOW (mini_window)->prev = Qnil;
413 XWINDOW (mini_window)->frame = frame;
415 /* Put the proper buffer in that window. */
417 Fset_window_buffer (mini_window,
418 (NILP (Vminibuffer_list)
419 ? get_minibuffer (0)
420 : Fcar (Vminibuffer_list)));
421 return f;
423 #endif /* HAVE_WINDOW_SYSTEM */
425 /* Construct a frame that refers to the terminal (stdin and stdout). */
427 static int terminal_frame_count;
429 struct frame *
430 make_terminal_frame ()
432 register struct frame *f;
433 Lisp_Object frame;
434 char name[20];
436 #ifdef MULTI_KBOARD
437 if (!initial_kboard)
439 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
440 init_kboard (initial_kboard);
441 initial_kboard->next_kboard = all_kboards;
442 all_kboards = initial_kboard;
444 #endif
446 /* The first call must initialize Vframe_list. */
447 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
448 Vframe_list = Qnil;
450 f = make_frame (1);
452 XSETFRAME (frame, f);
453 Vframe_list = Fcons (frame, Vframe_list);
455 terminal_frame_count++;
456 sprintf (name, "F%d", terminal_frame_count);
457 f->name = build_string (name);
459 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
460 f->async_visible = 1; /* Don't let visible be cleared later. */
461 #ifdef MSDOS
462 f->output_data.x = &the_only_x_display;
463 if (!inhibit_window_system
464 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
465 || XFRAME (selected_frame)->output_method == output_msdos_raw))
467 f->output_method = output_msdos_raw;
468 /* This initialization of foreground and background pixels is
469 only important for the initial frame created in temacs. If
470 we don't do that, we get black background and foreground in
471 the dumped Emacs because the_only_x_display is a static
472 variable, hence it is born all-zeroes, and zero is the code
473 for the black color. Other frames all inherit their pixels
474 from what's already in the_only_x_display. */
475 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
476 && f->output_data.x->background_pixel == 0
477 && f->output_data.x->foreground_pixel == 0)
479 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
480 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
483 else
484 f->output_method = output_termcap;
485 #else
486 #ifdef WINDOWSNT
487 f->output_method = output_termcap;
488 f->output_data.x = &tty_display;
489 #else
490 #ifdef macintosh
491 make_mac_terminal_frame (f);
492 #else
493 f->output_data.x = &tty_display;
494 #endif /* macintosh */
495 #endif /* WINDOWSNT */
496 #endif /* MSDOS */
498 if (!noninteractive)
499 init_frame_faces (f);
501 return f;
504 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
505 1, 1, 0, "Create an additional terminal frame.\n\
506 You can create multiple frames on a text-only terminal in this way.\n\
507 Only the selected terminal frame is actually displayed.\n\
508 This function takes one argument, an alist specifying frame parameters.\n\
509 In practice, generally you don't need to specify any parameters.\n\
510 Note that changing the size of one terminal frame automatically affects all.")
511 (parms)
512 Lisp_Object parms;
514 struct frame *f;
515 Lisp_Object frame, tem;
516 struct frame *sf = SELECTED_FRAME ();
518 #ifdef MSDOS
519 if (sf->output_method != output_msdos_raw
520 && sf->output_method != output_termcap)
521 abort ();
522 #else /* not MSDOS */
524 #ifdef macintosh
525 if (sf->output_method != output_mac)
526 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
527 #else
528 if (sf->output_method != output_termcap)
529 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
530 #endif
531 #endif /* not MSDOS */
533 f = make_terminal_frame ();
535 change_frame_size (f, FRAME_HEIGHT (sf),
536 FRAME_WIDTH (sf), 0, 0, 0);
537 adjust_glyphs (f);
538 calculate_costs (f);
539 XSETFRAME (frame, f);
540 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
541 Fmodify_frame_parameters (frame, parms);
543 /* Make the frame face alist be frame-specific, so that each
544 frame could change its face definitions independently. */
545 f->face_alist = Fcopy_alist (sf->face_alist);
546 /* Simple Fcopy_alist isn't enough, because we need the contents of
547 the vectors which are the CDRs of associations in face_alist to
548 be copied as well. */
549 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
550 XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
551 return frame;
554 Lisp_Object
555 do_switch_frame (frame, no_enter, track)
556 Lisp_Object frame, no_enter;
557 int track;
559 struct frame *sf = SELECTED_FRAME ();
561 /* If FRAME is a switch-frame event, extract the frame we should
562 switch to. */
563 if (CONSP (frame)
564 && EQ (XCAR (frame), Qswitch_frame)
565 && CONSP (XCDR (frame)))
566 frame = XCAR (XCDR (frame));
568 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
569 a switch-frame event to arrive after a frame is no longer live,
570 especially when deleting the initial frame during startup. */
571 CHECK_FRAME (frame, 0);
572 if (! FRAME_LIVE_P (XFRAME (frame)))
573 return Qnil;
575 if (sf == XFRAME (frame))
576 return frame;
578 /* This is too greedy; it causes inappropriate focus redirection
579 that's hard to get rid of. */
580 #if 0
581 /* If a frame's focus has been redirected toward the currently
582 selected frame, we should change the redirection to point to the
583 newly selected frame. This means that if the focus is redirected
584 from a minibufferless frame to a surrogate minibuffer frame, we
585 can use `other-window' to switch between all the frames using
586 that minibuffer frame, and the focus redirection will follow us
587 around. */
588 if (track)
590 Lisp_Object tail;
592 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
594 Lisp_Object focus;
596 if (!FRAMEP (XCAR (tail)))
597 abort ();
599 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
601 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
602 Fredirect_frame_focus (XCAR (tail), frame);
605 #else /* ! 0 */
606 /* Instead, apply it only to the frame we're pointing to. */
607 #ifdef HAVE_WINDOW_SYSTEM
608 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
610 Lisp_Object focus, xfocus;
612 xfocus = x_get_focus_frame (XFRAME (frame));
613 if (FRAMEP (xfocus))
615 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
616 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
617 Fredirect_frame_focus (xfocus, frame);
620 #endif /* HAVE_X_WINDOWS */
621 #endif /* ! 0 */
623 selected_frame = frame;
624 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
625 last_nonminibuf_frame = XFRAME (selected_frame);
627 Fselect_window (XFRAME (frame)->selected_window);
629 /* We want to make sure that the next event generates a frame-switch
630 event to the appropriate frame. This seems kludgy to me, but
631 before you take it out, make sure that evaluating something like
632 (select-window (frame-root-window (new-frame))) doesn't end up
633 with your typing being interpreted in the new frame instead of
634 the one you're actually typing in. */
635 internal_last_event_frame = Qnil;
637 return frame;
640 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
641 "Select the frame FRAME.\n\
642 Subsequent editing commands apply to its selected window.\n\
643 The selection of FRAME lasts until the next time the user does\n\
644 something to select a different frame, or until the next time this\n\
645 function is called.")
646 (frame, no_enter)
647 Lisp_Object frame, no_enter;
649 return do_switch_frame (frame, no_enter, 1);
653 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
654 "Handle a switch-frame event EVENT.\n\
655 Switch-frame events are usually bound to this function.\n\
656 A switch-frame event tells Emacs that the window manager has requested\n\
657 that the user's events be directed to the frame mentioned in the event.\n\
658 This function selects the selected window of the frame of EVENT.\n\
660 If EVENT is frame object, handle it as if it were a switch-frame event\n\
661 to that frame.")
662 (event, no_enter)
663 Lisp_Object event, no_enter;
665 /* Preserve prefix arg that the command loop just cleared. */
666 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
667 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
668 return do_switch_frame (event, no_enter, 0);
671 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
672 "Do nothing, but preserve any prefix argument already specified.\n\
673 This is a suitable binding for iconify-frame and make-frame-visible.")
676 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
677 return Qnil;
680 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
681 "Return the frame that is now selected.")
684 return selected_frame;
687 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
688 "Return the frame object that window WINDOW is on.")
689 (window)
690 Lisp_Object window;
692 CHECK_LIVE_WINDOW (window, 0);
693 return XWINDOW (window)->frame;
696 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
697 "Returns the topmost, leftmost window of FRAME.\n\
698 If omitted, FRAME defaults to the currently selected frame.")
699 (frame)
700 Lisp_Object frame;
702 Lisp_Object w;
704 if (NILP (frame))
705 w = SELECTED_FRAME ()->root_window;
706 else
708 CHECK_LIVE_FRAME (frame, 0);
709 w = XFRAME (frame)->root_window;
711 while (NILP (XWINDOW (w)->buffer))
713 if (! NILP (XWINDOW (w)->hchild))
714 w = XWINDOW (w)->hchild;
715 else if (! NILP (XWINDOW (w)->vchild))
716 w = XWINDOW (w)->vchild;
717 else
718 abort ();
720 return w;
723 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
724 Sactive_minibuffer_window, 0, 0, 0,
725 "Return the currently active minibuffer window, or nil if none.")
728 return minibuf_level ? minibuf_window : Qnil;
731 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
732 "Returns the root-window of FRAME.\n\
733 If omitted, FRAME defaults to the currently selected frame.")
734 (frame)
735 Lisp_Object frame;
737 Lisp_Object window;
739 if (NILP (frame))
740 window = SELECTED_FRAME ()->root_window;
741 else
743 CHECK_LIVE_FRAME (frame, 0);
744 window = XFRAME (frame)->root_window;
747 return window;
750 DEFUN ("frame-selected-window", Fframe_selected_window,
751 Sframe_selected_window, 0, 1, 0,
752 "Return the selected window of frame object FRAME.\n\
753 If omitted, FRAME defaults to the currently selected frame.")
754 (frame)
755 Lisp_Object frame;
757 Lisp_Object window;
759 if (NILP (frame))
760 window = SELECTED_FRAME ()->selected_window;
761 else
763 CHECK_LIVE_FRAME (frame, 0);
764 window = XFRAME (frame)->selected_window;
767 return window;
770 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
771 Sset_frame_selected_window, 2, 2, 0,
772 "Set the selected window of frame object FRAME to WINDOW.\n\
773 If FRAME is nil, the selected frame is used.\n\
774 If FRAME is the selected frame, this makes WINDOW the selected window.")
775 (frame, window)
776 Lisp_Object frame, window;
778 if (NILP (frame))
779 frame = selected_frame;
781 CHECK_LIVE_FRAME (frame, 0);
782 CHECK_LIVE_WINDOW (window, 1);
784 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
785 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
787 if (EQ (frame, selected_frame))
788 return Fselect_window (window);
790 return XFRAME (frame)->selected_window = window;
793 DEFUN ("frame-list", Fframe_list, Sframe_list,
794 0, 0, 0,
795 "Return a list of all frames.")
798 return Fcopy_sequence (Vframe_list);
801 /* Return the next frame in the frame list after FRAME.
802 If MINIBUF is nil, exclude minibuffer-only frames.
803 If MINIBUF is a window, include only its own frame
804 and any frame now using that window as the minibuffer.
805 If MINIBUF is `visible', include all visible frames.
806 If MINIBUF is 0, include all visible and iconified frames.
807 Otherwise, include all frames. */
809 Lisp_Object
810 next_frame (frame, minibuf)
811 Lisp_Object frame;
812 Lisp_Object minibuf;
814 Lisp_Object tail;
815 int passed = 0;
817 /* There must always be at least one frame in Vframe_list. */
818 if (! CONSP (Vframe_list))
819 abort ();
821 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
822 forever. Forestall that. */
823 CHECK_LIVE_FRAME (frame, 0);
825 while (1)
826 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
828 Lisp_Object f;
830 f = XCAR (tail);
832 if (passed
833 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
835 /* Decide whether this frame is eligible to be returned. */
837 /* If we've looped all the way around without finding any
838 eligible frames, return the original frame. */
839 if (EQ (f, frame))
840 return f;
842 /* Let minibuf decide if this frame is acceptable. */
843 if (NILP (minibuf))
845 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
846 return f;
848 else if (EQ (minibuf, Qvisible))
850 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
851 if (FRAME_VISIBLE_P (XFRAME (f)))
852 return f;
854 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
856 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
857 if (FRAME_VISIBLE_P (XFRAME (f))
858 || FRAME_ICONIFIED_P (XFRAME (f)))
859 return f;
861 else if (WINDOWP (minibuf))
863 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
864 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
865 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
866 FRAME_FOCUS_FRAME (XFRAME (f))))
867 return f;
869 else
870 return f;
873 if (EQ (frame, f))
874 passed++;
878 /* Return the previous frame in the frame list before FRAME.
879 If MINIBUF is nil, exclude minibuffer-only frames.
880 If MINIBUF is a window, include only its own frame
881 and any frame now using that window as the minibuffer.
882 If MINIBUF is `visible', include all visible frames.
883 If MINIBUF is 0, include all visible and iconified frames.
884 Otherwise, include all frames. */
886 Lisp_Object
887 prev_frame (frame, minibuf)
888 Lisp_Object frame;
889 Lisp_Object minibuf;
891 Lisp_Object tail;
892 Lisp_Object prev;
894 /* There must always be at least one frame in Vframe_list. */
895 if (! CONSP (Vframe_list))
896 abort ();
898 prev = Qnil;
899 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
901 Lisp_Object f;
903 f = XCAR (tail);
904 if (!FRAMEP (f))
905 abort ();
907 if (EQ (frame, f) && !NILP (prev))
908 return prev;
910 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
912 /* Decide whether this frame is eligible to be returned,
913 according to minibuf. */
914 if (NILP (minibuf))
916 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
917 prev = f;
919 else if (WINDOWP (minibuf))
921 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
922 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
923 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
924 FRAME_FOCUS_FRAME (XFRAME (f))))
925 prev = f;
927 else if (EQ (minibuf, Qvisible))
929 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
930 if (FRAME_VISIBLE_P (XFRAME (f)))
931 prev = f;
933 else if (XFASTINT (minibuf) == 0)
935 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
936 if (FRAME_VISIBLE_P (XFRAME (f))
937 || FRAME_ICONIFIED_P (XFRAME (f)))
938 prev = f;
940 else
941 prev = f;
945 /* We've scanned the entire list. */
946 if (NILP (prev))
947 /* We went through the whole frame list without finding a single
948 acceptable frame. Return the original frame. */
949 return frame;
950 else
951 /* There were no acceptable frames in the list before FRAME; otherwise,
952 we would have returned directly from the loop. Since PREV is the last
953 acceptable frame in the list, return it. */
954 return prev;
958 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
959 "Return the next frame in the frame list after FRAME.\n\
960 It considers only frames on the same terminal as FRAME.\n\
961 By default, skip minibuffer-only frames.\n\
962 If omitted, FRAME defaults to the selected frame.\n\
963 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
964 If MINIFRAME is a window, include only its own frame\n\
965 and any frame now using that window as the minibuffer.\n\
966 If MINIFRAME is `visible', include all visible frames.\n\
967 If MINIFRAME is 0, include all visible and iconified frames.\n\
968 Otherwise, include all frames.")
969 (frame, miniframe)
970 Lisp_Object frame, miniframe;
972 if (NILP (frame))
973 frame = selected_frame;
975 CHECK_LIVE_FRAME (frame, 0);
976 return next_frame (frame, miniframe);
979 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
980 "Return the previous frame in the frame list before FRAME.\n\
981 It considers only frames on the same terminal as FRAME.\n\
982 By default, skip minibuffer-only frames.\n\
983 If omitted, FRAME defaults to the selected frame.\n\
984 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
985 If MINIFRAME is a window, include only its own frame\n\
986 and any frame now using that window as the minibuffer.\n\
987 If MINIFRAME is `visible', include all visible frames.\n\
988 If MINIFRAME is 0, include all visible and iconified frames.\n\
989 Otherwise, include all frames.")
990 (frame, miniframe)
991 Lisp_Object frame, miniframe;
993 if (NILP (frame))
994 frame = selected_frame;
995 CHECK_LIVE_FRAME (frame, 0);
996 return prev_frame (frame, miniframe);
999 /* Return 1 if it is ok to delete frame F;
1000 0 if all frames aside from F are invisible.
1001 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1004 other_visible_frames (f)
1005 FRAME_PTR f;
1007 /* We know the selected frame is visible,
1008 so if F is some other frame, it can't be the sole visible one. */
1009 if (f == SELECTED_FRAME ())
1011 Lisp_Object frames;
1012 int count = 0;
1014 for (frames = Vframe_list;
1015 CONSP (frames);
1016 frames = XCDR (frames))
1018 Lisp_Object this;
1020 this = XCAR (frames);
1021 /* Verify that the frame's window still exists
1022 and we can still talk to it. And note any recent change
1023 in visibility. */
1024 #ifdef HAVE_WINDOW_SYSTEM
1025 if (FRAME_WINDOW_P (XFRAME (this)))
1027 x_sync (XFRAME (this));
1028 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1030 #endif
1032 if (FRAME_VISIBLE_P (XFRAME (this))
1033 || FRAME_ICONIFIED_P (XFRAME (this))
1034 /* Allow deleting the terminal frame when at least
1035 one X frame exists! */
1036 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1037 count++;
1039 return count > 1;
1041 return 1;
1044 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1045 "Delete FRAME, permanently eliminating it from use.\n\
1046 If omitted, FRAME defaults to the selected frame.\n\
1047 A frame may not be deleted if its minibuffer is used by other frames.\n\
1048 Normally, you may not delete a frame if all other frames are invisible,\n\
1049 but if the second optional argument FORCE is non-nil, you may do so.\n\
1051 This function runs `delete-frame-hook' before actually deleting the\n\
1052 frame. The hook is called with one argument FRAME.")
1053 (frame, force)
1054 Lisp_Object frame, force;
1056 struct frame *f;
1057 struct frame *sf = SELECTED_FRAME ();
1058 int minibuffer_selected;
1060 if (EQ (frame, Qnil))
1062 f = sf;
1063 XSETFRAME (frame, f);
1065 else
1067 CHECK_FRAME (frame, 0);
1068 f = XFRAME (frame);
1071 if (! FRAME_LIVE_P (f))
1072 return Qnil;
1074 if (NILP (force) && !other_visible_frames (f))
1075 error ("Attempt to delete the sole visible or iconified frame");
1077 #if 0
1078 /* This is a nice idea, but x_connection_closed needs to be able
1079 to delete the last frame, if it is gone. */
1080 if (NILP (XCDR (Vframe_list)))
1081 error ("Attempt to delete the only frame");
1082 #endif
1084 /* Does this frame have a minibuffer, and is it the surrogate
1085 minibuffer for any other frame? */
1086 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1088 Lisp_Object frames;
1090 for (frames = Vframe_list;
1091 CONSP (frames);
1092 frames = XCDR (frames))
1094 Lisp_Object this;
1095 this = XCAR (frames);
1097 if (! EQ (this, frame)
1098 && EQ (frame,
1099 WINDOW_FRAME (XWINDOW
1100 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1101 error ("Attempt to delete a surrogate minibuffer frame");
1105 /* Run `delete-frame-hook'. */
1106 if (!NILP (Vrun_hooks))
1108 Lisp_Object args[2];
1109 args[0] = intern ("delete-frame-hook");
1110 args[1] = frame;
1111 Frun_hook_with_args (2, args);
1114 minibuffer_selected = EQ (minibuf_window, selected_window);
1116 /* Don't let the frame remain selected. */
1117 if (f == sf)
1119 Lisp_Object tail, frame1;
1121 /* Look for another visible frame on the same terminal. */
1122 frame1 = next_frame (frame, Qvisible);
1124 /* If there is none, find *some* other frame. */
1125 if (NILP (frame1) || EQ (frame1, frame))
1127 FOR_EACH_FRAME (tail, frame1)
1129 if (! EQ (frame, frame1))
1130 break;
1134 do_switch_frame (frame1, Qnil, 0);
1135 sf = SELECTED_FRAME ();
1138 /* Don't allow minibuf_window to remain on a deleted frame. */
1139 if (EQ (f->minibuffer_window, minibuf_window))
1141 Fset_window_buffer (sf->minibuffer_window,
1142 XWINDOW (minibuf_window)->buffer);
1143 minibuf_window = sf->minibuffer_window;
1145 /* If the dying minibuffer window was selected,
1146 select the new one. */
1147 if (minibuffer_selected)
1148 Fselect_window (minibuf_window);
1151 /* Don't let echo_area_window to remain on a deleted frame. */
1152 if (EQ (f->minibuffer_window, echo_area_window))
1153 echo_area_window = sf->minibuffer_window;
1155 /* Clear any X selections for this frame. */
1156 #ifdef HAVE_X_WINDOWS
1157 if (FRAME_X_P (f))
1158 x_clear_frame_selections (f);
1159 #endif
1161 /* Free glyphs.
1162 This function must be called before the window tree of the
1163 frame is deleted because windows contain dynamically allocated
1164 memory. */
1165 free_glyphs (f);
1167 /* Mark all the windows that used to be on FRAME as deleted, and then
1168 remove the reference to them. */
1169 delete_all_subwindows (XWINDOW (f->root_window));
1170 f->root_window = Qnil;
1172 Vframe_list = Fdelq (frame, Vframe_list);
1173 FRAME_SET_VISIBLE (f, 0);
1175 if (f->namebuf)
1176 xfree (f->namebuf);
1177 if (FRAME_INSERT_COST (f))
1178 xfree (FRAME_INSERT_COST (f));
1179 if (FRAME_DELETEN_COST (f))
1180 xfree (FRAME_DELETEN_COST (f));
1181 if (FRAME_INSERTN_COST (f))
1182 xfree (FRAME_INSERTN_COST (f));
1183 if (FRAME_DELETE_COST (f))
1184 xfree (FRAME_DELETE_COST (f));
1185 if (FRAME_MESSAGE_BUF (f))
1186 xfree (FRAME_MESSAGE_BUF (f));
1188 /* Since some events are handled at the interrupt level, we may get
1189 an event for f at any time; if we zero out the frame's display
1190 now, then we may trip up the event-handling code. Instead, we'll
1191 promise that the display of the frame must be valid until we have
1192 called the window-system-dependent frame destruction routine. */
1194 /* I think this should be done with a hook. */
1195 #ifdef HAVE_WINDOW_SYSTEM
1196 if (FRAME_WINDOW_P (f))
1197 x_destroy_window (f);
1198 #endif
1200 f->output_data.nothing = 0;
1202 /* If we've deleted the last_nonminibuf_frame, then try to find
1203 another one. */
1204 if (f == last_nonminibuf_frame)
1206 Lisp_Object frames;
1208 last_nonminibuf_frame = 0;
1210 for (frames = Vframe_list;
1211 CONSP (frames);
1212 frames = XCDR (frames))
1214 f = XFRAME (XCAR (frames));
1215 if (!FRAME_MINIBUF_ONLY_P (f))
1217 last_nonminibuf_frame = f;
1218 break;
1223 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1224 find another one. Prefer minibuffer-only frames, but also notice
1225 frames with other windows. */
1226 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1228 Lisp_Object frames;
1230 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1231 Lisp_Object frame_with_minibuf;
1232 /* Some frame we found on the same kboard, or nil if there are none. */
1233 Lisp_Object frame_on_same_kboard;
1235 frame_on_same_kboard = Qnil;
1236 frame_with_minibuf = Qnil;
1238 for (frames = Vframe_list;
1239 CONSP (frames);
1240 frames = XCDR (frames))
1242 Lisp_Object this;
1243 struct frame *f1;
1245 this = XCAR (frames);
1246 if (!FRAMEP (this))
1247 abort ();
1248 f1 = XFRAME (this);
1250 /* Consider only frames on the same kboard
1251 and only those with minibuffers. */
1252 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1253 && FRAME_HAS_MINIBUF_P (f1))
1255 frame_with_minibuf = this;
1256 if (FRAME_MINIBUF_ONLY_P (f1))
1257 break;
1260 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1261 frame_on_same_kboard = this;
1264 if (!NILP (frame_on_same_kboard))
1266 /* We know that there must be some frame with a minibuffer out
1267 there. If this were not true, all of the frames present
1268 would have to be minibufferless, which implies that at some
1269 point their minibuffer frames must have been deleted, but
1270 that is prohibited at the top; you can't delete surrogate
1271 minibuffer frames. */
1272 if (NILP (frame_with_minibuf))
1273 abort ();
1275 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1277 else
1278 /* No frames left on this kboard--say no minibuffer either. */
1279 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1282 /* Cause frame titles to update--necessary if we now have just one frame. */
1283 update_mode_lines = 1;
1285 return Qnil;
1288 /* Return mouse position in character cell units. */
1290 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1291 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1292 The position is given in character cells, where (0, 0) is the\n\
1293 upper-left corner.\n\
1294 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1295 to read the mouse position, it returns the selected frame for FRAME\n\
1296 and nil for X and Y.\n\
1297 Runs the abnormal hook `mouse-position-function' with the normal return\n\
1298 value as argument.")
1301 FRAME_PTR f;
1302 Lisp_Object lispy_dummy;
1303 enum scroll_bar_part party_dummy;
1304 Lisp_Object x, y, retval;
1305 int col, row;
1306 unsigned long long_dummy;
1307 struct gcpro gcpro1;
1309 f = SELECTED_FRAME ();
1310 x = y = Qnil;
1312 #ifdef HAVE_MOUSE
1313 /* It's okay for the hook to refrain from storing anything. */
1314 if (mouse_position_hook)
1315 (*mouse_position_hook) (&f, -1,
1316 &lispy_dummy, &party_dummy,
1317 &x, &y,
1318 &long_dummy);
1319 if (! NILP (x))
1321 col = XINT (x);
1322 row = XINT (y);
1323 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1324 XSETINT (x, col);
1325 XSETINT (y, row);
1327 #endif
1328 XSETFRAME (lispy_dummy, f);
1329 retval = Fcons (lispy_dummy, Fcons (x, y));
1330 GCPRO1 (retval);
1331 if (!NILP (Vmouse_position_function))
1332 retval = call1 (Vmouse_position_function, retval);
1333 RETURN_UNGCPRO (retval);
1336 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1337 Smouse_pixel_position, 0, 0, 0,
1338 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1339 The position is given in pixel units, where (0, 0) is the\n\
1340 upper-left corner.\n\
1341 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1342 to read the mouse position, it returns the selected frame for FRAME\n\
1343 and nil for X and Y.")
1346 FRAME_PTR f;
1347 Lisp_Object lispy_dummy;
1348 enum scroll_bar_part party_dummy;
1349 Lisp_Object x, y;
1350 unsigned long long_dummy;
1352 f = SELECTED_FRAME ();
1353 x = y = Qnil;
1355 #ifdef HAVE_MOUSE
1356 /* It's okay for the hook to refrain from storing anything. */
1357 if (mouse_position_hook)
1358 (*mouse_position_hook) (&f, -1,
1359 &lispy_dummy, &party_dummy,
1360 &x, &y,
1361 &long_dummy);
1362 #endif
1363 XSETFRAME (lispy_dummy, f);
1364 return Fcons (lispy_dummy, Fcons (x, y));
1367 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1368 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1369 Coordinates are relative to the frame, not a window,\n\
1370 so the coordinates of the top left character in the frame\n\
1371 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1373 This function is a no-op for an X frame that is not visible.\n\
1374 If you have just created a frame, you must wait for it to become visible\n\
1375 before calling this function on it, like this.\n\
1376 (while (not (frame-visible-p frame)) (sleep-for .5))")
1377 (frame, x, y)
1378 Lisp_Object frame, x, y;
1380 CHECK_LIVE_FRAME (frame, 0);
1381 CHECK_NUMBER (x, 2);
1382 CHECK_NUMBER (y, 1);
1384 /* I think this should be done with a hook. */
1385 #ifdef HAVE_WINDOW_SYSTEM
1386 if (FRAME_WINDOW_P (XFRAME (frame)))
1387 /* Warping the mouse will cause enternotify and focus events. */
1388 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1389 #else
1390 #if defined (MSDOS) && defined (HAVE_MOUSE)
1391 if (FRAME_MSDOS_P (XFRAME (frame)))
1393 Fselect_frame (frame, Qnil);
1394 mouse_moveto (XINT (x), XINT (y));
1396 #endif
1397 #endif
1399 return Qnil;
1402 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1403 Sset_mouse_pixel_position, 3, 3, 0,
1404 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1405 Note, this is a no-op for an X frame that is not visible.\n\
1406 If you have just created a frame, you must wait for it to become visible\n\
1407 before calling this function on it, like this.\n\
1408 (while (not (frame-visible-p frame)) (sleep-for .5))")
1409 (frame, x, y)
1410 Lisp_Object frame, x, y;
1412 CHECK_LIVE_FRAME (frame, 0);
1413 CHECK_NUMBER (x, 2);
1414 CHECK_NUMBER (y, 1);
1416 /* I think this should be done with a hook. */
1417 #ifdef HAVE_WINDOW_SYSTEM
1418 if (FRAME_WINDOW_P (XFRAME (frame)))
1419 /* Warping the mouse will cause enternotify and focus events. */
1420 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1421 #else
1422 #if defined (MSDOS) && defined (HAVE_MOUSE)
1423 if (FRAME_MSDOS_P (XFRAME (frame)))
1425 Fselect_frame (frame, Qnil);
1426 mouse_moveto (XINT (x), XINT (y));
1428 #endif
1429 #endif
1431 return Qnil;
1434 static void make_frame_visible_1 P_ ((Lisp_Object));
1436 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1437 0, 1, "",
1438 "Make the frame FRAME visible (assuming it is an X-window).\n\
1439 If omitted, FRAME defaults to the currently selected frame.")
1440 (frame)
1441 Lisp_Object frame;
1443 if (NILP (frame))
1444 frame = selected_frame;
1446 CHECK_LIVE_FRAME (frame, 0);
1448 /* I think this should be done with a hook. */
1449 #ifdef HAVE_WINDOW_SYSTEM
1450 if (FRAME_WINDOW_P (XFRAME (frame)))
1452 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1453 x_make_frame_visible (XFRAME (frame));
1455 #endif
1457 make_frame_visible_1 (XFRAME (frame)->root_window);
1459 /* Make menu bar update for the Buffers and Frams menus. */
1460 windows_or_buffers_changed++;
1462 return frame;
1465 /* Update the display_time slot of the buffers shown in WINDOW
1466 and all its descendents. */
1468 static void
1469 make_frame_visible_1 (window)
1470 Lisp_Object window;
1472 struct window *w;
1474 for (;!NILP (window); window = w->next)
1476 w = XWINDOW (window);
1478 if (!NILP (w->buffer))
1479 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1481 if (!NILP (w->vchild))
1482 make_frame_visible_1 (w->vchild);
1483 if (!NILP (w->hchild))
1484 make_frame_visible_1 (w->hchild);
1488 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1489 0, 2, "",
1490 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1491 If omitted, FRAME defaults to the currently selected frame.\n\
1492 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1493 but if the second optional argument FORCE is non-nil, you may do so.")
1494 (frame, force)
1495 Lisp_Object frame, force;
1497 if (NILP (frame))
1498 frame = selected_frame;
1500 CHECK_LIVE_FRAME (frame, 0);
1502 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1503 error ("Attempt to make invisible the sole visible or iconified frame");
1505 #if 0 /* This isn't logically necessary, and it can do GC. */
1506 /* Don't let the frame remain selected. */
1507 if (EQ (frame, selected_frame))
1508 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1509 #endif
1511 /* Don't allow minibuf_window to remain on a deleted frame. */
1512 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1514 struct frame *sf = XFRAME (selected_frame);
1515 Fset_window_buffer (sf->minibuffer_window,
1516 XWINDOW (minibuf_window)->buffer);
1517 minibuf_window = sf->minibuffer_window;
1520 /* I think this should be done with a hook. */
1521 #ifdef HAVE_WINDOW_SYSTEM
1522 if (FRAME_WINDOW_P (XFRAME (frame)))
1523 x_make_frame_invisible (XFRAME (frame));
1524 #endif
1526 /* Make menu bar update for the Buffers and Frams menus. */
1527 windows_or_buffers_changed++;
1529 return Qnil;
1532 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1533 0, 1, "",
1534 "Make the frame FRAME into an icon.\n\
1535 If omitted, FRAME defaults to the currently selected frame.")
1536 (frame)
1537 Lisp_Object frame;
1539 if (NILP (frame))
1540 frame = selected_frame;
1542 CHECK_LIVE_FRAME (frame, 0);
1544 #if 0 /* This isn't logically necessary, and it can do GC. */
1545 /* Don't let the frame remain selected. */
1546 if (EQ (frame, selected_frame))
1547 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1548 #endif
1550 /* Don't allow minibuf_window to remain on a deleted frame. */
1551 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1553 struct frame *sf = XFRAME (selected_frame);
1554 Fset_window_buffer (sf->minibuffer_window,
1555 XWINDOW (minibuf_window)->buffer);
1556 minibuf_window = sf->minibuffer_window;
1559 /* I think this should be done with a hook. */
1560 #ifdef HAVE_WINDOW_SYSTEM
1561 if (FRAME_WINDOW_P (XFRAME (frame)))
1562 x_iconify_frame (XFRAME (frame));
1563 #endif
1565 /* Make menu bar update for the Buffers and Frams menus. */
1566 windows_or_buffers_changed++;
1568 return Qnil;
1571 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1572 1, 1, 0,
1573 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1574 A frame that is not \"visible\" is not updated and, if it works through\n\
1575 a window system, it may not show at all.\n\
1576 Return the symbol `icon' if frame is visible only as an icon.")
1577 (frame)
1578 Lisp_Object frame;
1580 CHECK_LIVE_FRAME (frame, 0);
1582 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1584 if (FRAME_VISIBLE_P (XFRAME (frame)))
1585 return Qt;
1586 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1587 return Qicon;
1588 return Qnil;
1591 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1592 0, 0, 0,
1593 "Return a list of all frames now \"visible\" (being updated).")
1596 Lisp_Object tail, frame;
1597 struct frame *f;
1598 Lisp_Object value;
1600 value = Qnil;
1601 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1603 frame = XCAR (tail);
1604 if (!FRAMEP (frame))
1605 continue;
1606 f = XFRAME (frame);
1607 if (FRAME_VISIBLE_P (f))
1608 value = Fcons (frame, value);
1610 return value;
1614 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1615 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1616 If FRAME is invisible, make it visible.\n\
1617 If you don't specify a frame, the selected frame is used.\n\
1618 If Emacs is displaying on an ordinary terminal or some other device which\n\
1619 doesn't support multiple overlapping frames, this function does nothing.")
1620 (frame)
1621 Lisp_Object frame;
1623 if (NILP (frame))
1624 frame = selected_frame;
1626 CHECK_LIVE_FRAME (frame, 0);
1628 /* Do like the documentation says. */
1629 Fmake_frame_visible (frame);
1631 if (frame_raise_lower_hook)
1632 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1634 return Qnil;
1637 /* Should we have a corresponding function called Flower_Power? */
1638 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1639 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1640 If you don't specify a frame, the selected frame is used.\n\
1641 If Emacs is displaying on an ordinary terminal or some other device which\n\
1642 doesn't support multiple overlapping frames, this function does nothing.")
1643 (frame)
1644 Lisp_Object frame;
1646 if (NILP (frame))
1647 frame = selected_frame;
1649 CHECK_LIVE_FRAME (frame, 0);
1651 if (frame_raise_lower_hook)
1652 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1654 return Qnil;
1658 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1659 1, 2, 0,
1660 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1661 In other words, switch-frame events caused by events in FRAME will\n\
1662 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1663 FOCUS-FRAME after reading an event typed at FRAME.\n\
1665 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1666 cancelled, and the frame again receives its own keystrokes.\n\
1668 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1669 a surrogate minibuffer frame when a frame doesn't have its own\n\
1670 minibuffer window.\n\
1672 A frame's focus redirection can be changed by select-frame. If frame\n\
1673 FOO is selected, and then a different frame BAR is selected, any\n\
1674 frames redirecting their focus to FOO are shifted to redirect their\n\
1675 focus to BAR. This allows focus redirection to work properly when the\n\
1676 user switches from one frame to another using `select-window'.\n\
1678 This means that a frame whose focus is redirected to itself is treated\n\
1679 differently from a frame whose focus is redirected to nil; the former\n\
1680 is affected by select-frame, while the latter is not.\n\
1682 The redirection lasts until `redirect-frame-focus' is called to change it.")
1683 (frame, focus_frame)
1684 Lisp_Object frame, focus_frame;
1686 /* Note that we don't check for a live frame here. It's reasonable
1687 to redirect the focus of a frame you're about to delete, if you
1688 know what other frame should receive those keystrokes. */
1689 CHECK_FRAME (frame, 0);
1691 if (! NILP (focus_frame))
1692 CHECK_LIVE_FRAME (focus_frame, 1);
1694 XFRAME (frame)->focus_frame = focus_frame;
1696 if (frame_rehighlight_hook)
1697 (*frame_rehighlight_hook) (XFRAME (frame));
1699 return Qnil;
1703 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1704 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1705 This returns nil if FRAME's focus is not redirected.\n\
1706 See `redirect-frame-focus'.")
1707 (frame)
1708 Lisp_Object frame;
1710 CHECK_LIVE_FRAME (frame, 0);
1712 return FRAME_FOCUS_FRAME (XFRAME (frame));
1717 /* Return the value of frame parameter PROP in frame FRAME. */
1719 Lisp_Object
1720 get_frame_param (frame, prop)
1721 register struct frame *frame;
1722 Lisp_Object prop;
1724 register Lisp_Object tem;
1726 tem = Fassq (prop, frame->param_alist);
1727 if (EQ (tem, Qnil))
1728 return tem;
1729 return Fcdr (tem);
1732 /* Return the buffer-predicate of the selected frame. */
1734 Lisp_Object
1735 frame_buffer_predicate (frame)
1736 Lisp_Object frame;
1738 return XFRAME (frame)->buffer_predicate;
1741 /* Return the buffer-list of the selected frame. */
1743 Lisp_Object
1744 frame_buffer_list (frame)
1745 Lisp_Object frame;
1747 return XFRAME (frame)->buffer_list;
1750 /* Set the buffer-list of the selected frame. */
1752 void
1753 set_frame_buffer_list (frame, list)
1754 Lisp_Object frame, list;
1756 XFRAME (frame)->buffer_list = list;
1759 /* Discard BUFFER from the buffer-list of each frame. */
1761 void
1762 frames_discard_buffer (buffer)
1763 Lisp_Object buffer;
1765 Lisp_Object frame, tail;
1767 FOR_EACH_FRAME (tail, frame)
1769 XFRAME (frame)->buffer_list
1770 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1774 /* Move BUFFER to the end of the buffer-list of each frame. */
1776 void
1777 frames_bury_buffer (buffer)
1778 Lisp_Object buffer;
1780 Lisp_Object frame, tail;
1782 FOR_EACH_FRAME (tail, frame)
1784 struct frame *f = XFRAME (frame);
1785 Lisp_Object found;
1787 found = Fmemq (buffer, f->buffer_list);
1788 if (!NILP (found))
1789 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1790 Fcons (buffer, Qnil));
1794 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1795 If the alist already has an element for PROP, we change it. */
1797 void
1798 store_in_alist (alistptr, prop, val)
1799 Lisp_Object *alistptr, val;
1800 Lisp_Object prop;
1802 register Lisp_Object tem;
1804 tem = Fassq (prop, *alistptr);
1805 if (EQ (tem, Qnil))
1806 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1807 else
1808 Fsetcdr (tem, val);
1811 static int
1812 frame_name_fnn_p (str, len)
1813 char *str;
1814 int len;
1816 if (len > 1 && str[0] == 'F')
1818 char *end_ptr;
1820 strtol (str + 1, &end_ptr, 10);
1822 if (end_ptr == str + len)
1823 return 1;
1825 return 0;
1828 /* Set the name of the terminal frame. Also used by MSDOS frames.
1829 Modeled after x_set_name which is used for WINDOW frames. */
1831 void
1832 set_term_frame_name (f, name)
1833 struct frame *f;
1834 Lisp_Object name;
1836 f->explicit_name = ! NILP (name);
1838 /* If NAME is nil, set the name to F<num>. */
1839 if (NILP (name))
1841 char namebuf[20];
1843 /* Check for no change needed in this very common case
1844 before we do any consing. */
1845 if (frame_name_fnn_p (XSTRING (f->name)->data,
1846 STRING_BYTES (XSTRING (f->name))))
1847 return;
1849 terminal_frame_count++;
1850 sprintf (namebuf, "F%d", terminal_frame_count);
1851 name = build_string (namebuf);
1853 else
1855 CHECK_STRING (name, 0);
1857 /* Don't change the name if it's already NAME. */
1858 if (! NILP (Fstring_equal (name, f->name)))
1859 return;
1861 /* Don't allow the user to set the frame name to F<num>, so it
1862 doesn't clash with the names we generate for terminal frames. */
1863 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1864 error ("Frame names of the form F<num> are usurped by Emacs");
1867 f->name = name;
1868 update_mode_lines = 1;
1871 void
1872 store_frame_param (f, prop, val)
1873 struct frame *f;
1874 Lisp_Object prop, val;
1876 register Lisp_Object old_alist_elt;
1878 /* The buffer-alist parameter is stored in a special place and is
1879 not in the alist. */
1880 if (EQ (prop, Qbuffer_list))
1882 f->buffer_list = val;
1883 return;
1886 /* If PROP is a symbol which is supposed to have frame-local values,
1887 and it is set up based on this frame, switch to the global
1888 binding. That way, we can create or alter the frame-local binding
1889 without messing up the symbol's status. */
1890 if (SYMBOLP (prop))
1892 Lisp_Object valcontents;
1893 valcontents = XSYMBOL (prop)->value;
1894 if ((BUFFER_LOCAL_VALUEP (valcontents)
1895 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1896 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1897 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1898 swap_in_global_binding (prop);
1901 /* Update the frame parameter alist. */
1902 old_alist_elt = Fassq (prop, f->param_alist);
1903 if (EQ (old_alist_elt, Qnil))
1904 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1905 else
1906 Fsetcdr (old_alist_elt, val);
1908 /* Update some other special parameters in their special places
1909 in addition to the alist. */
1911 if (EQ (prop, Qbuffer_predicate))
1912 f->buffer_predicate = val;
1914 if (! FRAME_WINDOW_P (f))
1916 if (EQ (prop, Qmenu_bar_lines))
1917 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1918 else if (EQ (prop, Qname))
1919 set_term_frame_name (f, val);
1922 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1924 if (! MINI_WINDOW_P (XWINDOW (val)))
1925 error ("Surrogate minibuffer windows must be minibuffer windows.");
1927 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1928 && !EQ (val, f->minibuffer_window))
1929 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1931 /* Install the chosen minibuffer window, with proper buffer. */
1932 f->minibuffer_window = val;
1936 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1937 "Return the parameters-alist of frame FRAME.\n\
1938 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1939 The meaningful PARMs depend on the kind of frame.\n\
1940 If FRAME is omitted, return information on the currently selected frame.")
1941 (frame)
1942 Lisp_Object frame;
1944 Lisp_Object alist;
1945 FRAME_PTR f;
1946 int height, width;
1947 struct gcpro gcpro1;
1949 if (EQ (frame, Qnil))
1950 frame = selected_frame;
1952 CHECK_FRAME (frame, 0);
1953 f = XFRAME (frame);
1955 if (!FRAME_LIVE_P (f))
1956 return Qnil;
1958 alist = Fcopy_alist (f->param_alist);
1959 GCPRO1 (alist);
1961 if (!FRAME_WINDOW_P (f))
1963 int fg = FRAME_FOREGROUND_PIXEL (f);
1964 int bg = FRAME_BACKGROUND_PIXEL (f);
1965 Lisp_Object elt;
1967 /* If the frame's parameter alist says the colors are
1968 unspecified and reversed, take the frame's background pixel
1969 for foreground and vice versa. */
1970 elt = Fassq (Qforeground_color, alist);
1971 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
1973 if (strncmp (XSTRING (XCDR (elt))->data,
1974 unspecified_bg,
1975 XSTRING (XCDR (elt))->size) == 0)
1976 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
1977 else if (strncmp (XSTRING (XCDR (elt))->data,
1978 unspecified_fg,
1979 XSTRING (XCDR (elt))->size) == 0)
1980 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
1982 else
1983 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
1984 elt = Fassq (Qbackground_color, alist);
1985 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
1987 if (strncmp (XSTRING (XCDR (elt))->data,
1988 unspecified_fg,
1989 XSTRING (XCDR (elt))->size) == 0)
1990 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
1991 else if (strncmp (XSTRING (XCDR (elt))->data,
1992 unspecified_bg,
1993 XSTRING (XCDR (elt))->size) == 0)
1994 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
1996 else
1997 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
1998 store_in_alist (&alist, intern ("font"),
1999 build_string (FRAME_MSDOS_P (f)
2000 ? "ms-dos"
2001 : FRAME_W32_P (f) ? "w32term"
2002 :"tty"));
2004 store_in_alist (&alist, Qname, f->name);
2005 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2006 store_in_alist (&alist, Qheight, make_number (height));
2007 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2008 store_in_alist (&alist, Qwidth, make_number (width));
2009 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2010 store_in_alist (&alist, Qminibuffer,
2011 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2012 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2013 : FRAME_MINIBUF_WINDOW (f)));
2014 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2015 store_in_alist (&alist, Qbuffer_list,
2016 frame_buffer_list (selected_frame));
2018 /* I think this should be done with a hook. */
2019 #ifdef HAVE_WINDOW_SYSTEM
2020 if (FRAME_WINDOW_P (f))
2021 x_report_frame_params (f, &alist);
2022 else
2023 #endif
2025 /* This ought to be correct in f->param_alist for an X frame. */
2026 Lisp_Object lines;
2027 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2028 store_in_alist (&alist, Qmenu_bar_lines, lines);
2031 UNGCPRO;
2032 return alist;
2036 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2037 "Return FRAME's value for parameter PARAMETER.\n\
2038 If FRAME is nil, describe the currently selected frame.")
2039 (frame, parameter)
2040 Lisp_Object frame, parameter;
2042 struct frame *f;
2043 Lisp_Object value;
2045 if (NILP (frame))
2046 frame = selected_frame;
2047 else
2048 CHECK_FRAME (frame, 0);
2049 CHECK_SYMBOL (parameter, 1);
2051 f = XFRAME (frame);
2052 value = Qnil;
2054 if (FRAME_LIVE_P (f))
2056 if (EQ (parameter, Qname))
2057 value = f->name;
2058 #ifdef HAVE_X_WINDOWS
2059 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2060 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2061 #endif /* HAVE_X_WINDOWS */
2062 else
2064 value = Fassq (parameter, f->param_alist);
2065 if (CONSP (value))
2067 value = XCDR (value);
2068 /* Fframe_parameters puts the actual fg/bg color names,
2069 even if f->param_alist says otherwise. This is
2070 important when param_alist's notion of colors is
2071 "unspecified". We need to do the same here. */
2072 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2074 char *color_name;
2075 EMACS_INT csz;
2077 if (EQ (parameter, Qbackground_color))
2079 color_name = XSTRING (value)->data;
2080 csz = XSTRING (value)->size;
2081 if (strncmp (color_name, unspecified_bg, csz) == 0)
2082 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2083 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2084 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2086 else if (EQ (parameter, Qforeground_color))
2088 color_name = XSTRING (value)->data;
2089 csz = XSTRING (value)->size;
2090 if (strncmp (color_name, unspecified_fg, csz) == 0)
2091 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2092 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2093 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2097 else if (EQ (parameter, Qdisplay_type)
2098 || EQ (parameter, Qbackground_mode))
2099 /* Avoid consing in frequent cases. */
2100 value = Qnil;
2101 else
2102 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2106 return value;
2110 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2111 Smodify_frame_parameters, 2, 2, 0,
2112 "Modify the parameters of frame FRAME according to ALIST.\n\
2113 ALIST is an alist of parameters to change and their new values.\n\
2114 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2115 The meaningful PARMs depend on the kind of frame.\n\
2116 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2117 so that `frame-parameters' will return them.\n\
2119 The value of frame parameter FOO can also be accessed\n\
2120 as a frame-local binding for the variable FOO, if you have\n\
2121 enabled such bindings for that variable with `make-variable-frame-local'.")
2122 (frame, alist)
2123 Lisp_Object frame, alist;
2125 FRAME_PTR f;
2126 register Lisp_Object tail, prop, val;
2127 int count = BINDING_STACK_SIZE ();
2129 /* Bind this to t to inhibit initialization of the default face from
2130 X resources in face-set-after-frame-default. If we don't inhibit
2131 this, modifying the `font' frame parameter, for example, while
2132 there is a `default.attributeFont' X resource, won't work,
2133 because `default's font is reset to the value of the X resource
2134 and that resets the `font' frame parameter. */
2135 specbind (Qinhibit_default_face_x_resources, Qt);
2137 if (EQ (frame, Qnil))
2138 frame = selected_frame;
2139 CHECK_LIVE_FRAME (frame, 0);
2140 f = XFRAME (frame);
2142 /* I think this should be done with a hook. */
2143 #ifdef HAVE_WINDOW_SYSTEM
2144 if (FRAME_WINDOW_P (f))
2145 x_set_frame_parameters (f, alist);
2146 else
2147 #endif
2148 #ifdef MSDOS
2149 if (FRAME_MSDOS_P (f))
2150 IT_set_frame_parameters (f, alist);
2151 else
2152 #endif
2155 int length = XINT (Flength (alist));
2156 int i;
2157 Lisp_Object *parms
2158 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2159 Lisp_Object *values
2160 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2162 /* Extract parm names and values into those vectors. */
2164 i = 0;
2165 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2167 Lisp_Object elt;
2169 elt = Fcar (tail);
2170 parms[i] = Fcar (elt);
2171 values[i] = Fcdr (elt);
2172 i++;
2175 /* Now process them in reverse of specified order. */
2176 for (i--; i >= 0; i--)
2178 prop = parms[i];
2179 val = values[i];
2180 store_frame_param (f, prop, val);
2184 return unbind_to (count, Qnil);
2187 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2188 0, 1, 0,
2189 "Height in pixels of a line in the font in frame FRAME.\n\
2190 If FRAME is omitted, the selected frame is used.\n\
2191 For a terminal frame, the value is always 1.")
2192 (frame)
2193 Lisp_Object frame;
2195 struct frame *f;
2197 if (NILP (frame))
2198 frame = selected_frame;
2199 CHECK_FRAME (frame, 0);
2200 f = XFRAME (frame);
2202 #ifdef HAVE_WINDOW_SYSTEM
2203 if (FRAME_WINDOW_P (f))
2204 return make_number (x_char_height (f));
2205 else
2206 #endif
2207 return make_number (1);
2211 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2212 0, 1, 0,
2213 "Width in pixels of characters in the font in frame FRAME.\n\
2214 If FRAME is omitted, the selected frame is used.\n\
2215 The width is the same for all characters, because\n\
2216 currently Emacs supports only fixed-width fonts.\n\
2217 For a terminal screen, the value is always 1.")
2218 (frame)
2219 Lisp_Object frame;
2221 struct frame *f;
2223 if (NILP (frame))
2224 frame = selected_frame;
2225 CHECK_FRAME (frame, 0);
2226 f = XFRAME (frame);
2228 #ifdef HAVE_WINDOW_SYSTEM
2229 if (FRAME_WINDOW_P (f))
2230 return make_number (x_char_width (f));
2231 else
2232 #endif
2233 return make_number (1);
2236 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2237 Sframe_pixel_height, 0, 1, 0,
2238 "Return a FRAME's height in pixels.\n\
2239 This counts only the height available for text lines,\n\
2240 not menu bars on window-system Emacs frames.\n\
2241 For a terminal frame, the result really gives the height in characters.\n\
2242 If FRAME is omitted, the selected frame is used.")
2243 (frame)
2244 Lisp_Object frame;
2246 struct frame *f;
2248 if (NILP (frame))
2249 frame = selected_frame;
2250 CHECK_FRAME (frame, 0);
2251 f = XFRAME (frame);
2253 #ifdef HAVE_WINDOW_SYSTEM
2254 if (FRAME_WINDOW_P (f))
2255 return make_number (x_pixel_height (f));
2256 else
2257 #endif
2258 return make_number (FRAME_HEIGHT (f));
2261 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2262 Sframe_pixel_width, 0, 1, 0,
2263 "Return FRAME's width in pixels.\n\
2264 For a terminal frame, the result really gives the width in characters.\n\
2265 If FRAME is omitted, the selected frame is used.")
2266 (frame)
2267 Lisp_Object frame;
2269 struct frame *f;
2271 if (NILP (frame))
2272 frame = selected_frame;
2273 CHECK_FRAME (frame, 0);
2274 f = XFRAME (frame);
2276 #ifdef HAVE_WINDOW_SYSTEM
2277 if (FRAME_WINDOW_P (f))
2278 return make_number (x_pixel_width (f));
2279 else
2280 #endif
2281 return make_number (FRAME_WIDTH (f));
2284 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2285 "Specify that the frame FRAME has LINES lines.\n\
2286 Optional third arg non-nil means that redisplay should use LINES lines\n\
2287 but that the idea of the actual height of the frame should not be changed.")
2288 (frame, lines, pretend)
2289 Lisp_Object frame, lines, pretend;
2291 register struct frame *f;
2293 CHECK_NUMBER (lines, 0);
2294 if (NILP (frame))
2295 frame = selected_frame;
2296 CHECK_LIVE_FRAME (frame, 0);
2297 f = XFRAME (frame);
2299 /* I think this should be done with a hook. */
2300 #ifdef HAVE_WINDOW_SYSTEM
2301 if (FRAME_WINDOW_P (f))
2303 if (XINT (lines) != f->height)
2304 x_set_window_size (f, 1, f->width, XINT (lines));
2305 do_pending_window_change (0);
2307 else
2308 #endif
2309 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2310 return Qnil;
2313 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2314 "Specify that the frame FRAME has COLS columns.\n\
2315 Optional third arg non-nil means that redisplay should use COLS columns\n\
2316 but that the idea of the actual width of the frame should not be changed.")
2317 (frame, cols, pretend)
2318 Lisp_Object frame, cols, pretend;
2320 register struct frame *f;
2321 CHECK_NUMBER (cols, 0);
2322 if (NILP (frame))
2323 frame = selected_frame;
2324 CHECK_LIVE_FRAME (frame, 0);
2325 f = XFRAME (frame);
2327 /* I think this should be done with a hook. */
2328 #ifdef HAVE_WINDOW_SYSTEM
2329 if (FRAME_WINDOW_P (f))
2331 if (XINT (cols) != f->width)
2332 x_set_window_size (f, 1, XINT (cols), f->height);
2333 do_pending_window_change (0);
2335 else
2336 #endif
2337 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2338 return Qnil;
2341 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2342 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2343 (frame, cols, rows)
2344 Lisp_Object frame, cols, rows;
2346 register struct frame *f;
2348 CHECK_LIVE_FRAME (frame, 0);
2349 CHECK_NUMBER (cols, 2);
2350 CHECK_NUMBER (rows, 1);
2351 f = XFRAME (frame);
2353 /* I think this should be done with a hook. */
2354 #ifdef HAVE_WINDOW_SYSTEM
2355 if (FRAME_WINDOW_P (f))
2357 if (XINT (rows) != f->height || XINT (cols) != f->width
2358 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2359 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2360 do_pending_window_change (0);
2362 else
2363 #endif
2364 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2366 return Qnil;
2369 DEFUN ("set-frame-position", Fset_frame_position,
2370 Sset_frame_position, 3, 3, 0,
2371 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2372 This is actually the position of the upper left corner of the frame.\n\
2373 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2374 the rightmost or bottommost possible position (that stays within the screen).")
2375 (frame, xoffset, yoffset)
2376 Lisp_Object frame, xoffset, yoffset;
2378 register struct frame *f;
2380 CHECK_LIVE_FRAME (frame, 0);
2381 CHECK_NUMBER (xoffset, 1);
2382 CHECK_NUMBER (yoffset, 2);
2383 f = XFRAME (frame);
2385 /* I think this should be done with a hook. */
2386 #ifdef HAVE_WINDOW_SYSTEM
2387 if (FRAME_WINDOW_P (f))
2388 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2389 #endif
2391 return Qt;
2395 void
2396 syms_of_frame ()
2398 Qframep = intern ("framep");
2399 staticpro (&Qframep);
2400 Qframe_live_p = intern ("frame-live-p");
2401 staticpro (&Qframe_live_p);
2402 Qheight = intern ("height");
2403 staticpro (&Qheight);
2404 Qicon = intern ("icon");
2405 staticpro (&Qicon);
2406 Qminibuffer = intern ("minibuffer");
2407 staticpro (&Qminibuffer);
2408 Qmodeline = intern ("modeline");
2409 staticpro (&Qmodeline);
2410 Qname = intern ("name");
2411 staticpro (&Qname);
2412 Qonly = intern ("only");
2413 staticpro (&Qonly);
2414 Qunsplittable = intern ("unsplittable");
2415 staticpro (&Qunsplittable);
2416 Qmenu_bar_lines = intern ("menu-bar-lines");
2417 staticpro (&Qmenu_bar_lines);
2418 Qtool_bar_lines = intern ("tool-bar-lines");
2419 staticpro (&Qtool_bar_lines);
2420 Qwidth = intern ("width");
2421 staticpro (&Qwidth);
2422 Qx = intern ("x");
2423 staticpro (&Qx);
2424 Qw32 = intern ("w32");
2425 staticpro (&Qw32);
2426 Qpc = intern ("pc");
2427 staticpro (&Qpc);
2428 Qmac = intern ("mac");
2429 staticpro (&Qmac);
2430 Qvisible = intern ("visible");
2431 staticpro (&Qvisible);
2432 Qbuffer_predicate = intern ("buffer-predicate");
2433 staticpro (&Qbuffer_predicate);
2434 Qbuffer_list = intern ("buffer-list");
2435 staticpro (&Qbuffer_list);
2436 Qtitle = intern ("title");
2437 staticpro (&Qtitle);
2438 Qdisplay_type = intern ("display-type");
2439 staticpro (&Qdisplay_type);
2440 Qbackground_mode = intern ("background-mode");
2441 staticpro (&Qbackground_mode);
2443 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
2444 "Alist of default values for frame creation.\n\
2445 These may be set in your init file, like this:\n\
2446 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
2447 These override values given in window system configuration data,\n\
2448 including X Windows' defaults database.\n\
2449 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
2450 For values specific to the separate minibuffer frame, see\n\
2451 `minibuffer-frame-alist'.\n\
2452 The `menu-bar-lines' element of the list controls whether new frames\n\
2453 have menu bars; `menu-bar-mode' works by altering this element.");
2454 Vdefault_frame_alist = Qnil;
2456 Qinhibit_default_face_x_resources
2457 = intern ("inhibit-default-face-x-resources");
2458 staticpro (&Qinhibit_default_face_x_resources);
2460 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2461 "The initial frame-object, which represents Emacs's stdout.");
2463 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2464 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2465 Vemacs_iconified = Qnil;
2467 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
2468 "If non-nil, function applied to the normal result of `mouse-position'.\n\
2469 This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
2470 which need to do mouse handling at the Lisp level.");
2471 Vmouse_position_function = Qnil;
2473 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2474 "Minibufferless frames use this frame's minibuffer.\n\
2476 Emacs cannot create minibufferless frames unless this is set to an\n\
2477 appropriate surrogate.\n\
2479 Emacs consults this variable only when creating minibufferless\n\
2480 frames; once the frame is created, it sticks with its assigned\n\
2481 minibuffer, no matter what this variable is set to. This means that\n\
2482 this variable doesn't necessarily say anything meaningful about the\n\
2483 current set of frames, or where the minibuffer is currently being\n\
2484 displayed.");
2486 staticpro (&Vframe_list);
2488 defsubr (&Sactive_minibuffer_window);
2489 defsubr (&Sframep);
2490 defsubr (&Sframe_live_p);
2491 defsubr (&Smake_terminal_frame);
2492 defsubr (&Shandle_switch_frame);
2493 defsubr (&Signore_event);
2494 defsubr (&Sselect_frame);
2495 defsubr (&Sselected_frame);
2496 defsubr (&Swindow_frame);
2497 defsubr (&Sframe_root_window);
2498 defsubr (&Sframe_first_window);
2499 defsubr (&Sframe_selected_window);
2500 defsubr (&Sset_frame_selected_window);
2501 defsubr (&Sframe_list);
2502 defsubr (&Snext_frame);
2503 defsubr (&Sprevious_frame);
2504 defsubr (&Sdelete_frame);
2505 defsubr (&Smouse_position);
2506 defsubr (&Smouse_pixel_position);
2507 defsubr (&Sset_mouse_position);
2508 defsubr (&Sset_mouse_pixel_position);
2509 #if 0
2510 defsubr (&Sframe_configuration);
2511 defsubr (&Srestore_frame_configuration);
2512 #endif
2513 defsubr (&Smake_frame_visible);
2514 defsubr (&Smake_frame_invisible);
2515 defsubr (&Siconify_frame);
2516 defsubr (&Sframe_visible_p);
2517 defsubr (&Svisible_frame_list);
2518 defsubr (&Sraise_frame);
2519 defsubr (&Slower_frame);
2520 defsubr (&Sredirect_frame_focus);
2521 defsubr (&Sframe_focus);
2522 defsubr (&Sframe_parameters);
2523 defsubr (&Sframe_parameter);
2524 defsubr (&Smodify_frame_parameters);
2525 defsubr (&Sframe_char_height);
2526 defsubr (&Sframe_char_width);
2527 defsubr (&Sframe_pixel_height);
2528 defsubr (&Sframe_pixel_width);
2529 defsubr (&Sset_frame_height);
2530 defsubr (&Sset_frame_width);
2531 defsubr (&Sset_frame_size);
2532 defsubr (&Sset_frame_position);
2535 void
2536 keys_of_frame ()
2538 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2539 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2540 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2541 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");