*** empty log message ***
[emacs.git] / src / frame.c
blob2a065833e079eb3960175282f1bff11639644722
1 /* Generic frame functions.
2 Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #include <stdio.h>
22 #include <config.h>
23 #include "lisp.h"
24 #include "frame.h"
25 #include "termhooks.h"
27 #ifdef MULTI_FRAME
29 #include "buffer.h"
30 #include "window.h"
32 /* These help us bind and responding to switch-frame events. */
33 #include "commands.h"
34 #include "keyboard.h"
36 Lisp_Object Vemacs_iconified;
37 Lisp_Object Vframe_list;
38 Lisp_Object Vterminal_frame;
39 Lisp_Object Vdefault_minibuffer_frame;
40 Lisp_Object Vdefault_frame_alist;
42 /* Evaluate this expression to rebuild the section of syms_of_frame
43 that initializes and staticpros the symbols declared below. Note
44 that Emacs 18 has a bug that keeps C-x C-e from being able to
45 evaluate this expression.
47 (progn
48 ;; Accumulate a list of the symbols we want to initialize from the
49 ;; declarations at the top of the file.
50 (goto-char (point-min))
51 (search-forward "/\*&&& symbols declared here &&&*\/\n")
52 (let (symbol-list)
53 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
54 (setq symbol-list
55 (cons (buffer-substring (match-beginning 1) (match-end 1))
56 symbol-list))
57 (forward-line 1))
58 (setq symbol-list (nreverse symbol-list))
59 ;; Delete the section of syms_of_... where we initialize the symbols.
60 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
61 (let ((start (point)))
62 (while (looking-at "^ Q")
63 (forward-line 2))
64 (kill-region start (point)))
65 ;; Write a new symbol initialization section.
66 (while symbol-list
67 (insert (format " %s = intern (\"" (car symbol-list)))
68 (let ((start (point)))
69 (insert (substring (car symbol-list) 1))
70 (subst-char-in-region start (point) ?_ ?-))
71 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
72 (setq symbol-list (cdr symbol-list)))))
73 */
75 /*&&& symbols declared here &&&*/
76 Lisp_Object Qframep;
77 Lisp_Object Qframe_live_p;
78 Lisp_Object Qheight;
79 Lisp_Object Qicon;
80 Lisp_Object Qminibuffer;
81 Lisp_Object Qmodeline;
82 Lisp_Object Qname;
83 Lisp_Object Qonly;
84 Lisp_Object Qunsplittable;
85 Lisp_Object Qmenu_bar_lines;
86 Lisp_Object Qwidth;
87 Lisp_Object Qx;
88 Lisp_Object Qvisible;
90 extern Lisp_Object Vminibuffer_list;
91 extern Lisp_Object get_minibuffer ();
92 extern Lisp_Object Fhandle_switch_frame ();
93 extern Lisp_Object Fredirect_frame_focus ();
95 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
96 "Return non-nil if OBJECT is a frame.\n\
97 Value is t for a termcap frame (a character-only terminal),\n\
98 `x' for an Emacs frame that is really an X window.\n\
99 Also see `live-frame-p'.")
100 (object)
101 Lisp_Object object;
103 if (XTYPE (object) != Lisp_Frame)
104 return Qnil;
105 switch (XFRAME (object)->output_method)
107 case output_termcap:
108 return Qt;
109 case output_x_window:
110 return Qx;
111 default:
112 abort ();
116 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
117 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
118 Value is nil if OBJECT is not a live frame. If object is a live\n\
119 frame, the return value indicates what sort of output device it is\n\
120 displayed on. Value is t for a termcap frame (a character-only\n\
121 terminal), `x' for an Emacs frame being displayed in an X window.")
122 (object)
123 Lisp_Object object;
125 return ((FRAMEP (object)
126 && FRAME_LIVE_P (XFRAME (object)))
127 ? Fframep (object)
128 : Qnil);
131 struct frame *
132 make_frame (mini_p)
133 int mini_p;
135 Lisp_Object frame;
136 register struct frame *f;
137 register Lisp_Object root_window;
138 register Lisp_Object mini_window;
140 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
141 - sizeof (Lisp_Object)))
142 / sizeof (Lisp_Object)),
143 make_number (0));
144 XSETTYPE (frame, Lisp_Frame);
145 f = XFRAME (frame);
147 f->cursor_x = 0;
148 f->cursor_y = 0;
149 f->current_glyphs = 0;
150 f->desired_glyphs = 0;
151 f->visible = 0;
152 f->async_visible = 0;
153 f->display.nothing = 0;
154 f->iconified = 0;
155 f->async_iconified = 0;
156 f->wants_modeline = 1;
157 f->auto_raise = 0;
158 f->auto_lower = 0;
159 f->no_split = 0;
160 f->garbaged = 0;
161 f->has_minibuffer = mini_p;
162 f->focus_frame = Qnil;
163 f->explicit_name = 0;
164 f->can_have_scroll_bars = 0;
165 f->has_vertical_scroll_bars = 0;
166 f->param_alist = Qnil;
167 f->scroll_bars = Qnil;
168 f->condemned_scroll_bars = Qnil;
169 f->face_alist = Qnil;
170 f->menu_bar_items = Qnil;
171 f->menu_bar_vector = Qnil;
172 f->menu_bar_items_used = 0;
174 root_window = make_window ();
175 if (mini_p)
177 mini_window = make_window ();
178 XWINDOW (root_window)->next = mini_window;
179 XWINDOW (mini_window)->prev = root_window;
180 XWINDOW (mini_window)->mini_p = Qt;
181 XWINDOW (mini_window)->frame = frame;
182 f->minibuffer_window = mini_window;
184 else
186 mini_window = Qnil;
187 XWINDOW (root_window)->next = Qnil;
188 f->minibuffer_window = Qnil;
191 XWINDOW (root_window)->frame = frame;
193 /* 10 is arbitrary,
194 just so that there is "something there."
195 Correct size will be set up later with change_frame_size. */
197 f->width = 10;
198 f->height = 10;
200 XFASTINT (XWINDOW (root_window)->width) = 10;
201 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
203 if (mini_p)
205 XFASTINT (XWINDOW (mini_window)->width) = 10;
206 XFASTINT (XWINDOW (mini_window)->top) = 9;
207 XFASTINT (XWINDOW (mini_window)->height) = 1;
210 /* Choose a buffer for the frame's root window. */
212 Lisp_Object buf;
214 XWINDOW (root_window)->buffer = Qt;
215 buf = Fcurrent_buffer ();
216 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
217 a space), try to find another one. */
218 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
219 buf = Fother_buffer (buf, Qnil);
220 Fset_window_buffer (root_window, buf);
223 if (mini_p)
225 XWINDOW (mini_window)->buffer = Qt;
226 Fset_window_buffer (mini_window,
227 (NILP (Vminibuffer_list)
228 ? get_minibuffer (0)
229 : Fcar (Vminibuffer_list)));
232 f->root_window = root_window;
233 f->selected_window = root_window;
234 /* Make sure this window seems more recently used than
235 a newly-created, never-selected window. */
236 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
238 return f;
241 /* Make a frame using a separate minibuffer window on another frame.
242 MINI_WINDOW is the minibuffer window to use. nil means use the
243 default (the global minibuffer). */
245 struct frame *
246 make_frame_without_minibuffer (mini_window)
247 register Lisp_Object mini_window;
249 register struct frame *f;
251 /* Choose the minibuffer window to use. */
252 if (NILP (mini_window))
254 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
255 error ("default-minibuffer-frame must be set when creating minibufferless frames");
256 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
257 error ("default-minibuffer-frame must be a live frame");
258 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
260 else
262 CHECK_LIVE_WINDOW (mini_window, 0);
265 /* Make a frame containing just a root window. */
266 f = make_frame (0);
268 /* Install the chosen minibuffer window, with proper buffer. */
269 f->minibuffer_window = mini_window;
270 Fset_window_buffer (mini_window,
271 (NILP (Vminibuffer_list)
272 ? get_minibuffer (0)
273 : Fcar (Vminibuffer_list)));
274 return f;
277 /* Make a frame containing only a minibuffer window. */
279 struct frame *
280 make_minibuffer_frame ()
282 /* First make a frame containing just a root window, no minibuffer. */
284 register struct frame *f = make_frame (0);
285 register Lisp_Object mini_window;
286 register Lisp_Object frame;
288 XSET (frame, Lisp_Frame, f);
290 f->auto_raise = 0;
291 f->auto_lower = 0;
292 f->no_split = 1;
293 f->wants_modeline = 0;
294 f->has_minibuffer = 1;
296 /* Now label the root window as also being the minibuffer.
297 Avoid infinite looping on the window chain by marking next pointer
298 as nil. */
300 mini_window = f->minibuffer_window = f->root_window;
301 XWINDOW (mini_window)->mini_p = Qt;
302 XWINDOW (mini_window)->next = Qnil;
303 XWINDOW (mini_window)->prev = Qnil;
304 XWINDOW (mini_window)->frame = frame;
306 /* Put the proper buffer in that window. */
308 Fset_window_buffer (mini_window,
309 (NILP (Vminibuffer_list)
310 ? get_minibuffer (0)
311 : Fcar (Vminibuffer_list)));
312 return f;
315 /* Construct a frame that refers to the terminal (stdin and stdout). */
317 struct frame *
318 make_terminal_frame ()
320 register struct frame *f;
321 Lisp_Object frame;
323 Vframe_list = Qnil;
324 f = make_frame (1);
326 XSET (frame, Lisp_Frame, f);
327 Vframe_list = Fcons (frame, Vframe_list);
329 f->name = build_string ("terminal");
330 FRAME_SET_VISIBLE (f, 1);
331 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
332 XSET (Vterminal_frame, Lisp_Frame, f);
333 return f;
336 static Lisp_Object
337 do_switch_frame (frame, no_enter, track)
338 Lisp_Object frame, no_enter;
339 int track;
341 /* If FRAME is a switch-frame event, extract the frame we should
342 switch to. */
343 if (CONSP (frame)
344 && EQ (XCONS (frame)->car, Qswitch_frame)
345 && CONSP (XCONS (frame)->cdr))
346 frame = XCONS (XCONS (frame)->cdr)->car;
348 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
349 a switch-frame event to arrive after a frame is no longer live,
350 especially when deleting the initial frame during startup. */
351 CHECK_FRAME (frame, 0);
352 if (! FRAME_LIVE_P (XFRAME (frame)))
353 return Qnil;
355 if (selected_frame == XFRAME (frame))
356 return frame;
358 /* This is too greedy; it causes inappropriate focus redirection
359 that's hard to get rid of. */
360 #if 0
361 /* If a frame's focus has been redirected toward the currently
362 selected frame, we should change the redirection to point to the
363 newly selected frame. This means that if the focus is redirected
364 from a minibufferless frame to a surrogate minibuffer frame, we
365 can use `other-window' to switch between all the frames using
366 that minibuffer frame, and the focus redirection will follow us
367 around. */
368 if (track)
370 Lisp_Object tail;
372 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
374 Lisp_Object focus;
376 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
377 abort ();
379 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
381 if (XTYPE (focus) == Lisp_Frame
382 && XFRAME (focus) == selected_frame)
383 Fredirect_frame_focus (XCONS (tail)->car, frame);
386 #else /* ! 0 */
387 /* Instead, apply it only to the frame we're pointing to. */
388 #ifdef HAVE_X_WINDOWS
389 if (track)
391 Lisp_Object focus, xfocus;
393 xfocus = x_get_focus_frame ();
394 if (FRAMEP (xfocus))
396 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
397 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
398 Fredirect_frame_focus (xfocus, frame);
401 #endif /* HAVE_X_WINDOWS */
402 #endif /* ! 0 */
404 selected_frame = XFRAME (frame);
405 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
406 last_nonminibuf_frame = selected_frame;
408 Fselect_window (XFRAME (frame)->selected_window);
409 choose_minibuf_frame ();
411 /* We want to make sure that the next event generates a frame-switch
412 event to the appropriate frame. This seems kludgy to me, but
413 before you take it out, make sure that evaluating something like
414 (select-window (frame-root-window (new-frame))) doesn't end up
415 with your typing being interpreted in the new frame instead of
416 the one you're actually typing in. */
417 internal_last_event_frame = Qnil;
419 return frame;
422 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
423 "Select the frame FRAME.\n\
424 Subsequent editing commands apply to its selected window.\n\
425 The selection of FRAME lasts until the next time the user does\n\
426 something to select a different frame, or until the next time this\n\
427 function is called.")
428 (frame, no_enter)
429 Lisp_Object frame, no_enter;
431 return do_switch_frame (frame, no_enter, 1);
435 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
436 "Handle a switch-frame event EVENT.\n\
437 Switch-frame events are usually bound to this function.\n\
438 A switch-frame event tells Emacs that the window manager has requested\n\
439 that the user's events be directed to the frame mentioned in the event.\n\
440 This function selects the selected window of the frame of EVENT.\n\
442 If EVENT is frame object, handle it as if it were a switch-frame event\n\
443 to that frame.")
444 (frame, no_enter)
445 Lisp_Object frame, no_enter;
447 return do_switch_frame (frame, no_enter, 0);
451 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
452 "Return the frame that is now selected.")
455 Lisp_Object tem;
456 XSET (tem, Lisp_Frame, selected_frame);
457 return tem;
460 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
461 "Return the frame object that window WINDOW is on.")
462 (window)
463 Lisp_Object window;
465 CHECK_LIVE_WINDOW (window, 0);
466 return XWINDOW (window)->frame;
469 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
470 "Returns the topmost, leftmost window of FRAME.\n\
471 If omitted, FRAME defaults to the currently selected frame.")
472 (frame)
473 Lisp_Object frame;
475 Lisp_Object w;
477 if (NILP (frame))
478 w = selected_frame->root_window;
479 else
481 CHECK_LIVE_FRAME (frame, 0);
482 w = XFRAME (frame)->root_window;
484 while (NILP (XWINDOW (w)->buffer))
486 if (! NILP (XWINDOW (w)->hchild))
487 w = XWINDOW (w)->hchild;
488 else if (! NILP (XWINDOW (w)->vchild))
489 w = XWINDOW (w)->vchild;
490 else
491 abort ();
493 return w;
496 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
497 "Returns the root-window of FRAME.\n\
498 If omitted, FRAME defaults to the currently selected frame.")
499 (frame)
500 Lisp_Object frame;
502 if (NILP (frame))
503 XSET (frame, Lisp_Frame, selected_frame);
504 else
505 CHECK_LIVE_FRAME (frame, 0);
507 return XFRAME (frame)->root_window;
510 DEFUN ("frame-selected-window", Fframe_selected_window,
511 Sframe_selected_window, 0, 1, 0,
512 "Return the selected window of frame object FRAME.\n\
513 If omitted, FRAME defaults to the currently selected frame.")
514 (frame)
515 Lisp_Object frame;
517 if (NILP (frame))
518 XSET (frame, Lisp_Frame, selected_frame);
519 else
520 CHECK_LIVE_FRAME (frame, 0);
522 return XFRAME (frame)->selected_window;
525 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
526 Sset_frame_selected_window, 2, 2, 0,
527 "Set the selected window of frame object FRAME to WINDOW.\n\
528 If FRAME is nil, the selected frame is used.\n\
529 If FRAME is the selected frame, this makes WINDOW the selected window.")
530 (frame, window)
531 Lisp_Object frame, window;
533 if (NILP (frame))
534 XSET (frame, Lisp_Frame, selected_frame);
535 else
536 CHECK_LIVE_FRAME (frame, 0);
538 CHECK_LIVE_WINDOW (window, 1);
540 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
541 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
543 if (XFRAME (frame) == selected_frame)
544 return Fselect_window (window);
546 return XFRAME (frame)->selected_window = window;
549 DEFUN ("frame-list", Fframe_list, Sframe_list,
550 0, 0, 0,
551 "Return a list of all frames.")
554 return Fcopy_sequence (Vframe_list);
557 /* Return the next frame in the frame list after FRAME.
558 If MINIBUF is nil, exclude minibuffer-only frames.
559 If MINIBUF is a window, include only frames using that window for
560 their minibuffer.
561 If MINIBUF is `visible', include all visible frames.
562 Otherwise, include all frames. */
564 Lisp_Object
565 next_frame (frame, minibuf)
566 Lisp_Object frame;
567 Lisp_Object minibuf;
569 Lisp_Object tail;
570 int passed = 0;
572 /* There must always be at least one frame in Vframe_list. */
573 if (! CONSP (Vframe_list))
574 abort ();
576 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
577 forever. Forestall that. */
578 CHECK_LIVE_FRAME (frame, 0);
580 while (1)
581 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
583 Lisp_Object f;
585 f = XCONS (tail)->car;
586 if (passed)
588 /* Decide whether this frame is eligible to be returned. */
590 /* If we've looped all the way around without finding any
591 eligible frames, return the original frame. */
592 if (EQ (f, frame))
593 return f;
595 /* Let minibuf decide if this frame is acceptable. */
596 if (NILP (minibuf))
598 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
599 return f;
601 else if (EQ (minibuf, Qvisible))
603 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
604 if (FRAME_VISIBLE_P (XFRAME (f)))
605 return f;
607 else if (WINDOWP (minibuf))
609 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
610 return f;
612 else
613 return f;
616 if (EQ (frame, f))
617 passed++;
621 /* Return the previous frame in the frame list before FRAME.
622 If MINIBUF is nil, exclude minibuffer-only frames.
623 If MINIBUF is a window, include only frames using that window for
624 their minibuffer.
625 If MINIBUF is `visible', include all visible frames.
626 Otherwise, include all frames. */
628 Lisp_Object
629 prev_frame (frame, minibuf)
630 Lisp_Object frame;
631 Lisp_Object minibuf;
633 Lisp_Object tail;
634 Lisp_Object prev;
636 /* There must always be at least one frame in Vframe_list. */
637 if (! CONSP (Vframe_list))
638 abort ();
640 prev = Qnil;
641 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
643 Lisp_Object f;
645 f = XCONS (tail)->car;
646 if (XTYPE (f) != Lisp_Frame)
647 abort ();
649 if (EQ (frame, f) && !NILP (prev))
650 return prev;
652 /* Decide whether this frame is eligible to be returned,
653 according to minibuf. */
654 if (NILP (minibuf))
656 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
657 prev = f;
659 else if (XTYPE (minibuf) == Lisp_Window)
661 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
662 prev = f;
664 else if (EQ (minibuf, Qvisible))
666 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
667 if (FRAME_VISIBLE_P (XFRAME (f)))
668 prev = f;
670 else
671 prev = f;
674 /* We've scanned the entire list. */
675 if (NILP (prev))
676 /* We went through the whole frame list without finding a single
677 acceptable frame. Return the original frame. */
678 return frame;
679 else
680 /* There were no acceptable frames in the list before FRAME; otherwise,
681 we would have returned directly from the loop. Since PREV is the last
682 acceptable frame in the list, return it. */
683 return prev;
687 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
688 "Return the next frame in the frame list after FRAME.\n\
689 By default, skip minibuffer-only frames.\n\
690 If omitted, FRAME defaults to the selected frame.\n\
691 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
692 If MINIFRAME is a window, include only frames using that window for their\n\
693 minibuffer.\n\
694 If MINIFRAME is `visible', include all visible frames.\n\
695 Otherwise, include all frames.")
696 (frame, miniframe)
697 Lisp_Object frame, miniframe;
699 Lisp_Object tail;
701 if (NILP (frame))
702 XSET (frame, Lisp_Frame, selected_frame);
703 else
704 CHECK_LIVE_FRAME (frame, 0);
706 return next_frame (frame, miniframe);
709 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
710 "Return the previous frame in the frame list before FRAME.\n\
711 By default, skip minibuffer-only frames.\n\
712 If omitted, FRAME defaults to the selected frame.\n\
713 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
714 If MINIFRAME is a window, include only frames using that window for their\n\
715 minibuffer.\n\
716 If MINIFRAME is `visible', include all visible frames.\n\
717 Otherwise, include all frames.")
718 (frame, miniframe)
719 Lisp_Object frame, miniframe;
721 Lisp_Object tail;
723 if (NILP (frame))
724 XSET (frame, Lisp_Frame, selected_frame);
725 else
726 CHECK_LIVE_FRAME (frame, 0);
728 return prev_frame (frame, miniframe);
731 /* Return 1 if it is ok to delete frame F;
732 0 if all frames aside from F are invisible.
733 (Exception: if F is the terminal frame, and we are using X, return 1.) */
735 static int
736 other_visible_frames (f)
737 FRAME_PTR f;
739 /* We know the selected frame is visible,
740 so if F is some other frame, it can't be the sole visible one. */
741 if (f == selected_frame)
743 Lisp_Object frames;
744 int count = 0;
746 for (frames = Vframe_list;
747 CONSP (frames);
748 frames = XCONS (frames)->cdr)
750 Lisp_Object this;
752 this = XCONS (frames)->car;
753 /* Verify that the frame's window still exists
754 and we can still talk to it. And note any recent change
755 in visibility. */
756 #ifdef HAVE_X_WINDOWS
757 if (FRAME_X_P (XFRAME (this)))
759 x_sync (this);
760 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
762 #endif
764 if (FRAME_VISIBLE_P (XFRAME (this))
765 || FRAME_ICONIFIED_P (XFRAME (this))
766 /* Allow deleting the terminal frame when at least
767 one X frame exists! */
768 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
769 count++;
771 return count > 1;
773 return 1;
776 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
777 "Delete FRAME, permanently eliminating it from use.\n\
778 If omitted, FRAME defaults to the selected frame.\n\
779 A frame may not be deleted if its minibuffer is used by other frames.\n\
780 Normally, you may not delete a frame if all other frames are invisible,\n\
781 but if the second optional argument FORCE is non-nil, you may do so.")
782 (frame, force)
783 Lisp_Object frame, force;
785 struct frame *f;
787 if (EQ (frame, Qnil))
789 f = selected_frame;
790 XSET (frame, Lisp_Frame, f);
792 else
794 CHECK_FRAME (frame, 0);
795 f = XFRAME (frame);
798 if (! FRAME_LIVE_P (f))
799 return Qnil;
801 if (NILP (force) && !other_visible_frames (f))
802 error ("Attempt to delete the sole visible or iconified frame");
804 /* Does this frame have a minibuffer, and is it the surrogate
805 minibuffer for any other frame? */
806 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
808 Lisp_Object frames;
810 for (frames = Vframe_list;
811 CONSP (frames);
812 frames = XCONS (frames)->cdr)
814 Lisp_Object this;
815 this = XCONS (frames)->car;
817 if (! EQ (this, frame)
818 && EQ (frame,
819 WINDOW_FRAME (XWINDOW
820 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
821 error ("Attempt to delete a surrogate minibuffer frame");
825 /* Don't let the frame remain selected. */
826 if (f == selected_frame)
827 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
829 /* Don't allow minibuf_window to remain on a deleted frame. */
830 if (EQ (f->minibuffer_window, minibuf_window))
832 Fset_window_buffer (selected_frame->minibuffer_window,
833 XWINDOW (minibuf_window)->buffer);
834 minibuf_window = selected_frame->minibuffer_window;
837 /* Mark all the windows that used to be on FRAME as deleted, and then
838 remove the reference to them. */
839 delete_all_subwindows (XWINDOW (f->root_window));
840 f->root_window = Qnil;
842 Vframe_list = Fdelq (frame, Vframe_list);
843 FRAME_SET_VISIBLE (f, 0);
845 /* Since some events are handled at the interrupt level, we may get
846 an event for f at any time; if we zero out the frame's display
847 now, then we may trip up the event-handling code. Instead, we'll
848 promise that the display of the frame must be valid until we have
849 called the window-system-dependent frame destruction routine. */
851 /* I think this should be done with a hook. */
852 #ifdef HAVE_X_WINDOWS
853 if (FRAME_X_P (f))
854 x_destroy_window (f);
855 #endif
857 f->display.nothing = 0;
859 /* If we've deleted the last_nonminibuf_frame, then try to find
860 another one. */
861 if (f == last_nonminibuf_frame)
863 Lisp_Object frames;
865 last_nonminibuf_frame = 0;
867 for (frames = Vframe_list;
868 CONSP (frames);
869 frames = XCONS (frames)->cdr)
871 f = XFRAME (XCONS (frames)->car);
872 if (!FRAME_MINIBUF_ONLY_P (f))
874 last_nonminibuf_frame = f;
875 break;
880 /* If we've deleted Vdefault_minibuffer_frame, try to find another
881 one. Prefer minibuffer-only frames, but also notice frames
882 with other windows. */
883 if (EQ (frame, Vdefault_minibuffer_frame))
885 Lisp_Object frames;
887 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
888 Lisp_Object frame_with_minibuf;
890 frame_with_minibuf = Qnil;
891 for (frames = Vframe_list;
892 CONSP (frames);
893 frames = XCONS (frames)->cdr)
895 Lisp_Object this;
897 this = XCONS (frames)->car;
898 if (XTYPE (this) != Lisp_Frame)
899 abort ();
900 f = XFRAME (this);
902 if (FRAME_HAS_MINIBUF_P (f))
904 frame_with_minibuf = this;
905 if (FRAME_MINIBUF_ONLY_P (f))
906 break;
910 /* We know that there must be some frame with a minibuffer out
911 there. If this were not true, all of the frames present
912 would have to be minibufferless, which implies that at some
913 point their minibuffer frames must have been deleted, but
914 that is prohibited at the top; you can't delete surrogate
915 minibuffer frames. */
916 if (NILP (frame_with_minibuf))
917 abort ();
919 Vdefault_minibuffer_frame = frame_with_minibuf;
922 return Qnil;
925 /* Return mouse position in character cell units. */
927 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
928 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
929 The position is given in character cells, where (0, 0) is the\n\
930 upper-left corner.\n\
931 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
932 to read the mouse position, it returns the selected frame for FRAME\n\
933 and nil for X and Y.")
936 FRAME_PTR f;
937 Lisp_Object lispy_dummy;
938 enum scroll_bar_part party_dummy;
939 Lisp_Object x, y;
940 int col, row;
941 unsigned long long_dummy;
943 f = selected_frame;
944 x = y = Qnil;
946 /* It's okay for the hook to refrain from storing anything. */
947 if (mouse_position_hook)
948 (*mouse_position_hook) (&f,
949 &lispy_dummy, &party_dummy,
950 &x, &y,
951 &long_dummy);
952 if (! NILP (x))
954 col = XINT (x);
955 row = XINT (y);
956 pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
957 XSETINT (x, col);
958 XSETINT (y, row);
960 XSET (lispy_dummy, Lisp_Frame, f);
961 return Fcons (lispy_dummy, Fcons (x, y));
964 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
965 Smouse_pixel_position, 0, 0, 0,
966 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
967 The position is given in pixel units, where (0, 0) is the\n\
968 upper-left corner.\n\
969 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
970 to read the mouse position, it returns the selected frame for FRAME\n\
971 and nil for X and Y.")
974 FRAME_PTR f;
975 Lisp_Object lispy_dummy;
976 enum scroll_bar_part party_dummy;
977 Lisp_Object x, y;
978 int col, row;
979 unsigned long long_dummy;
981 f = selected_frame;
982 x = y = Qnil;
984 /* It's okay for the hook to refrain from storing anything. */
985 if (mouse_position_hook)
986 (*mouse_position_hook) (&f,
987 &lispy_dummy, &party_dummy,
988 &x, &y,
989 &long_dummy);
990 XSET (lispy_dummy, Lisp_Frame, f);
991 return Fcons (lispy_dummy, Fcons (x, y));
994 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
995 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
996 WARNING: If you use this under X windows,\n\
997 you should call `unfocus-frame' afterwards.")
998 (frame, x, y)
999 Lisp_Object frame, x, y;
1001 CHECK_LIVE_FRAME (frame, 0);
1002 CHECK_NUMBER (x, 2);
1003 CHECK_NUMBER (y, 1);
1005 /* I think this should be done with a hook. */
1006 #ifdef HAVE_X_WINDOWS
1007 if (FRAME_X_P (XFRAME (frame)))
1008 /* Warping the mouse will cause enternotify and focus events. */
1009 x_set_mouse_position (XFRAME (frame), x, y);
1010 #endif
1012 return Qnil;
1015 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1016 Sset_mouse_pixel_position, 3, 3, 0,
1017 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1018 WARNING: If you use this under X windows,\n\
1019 you should call `unfocus-frame' afterwards.")
1020 (frame, x, y)
1021 Lisp_Object frame, x, y;
1023 CHECK_LIVE_FRAME (frame, 0);
1024 CHECK_NUMBER (x, 2);
1025 CHECK_NUMBER (y, 1);
1027 /* I think this should be done with a hook. */
1028 #ifdef HAVE_X_WINDOWS
1029 if (FRAME_X_P (XFRAME (frame)))
1030 /* Warping the mouse will cause enternotify and focus events. */
1031 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1032 #endif
1034 return Qnil;
1037 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1038 0, 1, "",
1039 "Make the frame FRAME visible (assuming it is an X-window).\n\
1040 If omitted, FRAME defaults to the currently selected frame.")
1041 (frame)
1042 Lisp_Object frame;
1044 if (NILP (frame))
1045 XSET (frame, Lisp_Frame, selected_frame);
1047 CHECK_LIVE_FRAME (frame, 0);
1049 /* I think this should be done with a hook. */
1050 #ifdef HAVE_X_WINDOWS
1051 if (FRAME_X_P (XFRAME (frame)))
1053 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1054 x_make_frame_visible (XFRAME (frame));
1056 #endif
1058 return frame;
1061 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1062 0, 2, "",
1063 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1064 If omitted, FRAME defaults to the currently selected frame.\n\
1065 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1066 but if the second optional argument FORCE is non-nil, you may do so.")
1067 (frame, force)
1068 Lisp_Object frame, force;
1070 if (NILP (frame))
1071 XSET (frame, Lisp_Frame, selected_frame);
1073 CHECK_LIVE_FRAME (frame, 0);
1075 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1076 error ("Attempt to make invisible the sole visible or iconified frame");
1078 /* Don't let the frame remain selected. */
1079 if (XFRAME (frame) == selected_frame)
1080 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1082 /* Don't allow minibuf_window to remain on a deleted frame. */
1083 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1085 Fset_window_buffer (selected_frame->minibuffer_window,
1086 XWINDOW (minibuf_window)->buffer);
1087 minibuf_window = selected_frame->minibuffer_window;
1090 /* I think this should be done with a hook. */
1091 #ifdef HAVE_X_WINDOWS
1092 if (FRAME_X_P (XFRAME (frame)))
1093 x_make_frame_invisible (XFRAME (frame));
1094 #endif
1096 return Qnil;
1099 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1100 0, 1, "",
1101 "Make the frame FRAME into an icon.\n\
1102 If omitted, FRAME defaults to the currently selected frame.")
1103 (frame)
1104 Lisp_Object frame;
1106 if (NILP (frame))
1107 XSET (frame, Lisp_Frame, selected_frame);
1109 CHECK_LIVE_FRAME (frame, 0);
1111 /* Don't let the frame remain selected. */
1112 if (XFRAME (frame) == selected_frame)
1113 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1115 /* Don't allow minibuf_window to remain on a deleted frame. */
1116 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1118 Fset_window_buffer (selected_frame->minibuffer_window,
1119 XWINDOW (minibuf_window)->buffer);
1120 minibuf_window = selected_frame->minibuffer_window;
1123 /* I think this should be done with a hook. */
1124 #ifdef HAVE_X_WINDOWS
1125 if (FRAME_X_P (XFRAME (frame)))
1126 x_iconify_frame (XFRAME (frame));
1127 #endif
1129 return Qnil;
1132 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1133 1, 1, 0,
1134 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1135 A frame that is not \"visible\" is not updated and, if it works through\n\
1136 a window system, it may not show at all.\n\
1137 Return the symbol `icon' if frame is visible only as an icon.")
1138 (frame)
1139 Lisp_Object frame;
1141 CHECK_LIVE_FRAME (frame, 0);
1143 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1145 if (FRAME_VISIBLE_P (XFRAME (frame)))
1146 return Qt;
1147 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1148 return Qicon;
1149 return Qnil;
1152 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1153 0, 0, 0,
1154 "Return a list of all frames now \"visible\" (being updated).")
1157 Lisp_Object tail, frame;
1158 struct frame *f;
1159 Lisp_Object value;
1161 value = Qnil;
1162 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1164 frame = XCONS (tail)->car;
1165 if (XTYPE (frame) != Lisp_Frame)
1166 continue;
1167 f = XFRAME (frame);
1168 if (FRAME_VISIBLE_P (f))
1169 value = Fcons (frame, value);
1171 return value;
1175 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
1176 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1177 If FRAME is invisible, make it visible.\n\
1178 If Emacs is displaying on an ordinary terminal or some other device which\n\
1179 doesn't support multiple overlapping frames, this function does nothing.")
1180 (frame)
1181 Lisp_Object frame;
1183 CHECK_LIVE_FRAME (frame, 0);
1185 /* Do like the documentation says. */
1186 Fmake_frame_visible (frame);
1188 if (frame_raise_lower_hook)
1189 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1191 return Qnil;
1194 /* Should we have a corresponding function called Flower_Power? */
1195 DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
1196 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1197 If Emacs is displaying on an ordinary terminal or some other device which\n\
1198 doesn't support multiple overlapping frames, this function does nothing.")
1199 (frame)
1200 Lisp_Object frame;
1202 CHECK_LIVE_FRAME (frame, 0);
1204 if (frame_raise_lower_hook)
1205 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1207 return Qnil;
1211 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1212 1, 2, 0,
1213 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1214 In other words, switch-frame events caused by events in FRAME will\n\
1215 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1216 FOCUS-FRAME after reading an event typed at FRAME.\n\
1218 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1219 cancelled, and the frame again receives its own keystrokes.\n\
1221 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1222 a surrogate minibuffer frame when a frame doesn't have its own\n\
1223 minibuffer window.\n\
1225 A frame's focus redirection can be changed by select-frame. If frame\n\
1226 FOO is selected, and then a different frame BAR is selected, any\n\
1227 frames redirecting their focus to FOO are shifted to redirect their\n\
1228 focus to BAR. This allows focus redirection to work properly when the\n\
1229 user switches from one frame to another using `select-window'.\n\
1231 This means that a frame whose focus is redirected to itself is treated\n\
1232 differently from a frame whose focus is redirected to nil; the former\n\
1233 is affected by select-frame, while the latter is not.\n\
1235 The redirection lasts until `redirect-frame-focus' is called to change it.")
1236 (frame, focus_frame)
1237 Lisp_Object frame, focus_frame;
1239 /* Note that we don't check for a live frame here. It's reasonable
1240 to redirect the focus of a frame you're about to delete, if you
1241 know what other frame should receive those keystrokes. */
1242 CHECK_FRAME (frame, 0);
1244 if (! NILP (focus_frame))
1245 CHECK_LIVE_FRAME (focus_frame, 1);
1247 XFRAME (frame)->focus_frame = focus_frame;
1249 /* I think this should be done with a hook. */
1250 #ifdef HAVE_X_WINDOWS
1251 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1252 && FRAME_X_P (XFRAME (focus_frame)))
1253 Ffocus_frame (focus_frame);
1254 #endif
1256 if (frame_rehighlight_hook)
1257 (*frame_rehighlight_hook) ();
1259 return Qnil;
1263 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1264 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1265 This returns nil if FRAME's focus is not redirected.\n\
1266 See `redirect-frame-focus'.")
1267 (frame)
1268 Lisp_Object frame;
1270 CHECK_LIVE_FRAME (frame, 0);
1272 return FRAME_FOCUS_FRAME (XFRAME (frame));
1277 Lisp_Object
1278 get_frame_param (frame, prop)
1279 register struct frame *frame;
1280 Lisp_Object prop;
1282 register Lisp_Object tem;
1284 tem = Fassq (prop, frame->param_alist);
1285 if (EQ (tem, Qnil))
1286 return tem;
1287 return Fcdr (tem);
1290 void
1291 store_in_alist (alistptr, prop, val)
1292 Lisp_Object *alistptr, val;
1293 Lisp_Object prop;
1295 register Lisp_Object tem;
1297 tem = Fassq (prop, *alistptr);
1298 if (EQ (tem, Qnil))
1299 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1300 else
1301 Fsetcdr (tem, val);
1304 void
1305 store_frame_param (f, prop, val)
1306 struct frame *f;
1307 Lisp_Object prop, val;
1309 register Lisp_Object tem;
1311 tem = Fassq (prop, f->param_alist);
1312 if (EQ (tem, Qnil))
1313 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1314 else
1315 Fsetcdr (tem, val);
1317 if (EQ (prop, Qminibuffer)
1318 && XTYPE (val) == Lisp_Window)
1320 if (! MINI_WINDOW_P (XWINDOW (val)))
1321 error ("Surrogate minibuffer windows must be minibuffer windows.");
1323 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1324 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1326 /* Install the chosen minibuffer window, with proper buffer. */
1327 f->minibuffer_window = val;
1331 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1332 "Return the parameters-alist of frame FRAME.\n\
1333 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1334 The meaningful PARMs depend on the kind of frame.\n\
1335 If FRAME is omitted, return information on the currently selected frame.")
1336 (frame)
1337 Lisp_Object frame;
1339 Lisp_Object alist;
1340 struct frame *f;
1342 if (EQ (frame, Qnil))
1343 f = selected_frame;
1344 else
1346 CHECK_FRAME (frame, 0);
1347 f = XFRAME (frame);
1350 if (f->display.nothing == 0)
1351 return Qnil;
1353 alist = Fcopy_alist (f->param_alist);
1354 store_in_alist (&alist, Qname, f->name);
1355 store_in_alist (&alist, Qheight, make_number (f->height));
1356 store_in_alist (&alist, Qwidth, make_number (f->width));
1357 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1358 store_in_alist (&alist, Qminibuffer,
1359 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1360 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1361 : FRAME_MINIBUF_WINDOW (f))));
1362 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1363 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
1365 /* I think this should be done with a hook. */
1366 #ifdef HAVE_X_WINDOWS
1367 if (FRAME_X_P (f))
1368 x_report_frame_params (f, &alist);
1369 #endif
1370 return alist;
1373 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1374 Smodify_frame_parameters, 2, 2, 0,
1375 "Modify the parameters of frame FRAME according to ALIST.\n\
1376 ALIST is an alist of parameters to change and their new values.\n\
1377 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1378 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1379 (frame, alist)
1380 Lisp_Object frame, alist;
1382 FRAME_PTR f;
1383 register Lisp_Object tail, elt, prop, val;
1385 if (EQ (frame, Qnil))
1386 f = selected_frame;
1387 else
1389 CHECK_LIVE_FRAME (frame, 0);
1390 f = XFRAME (frame);
1393 /* I think this should be done with a hook. */
1394 #ifdef HAVE_X_WINDOWS
1395 if (FRAME_X_P (f))
1396 #if 1
1397 x_set_frame_parameters (f, alist);
1398 #else
1399 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1401 elt = Fcar (tail);
1402 prop = Fcar (elt);
1403 val = Fcdr (elt);
1404 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1405 store_frame_param (f, prop, val);
1407 #endif
1408 #endif
1410 return Qnil;
1413 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1414 0, 1, 0,
1415 "Height in pixels of a line in the font in frame FRAME.\n\
1416 If FRAME is omitted, the selected frame is used.\n\
1417 For a terminal frame, the value is always 1.")
1418 (frame)
1419 Lisp_Object frame;
1421 struct frame *f;
1423 if (NILP (frame))
1424 f = selected_frame;
1425 else
1427 CHECK_FRAME (frame, 0);
1428 f = XFRAME (frame);
1431 #ifdef HAVE_X_WINDOWS
1432 if (FRAME_X_P (f))
1433 return make_number (x_char_height (f));
1434 else
1435 #endif
1436 return make_number (1);
1440 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1441 0, 1, 0,
1442 "Width in pixels of characters in the font in frame FRAME.\n\
1443 If FRAME is omitted, the selected frame is used.\n\
1444 The width is the same for all characters, because\n\
1445 currently Emacs supports only fixed-width fonts.\n\
1446 For a terminal screen, the value is always 1.")
1447 (frame)
1448 Lisp_Object frame;
1450 struct frame *f;
1452 if (NILP (frame))
1453 f = selected_frame;
1454 else
1456 CHECK_FRAME (frame, 0);
1457 f = XFRAME (frame);
1460 #ifdef HAVE_X_WINDOWS
1461 if (FRAME_X_P (f))
1462 return make_number (x_char_width (f));
1463 else
1464 #endif
1465 return make_number (1);
1468 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1469 Sframe_pixel_height, 0, 1, 0,
1470 "Return a FRAME's height in pixels.\n\
1471 For a terminal frame, the result really gives the height in characters.\n\
1472 If FRAME is omitted, the selected frame is used.")
1473 (frame)
1474 Lisp_Object frame;
1476 struct frame *f;
1478 if (NILP (frame))
1479 f = selected_frame;
1480 else
1482 CHECK_FRAME (frame, 0);
1483 f = XFRAME (frame);
1486 #ifdef HAVE_X_WINDOWS
1487 if (FRAME_X_P (f))
1488 return make_number (x_pixel_height (f));
1489 else
1490 #endif
1491 return make_number (FRAME_HEIGHT (f));
1494 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1495 Sframe_pixel_width, 0, 1, 0,
1496 "Return FRAME's width in pixels.\n\
1497 For a terminal frame, the result really gives the width in characters.\n\
1498 If FRAME is omitted, the selected frame is used.")
1499 (frame)
1500 Lisp_Object frame;
1502 struct frame *f;
1504 if (NILP (frame))
1505 f = selected_frame;
1506 else
1508 CHECK_FRAME (frame, 0);
1509 f = XFRAME (frame);
1512 #ifdef HAVE_X_WINDOWS
1513 if (FRAME_X_P (f))
1514 return make_number (x_pixel_width (f));
1515 else
1516 #endif
1517 return make_number (FRAME_WIDTH (f));
1520 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1521 "Specify that the frame FRAME has LINES lines.\n\
1522 Optional third arg non-nil means that redisplay should use LINES lines\n\
1523 but that the idea of the actual height of the frame should not be changed.")
1524 (frame, rows, pretend)
1525 Lisp_Object frame, rows, pretend;
1527 register struct frame *f;
1529 CHECK_NUMBER (rows, 0);
1530 if (NILP (frame))
1531 f = selected_frame;
1532 else
1534 CHECK_LIVE_FRAME (frame, 0);
1535 f = XFRAME (frame);
1538 /* I think this should be done with a hook. */
1539 #ifdef HAVE_X_WINDOWS
1540 if (FRAME_X_P (f))
1542 if (XINT (rows) != f->width)
1543 x_set_window_size (f, 1, f->width, XINT (rows));
1545 else
1546 #endif
1547 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1548 return Qnil;
1551 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1552 "Specify that the frame FRAME has COLS columns.\n\
1553 Optional third arg non-nil means that redisplay should use COLS columns\n\
1554 but that the idea of the actual width of the frame should not be changed.")
1555 (frame, cols, pretend)
1556 Lisp_Object frame, cols, pretend;
1558 register struct frame *f;
1559 CHECK_NUMBER (cols, 0);
1560 if (NILP (frame))
1561 f = selected_frame;
1562 else
1564 CHECK_LIVE_FRAME (frame, 0);
1565 f = XFRAME (frame);
1568 /* I think this should be done with a hook. */
1569 #ifdef HAVE_X_WINDOWS
1570 if (FRAME_X_P (f))
1572 if (XINT (cols) != f->width)
1573 x_set_window_size (f, 1, XINT (cols), f->height);
1575 else
1576 #endif
1577 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1578 return Qnil;
1581 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1582 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1583 (frame, cols, rows)
1584 Lisp_Object frame, cols, rows;
1586 register struct frame *f;
1587 int mask;
1589 CHECK_LIVE_FRAME (frame, 0);
1590 CHECK_NUMBER (cols, 2);
1591 CHECK_NUMBER (rows, 1);
1592 f = XFRAME (frame);
1594 /* I think this should be done with a hook. */
1595 #ifdef HAVE_X_WINDOWS
1596 if (FRAME_X_P (f))
1598 if (XINT (rows) != f->height || XINT (cols) != f->width)
1599 x_set_window_size (f, 1, XINT (cols), XINT (rows));
1601 else
1602 #endif
1603 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1605 return Qnil;
1608 DEFUN ("set-frame-position", Fset_frame_position,
1609 Sset_frame_position, 3, 3, 0,
1610 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1611 This is actually the position of the upper left corner of the frame.\n\
1612 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1613 the rightmost or bottommost possible position (that stays within the screen).")
1614 (frame, xoffset, yoffset)
1615 Lisp_Object frame, xoffset, yoffset;
1617 register struct frame *f;
1618 int mask;
1620 CHECK_LIVE_FRAME (frame, 0);
1621 CHECK_NUMBER (xoffset, 1);
1622 CHECK_NUMBER (yoffset, 2);
1623 f = XFRAME (frame);
1625 /* I think this should be done with a hook. */
1626 #ifdef HAVE_X_WINDOWS
1627 if (FRAME_X_P (f))
1628 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
1629 #endif
1631 return Qt;
1635 choose_minibuf_frame ()
1637 /* For lowest-level minibuf, put it on currently selected frame
1638 if frame has a minibuffer. */
1640 if (minibuf_level == 0
1641 && selected_frame != 0
1642 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1644 /* I don't think that any frames may validly have a null minibuffer
1645 window anymore. */
1646 if (NILP (selected_frame->minibuffer_window))
1647 abort ();
1649 Fset_window_buffer (selected_frame->minibuffer_window,
1650 XWINDOW (minibuf_window)->buffer);
1651 minibuf_window = selected_frame->minibuffer_window;
1655 syms_of_frame ()
1657 /*&&& init symbols here &&&*/
1658 Qframep = intern ("framep");
1659 staticpro (&Qframep);
1660 Qframe_live_p = intern ("frame-live-p");
1661 staticpro (&Qframe_live_p);
1662 Qheight = intern ("height");
1663 staticpro (&Qheight);
1664 Qicon = intern ("icon");
1665 staticpro (&Qicon);
1666 Qminibuffer = intern ("minibuffer");
1667 staticpro (&Qminibuffer);
1668 Qmodeline = intern ("modeline");
1669 staticpro (&Qmodeline);
1670 Qname = intern ("name");
1671 staticpro (&Qname);
1672 Qonly = intern ("only");
1673 staticpro (&Qonly);
1674 Qunsplittable = intern ("unsplittable");
1675 staticpro (&Qunsplittable);
1676 Qmenu_bar_lines = intern ("menu-bar-lines");
1677 staticpro (&Qmenu_bar_lines);
1678 Qwidth = intern ("width");
1679 staticpro (&Qwidth);
1680 Qx = intern ("x");
1681 staticpro (&Qx);
1682 Qvisible = intern ("visible");
1683 staticpro (&Qvisible);
1685 staticpro (&Vframe_list);
1687 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1688 "The initial frame-object, which represents Emacs's stdout.");
1690 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1691 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1692 Vemacs_iconified = Qnil;
1694 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1695 "Minibufferless frames use this frame's minibuffer.\n\
1697 Emacs cannot create minibufferless frames unless this is set to an\n\
1698 appropriate surrogate.\n\
1700 Emacs consults this variable only when creating minibufferless\n\
1701 frames; once the frame is created, it sticks with its assigned\n\
1702 minibuffer, no matter what this variable is set to. This means that\n\
1703 this variable doesn't necessarily say anything meaningful about the\n\
1704 current set of frames, or where the minibuffer is currently being\n\
1705 displayed.");
1706 Vdefault_minibuffer_frame = Qnil;
1708 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1709 "Alist of default values for frame creation.\n\
1710 These may be set in your init file, like this:\n\
1711 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1712 These override values given in window system configuration data, like\n\
1713 X Windows' defaults database.\n\
1714 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1715 For values specific to the separate minibuffer frame, see\n\
1716 `minibuffer-frame-alist'.");
1717 Vdefault_frame_alist = Qnil;
1719 defsubr (&Sframep);
1720 defsubr (&Sframe_live_p);
1721 defsubr (&Shandle_switch_frame);
1722 defsubr (&Sselect_frame);
1723 defsubr (&Sselected_frame);
1724 defsubr (&Swindow_frame);
1725 defsubr (&Sframe_root_window);
1726 defsubr (&Sframe_selected_window);
1727 defsubr (&Sset_frame_selected_window);
1728 defsubr (&Sframe_list);
1729 defsubr (&Snext_frame);
1730 defsubr (&Sprevious_frame);
1731 defsubr (&Sdelete_frame);
1732 defsubr (&Smouse_position);
1733 defsubr (&Smouse_pixel_position);
1734 defsubr (&Sset_mouse_position);
1735 defsubr (&Sset_mouse_pixel_position);
1736 #if 0
1737 defsubr (&Sframe_configuration);
1738 defsubr (&Srestore_frame_configuration);
1739 #endif
1740 defsubr (&Smake_frame_visible);
1741 defsubr (&Smake_frame_invisible);
1742 defsubr (&Siconify_frame);
1743 defsubr (&Sframe_visible_p);
1744 defsubr (&Svisible_frame_list);
1745 defsubr (&Sraise_frame);
1746 defsubr (&Slower_frame);
1747 defsubr (&Sredirect_frame_focus);
1748 defsubr (&Sframe_focus);
1749 defsubr (&Sframe_parameters);
1750 defsubr (&Smodify_frame_parameters);
1751 defsubr (&Sframe_char_height);
1752 defsubr (&Sframe_char_width);
1753 defsubr (&Sframe_pixel_height);
1754 defsubr (&Sframe_pixel_width);
1755 defsubr (&Sset_frame_height);
1756 defsubr (&Sset_frame_width);
1757 defsubr (&Sset_frame_size);
1758 defsubr (&Sset_frame_position);
1761 keys_of_frame ()
1763 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
1766 #else /* not MULTI_FRAME */
1768 /* If we're not using multi-frame stuff, we still need to provide some
1769 support functions. */
1771 Lisp_Object Vterminal_frame;
1773 /* Unless this function is defined, providing set-frame-height and
1774 set-frame-width doesn't help compatibility any, since they both
1775 want this as their first argument. */
1776 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1777 /* Don't confuse make-docfile by having two doc strings for this function.
1778 make-docfile does not pay attention to #if, for good reason! */
1782 Lisp_Object tem;
1783 XFASTINT (tem) = 0;
1784 return tem;
1786 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1787 /* Don't confuse make-docfile by having two doc strings for this function.
1788 make-docfile does not pay attention to #if, for good reason! */
1790 (object)
1791 Lisp_Object object;
1793 return Qnil;
1796 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1797 /* Don't confuse make-docfile by having two doc strings for this function.
1798 make-docfile does not pay attention to #if, for good reason! */
1800 (frame, rows, pretend)
1801 Lisp_Object frame, rows, pretend;
1803 CHECK_NUMBER (rows, 0);
1805 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1806 return Qnil;
1809 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1810 /* Don't confuse make-docfile by having two doc strings for this function.
1811 make-docfile does not pay attention to #if, for good reason! */
1813 (frame, cols, pretend)
1814 Lisp_Object frame, cols, pretend;
1816 CHECK_NUMBER (cols, 0);
1818 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1819 return Qnil;
1822 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1823 /* Don't confuse make-docfile by having two doc strings for this function.
1824 make-docfile does not pay attention to #if, for good reason! */
1826 (frame, cols, rows)
1827 Lisp_Object frame, cols, rows;
1829 CHECK_NUMBER (cols, 2);
1830 CHECK_NUMBER (rows, 1);
1832 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1834 return Qnil;
1837 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1838 "Return number of lines available for display on FRAME.\n\
1839 If FRAME is omitted, describe the currently selected frame.")
1840 (frame)
1841 Lisp_Object frame;
1843 return make_number (FRAME_HEIGHT (selected_frame));
1846 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1847 "Return number of columns available for display on FRAME.\n\
1848 If FRAME is omitted, describe the currently selected frame.")
1849 (frame)
1850 Lisp_Object frame;
1852 return make_number (FRAME_WIDTH (selected_frame));
1855 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1856 0, 1, 0,
1857 /* Don't confuse make-docfile by having two doc strings for this function.
1858 make-docfile does not pay attention to #if, for good reason! */
1860 (frame)
1861 Lisp_Object frame;
1863 return make_number (1);
1867 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1868 0, 1, 0,
1869 /* Don't confuse make-docfile by having two doc strings for this function.
1870 make-docfile does not pay attention to #if, for good reason! */
1872 (frame)
1873 Lisp_Object frame;
1875 return make_number (1);
1878 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1879 Sframe_pixel_height, 0, 1, 0,
1880 /* Don't confuse make-docfile by having two doc strings for this function.
1881 make-docfile does not pay attention to #if, for good reason! */
1883 (frame)
1884 Lisp_Object frame;
1886 return make_number (FRAME_HEIGHT (f));
1889 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1890 Sframe_pixel_width, 0, 1, 0,
1891 /* Don't confuse make-docfile by having two doc strings for this function.
1892 make-docfile does not pay attention to #if, for good reason! */
1894 (frame)
1895 Lisp_Object frame;
1897 return make_number (FRAME_WIDTH (f));
1900 /* These are for backward compatibility with Emacs 18. */
1902 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1903 "Tell redisplay that the screen has LINES lines.\n\
1904 Optional second arg non-nil means that redisplay should use LINES lines\n\
1905 but that the idea of the actual height of the screen should not be changed.")
1906 (lines, pretend)
1907 Lisp_Object lines, pretend;
1909 CHECK_NUMBER (lines, 0);
1911 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1912 return Qnil;
1915 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1916 "Tell redisplay that the screen has COLS columns.\n\
1917 Optional second arg non-nil means that redisplay should use COLS columns\n\
1918 but that the idea of the actual width of the screen should not be changed.")
1919 (cols, pretend)
1920 Lisp_Object cols, pretend;
1922 CHECK_NUMBER (cols, 0);
1924 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1925 return Qnil;
1928 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1929 /* Don't confuse make-docfile by having two doc strings for this function.
1930 make-docfile does not pay attention to #if, for good reason! */
1934 return Fcons (Qnil, Fcons (Qnil, Qnil));
1937 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1938 /* Don't confuse make-docfile by having two doc strings for this function.
1939 make-docfile does not pay attention to #if, for good reason! */
1941 (frame)
1942 Lisp_Object frame;
1944 return Qnil;
1947 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1948 Smodify_frame_parameters, 2, 2, 0,
1949 /* Don't confuse make-docfile by having two doc strings for this function.
1950 make-docfile does not pay attention to #if, for good reason! */
1952 (frame, alist)
1953 Lisp_Object frame, alist;
1955 return Qnil;
1958 syms_of_frame ()
1960 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1961 "The initial frame-object, which represents Emacs's stdout.");
1962 XFASTINT (Vterminal_frame) = 0;
1964 defsubr (&Sselected_frame);
1965 defsubr (&Sframep);
1966 defsubr (&Sframe_char_height);
1967 defsubr (&Sframe_char_width);
1968 defsubr (&Sframe_pixel_height);
1969 defsubr (&Sframe_pixel_width);
1970 defsubr (&Sset_frame_height);
1971 defsubr (&Sset_frame_width);
1972 defsubr (&Sset_frame_size);
1973 defsubr (&Sset_screen_height);
1974 defsubr (&Sset_screen_width);
1975 defsubr (&Sframe_height);
1976 Ffset (intern ("screen-height"), intern ("frame-height"));
1977 defsubr (&Sframe_width);
1978 Ffset (intern ("screen-width"), intern ("frame-width"));
1979 defsubr (&Smouse_position);
1980 defsubr (&Sframe_parameters);
1981 defsubr (&Smodify_frame_parameters);
1984 keys_of_frame ()
1988 #endif /* not MULTI_FRAME */