(x_consider_frame_title, decode_mode_spec): Use assignment, not initialization.
[emacs.git] / src / frame.c
blobb11a40a61a30b94f78a7590ee531805d3c46b3ab
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;
172 root_window = make_window ();
173 if (mini_p)
175 mini_window = make_window ();
176 XWINDOW (root_window)->next = mini_window;
177 XWINDOW (mini_window)->prev = root_window;
178 XWINDOW (mini_window)->mini_p = Qt;
179 XWINDOW (mini_window)->frame = frame;
180 f->minibuffer_window = mini_window;
182 else
184 mini_window = Qnil;
185 XWINDOW (root_window)->next = Qnil;
186 f->minibuffer_window = Qnil;
189 XWINDOW (root_window)->frame = frame;
191 /* 10 is arbitrary,
192 just so that there is "something there."
193 Correct size will be set up later with change_frame_size. */
195 f->width = 10;
196 f->height = 10;
198 XFASTINT (XWINDOW (root_window)->width) = 10;
199 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
201 if (mini_p)
203 XFASTINT (XWINDOW (mini_window)->width) = 10;
204 XFASTINT (XWINDOW (mini_window)->top) = 9;
205 XFASTINT (XWINDOW (mini_window)->height) = 1;
208 /* Choose a buffer for the frame's root window. */
210 Lisp_Object buf;
212 XWINDOW (root_window)->buffer = Qt;
213 buf = Fcurrent_buffer ();
214 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
215 a space), try to find another one. */
216 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
217 buf = Fother_buffer (buf, Qnil);
218 Fset_window_buffer (root_window, buf);
221 if (mini_p)
223 XWINDOW (mini_window)->buffer = Qt;
224 Fset_window_buffer (mini_window,
225 (NILP (Vminibuffer_list)
226 ? get_minibuffer (0)
227 : Fcar (Vminibuffer_list)));
230 f->root_window = root_window;
231 f->selected_window = root_window;
232 /* Make sure this window seems more recently used than
233 a newly-created, never-selected window. */
234 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
236 return f;
239 /* Make a frame using a separate minibuffer window on another frame.
240 MINI_WINDOW is the minibuffer window to use. nil means use the
241 default (the global minibuffer). */
243 struct frame *
244 make_frame_without_minibuffer (mini_window)
245 register Lisp_Object mini_window;
247 register struct frame *f;
249 /* Choose the minibuffer window to use. */
250 if (NILP (mini_window))
252 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
253 error ("default-minibuffer-frame must be set when creating minibufferless frames");
254 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
255 error ("default-minibuffer-frame must be a live frame");
256 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
258 else
260 CHECK_LIVE_WINDOW (mini_window, 0);
263 /* Make a frame containing just a root window. */
264 f = make_frame (0);
266 /* Install the chosen minibuffer window, with proper buffer. */
267 f->minibuffer_window = mini_window;
268 Fset_window_buffer (mini_window,
269 (NILP (Vminibuffer_list)
270 ? get_minibuffer (0)
271 : Fcar (Vminibuffer_list)));
272 return f;
275 /* Make a frame containing only a minibuffer window. */
277 struct frame *
278 make_minibuffer_frame ()
280 /* First make a frame containing just a root window, no minibuffer. */
282 register struct frame *f = make_frame (0);
283 register Lisp_Object mini_window;
284 register Lisp_Object frame;
286 XSET (frame, Lisp_Frame, f);
288 f->auto_raise = 0;
289 f->auto_lower = 0;
290 f->no_split = 1;
291 f->wants_modeline = 0;
292 f->has_minibuffer = 1;
294 /* Now label the root window as also being the minibuffer.
295 Avoid infinite looping on the window chain by marking next pointer
296 as nil. */
298 mini_window = f->minibuffer_window = f->root_window;
299 XWINDOW (mini_window)->mini_p = Qt;
300 XWINDOW (mini_window)->next = Qnil;
301 XWINDOW (mini_window)->prev = Qnil;
302 XWINDOW (mini_window)->frame = frame;
304 /* Put the proper buffer in that window. */
306 Fset_window_buffer (mini_window,
307 (NILP (Vminibuffer_list)
308 ? get_minibuffer (0)
309 : Fcar (Vminibuffer_list)));
310 return f;
313 /* Construct a frame that refers to the terminal (stdin and stdout). */
315 struct frame *
316 make_terminal_frame ()
318 register struct frame *f;
319 Lisp_Object frame;
321 Vframe_list = Qnil;
322 f = make_frame (1);
324 XSET (frame, Lisp_Frame, f);
325 Vframe_list = Fcons (frame, Vframe_list);
327 f->name = build_string ("terminal");
328 FRAME_SET_VISIBLE (f, 1);
329 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
330 XSET (Vterminal_frame, Lisp_Frame, f);
331 return f;
334 static Lisp_Object
335 do_switch_frame (frame, no_enter, track)
336 Lisp_Object frame, no_enter;
337 int track;
339 /* If FRAME is a switch-frame event, extract the frame we should
340 switch to. */
341 if (CONSP (frame)
342 && EQ (XCONS (frame)->car, Qswitch_frame)
343 && CONSP (XCONS (frame)->cdr))
344 frame = XCONS (XCONS (frame)->cdr)->car;
346 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
347 a switch-frame event to arrive after a frame is no longer live,
348 especially when deleting the initial frame during startup. */
349 CHECK_FRAME (frame, 0);
350 if (! FRAME_LIVE_P (XFRAME (frame)))
351 return Qnil;
353 if (selected_frame == XFRAME (frame))
354 return frame;
356 /* This is too greedy; it causes inappropriate focus redirection
357 that's hard to get rid of. */
358 #if 0
359 /* If a frame's focus has been redirected toward the currently
360 selected frame, we should change the redirection to point to the
361 newly selected frame. This means that if the focus is redirected
362 from a minibufferless frame to a surrogate minibuffer frame, we
363 can use `other-window' to switch between all the frames using
364 that minibuffer frame, and the focus redirection will follow us
365 around. */
366 if (track)
368 Lisp_Object tail;
370 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
372 Lisp_Object focus;
374 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
375 abort ();
377 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
379 if (XTYPE (focus) == Lisp_Frame
380 && XFRAME (focus) == selected_frame)
381 Fredirect_frame_focus (XCONS (tail)->car, frame);
384 #else /* ! 0 */
385 /* Instead, apply it only to the frame we're pointing to. */
386 #ifdef HAVE_X_WINDOWS
387 if (track)
389 Lisp_Object focus, xfocus;
391 xfocus = x_get_focus_frame ();
392 if (FRAMEP (xfocus))
394 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
395 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
396 Fredirect_frame_focus (xfocus, frame);
399 #endif /* HAVE_X_WINDOWS */
400 #endif /* ! 0 */
402 selected_frame = XFRAME (frame);
403 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
404 last_nonminibuf_frame = selected_frame;
406 Fselect_window (XFRAME (frame)->selected_window);
407 choose_minibuf_frame ();
409 /* We want to make sure that the next event generates a frame-switch
410 event to the appropriate frame. This seems kludgy to me, but
411 before you take it out, make sure that evaluating something like
412 (select-window (frame-root-window (new-frame))) doesn't end up
413 with your typing being interpreted in the new frame instead of
414 the one you're actually typing in. */
415 internal_last_event_frame = Qnil;
417 return frame;
420 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
421 "Select the frame FRAME.\n\
422 Subsequent editing commands apply to its selected window.\n\
423 The selection of FRAME lasts until the next time the user does\n\
424 something to select a different frame, or until the next time this\n\
425 function is called.")
426 (frame, no_enter)
427 Lisp_Object frame, no_enter;
429 return do_switch_frame (frame, no_enter, 1);
433 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
434 "Handle a switch-frame event EVENT.\n\
435 Switch-frame events are usually bound to this function.\n\
436 A switch-frame event tells Emacs that the window manager has requested\n\
437 that the user's events be directed to the frame mentioned in the event.\n\
438 This function selects the selected window of the frame of EVENT.\n\
440 If EVENT is frame object, handle it as if it were a switch-frame event\n\
441 to that frame.")
442 (frame, no_enter)
443 Lisp_Object frame, no_enter;
445 return do_switch_frame (frame, no_enter, 0);
449 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
450 "Return the frame that is now selected.")
453 Lisp_Object tem;
454 XSET (tem, Lisp_Frame, selected_frame);
455 return tem;
458 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
459 "Return the frame object that window WINDOW is on.")
460 (window)
461 Lisp_Object window;
463 CHECK_LIVE_WINDOW (window, 0);
464 return XWINDOW (window)->frame;
467 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
468 "Returns the root-window of FRAME.\n\
469 If omitted, FRAME defaults to the currently selected frame.")
470 (frame)
471 Lisp_Object frame;
473 if (NILP (frame))
474 XSET (frame, Lisp_Frame, selected_frame);
475 else
476 CHECK_LIVE_FRAME (frame, 0);
478 return XFRAME (frame)->root_window;
481 DEFUN ("frame-selected-window", Fframe_selected_window,
482 Sframe_selected_window, 0, 1, 0,
483 "Return the selected window of frame object FRAME.\n\
484 If omitted, FRAME defaults to the currently selected frame.")
485 (frame)
486 Lisp_Object frame;
488 if (NILP (frame))
489 XSET (frame, Lisp_Frame, selected_frame);
490 else
491 CHECK_LIVE_FRAME (frame, 0);
493 return XFRAME (frame)->selected_window;
496 DEFUN ("frame-list", Fframe_list, Sframe_list,
497 0, 0, 0,
498 "Return a list of all frames.")
501 return Fcopy_sequence (Vframe_list);
504 /* Return the next frame in the frame list after FRAME.
505 If MINIBUF is nil, exclude minibuffer-only frames.
506 If MINIBUF is a window, include only frames using that window for
507 their minibuffer.
508 If MINIBUF is `visible', include all visible frames.
509 Otherwise, include all frames. */
511 Lisp_Object
512 next_frame (frame, minibuf)
513 Lisp_Object frame;
514 Lisp_Object minibuf;
516 Lisp_Object tail;
517 int passed = 0;
519 /* There must always be at least one frame in Vframe_list. */
520 if (! CONSP (Vframe_list))
521 abort ();
523 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
524 forever. Forestall that. */
525 CHECK_LIVE_FRAME (frame, 0);
527 while (1)
528 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
530 Lisp_Object f;
532 f = XCONS (tail)->car;
533 if (passed)
535 /* Decide whether this frame is eligible to be returned. */
537 /* If we've looped all the way around without finding any
538 eligible frames, return the original frame. */
539 if (EQ (f, frame))
540 return f;
542 /* Let minibuf decide if this frame is acceptable. */
543 if (NILP (minibuf))
545 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
546 return f;
548 else if (EQ (minibuf, Qvisible))
550 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
551 if (FRAME_VISIBLE_P (XFRAME (f)))
552 return f;
554 else if (WINDOWP (minibuf))
556 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
557 return f;
559 else
560 return f;
563 if (EQ (frame, f))
564 passed++;
568 /* Return the previous frame in the frame list before FRAME.
569 If MINIBUF is nil, exclude minibuffer-only frames.
570 If MINIBUF is a window, include only frames using that window for
571 their minibuffer.
572 If MINIBUF is `visible', include all visible frames.
573 Otherwise, include all frames. */
575 Lisp_Object
576 prev_frame (frame, minibuf)
577 Lisp_Object frame;
578 Lisp_Object minibuf;
580 Lisp_Object tail;
581 Lisp_Object prev;
583 /* There must always be at least one frame in Vframe_list. */
584 if (! CONSP (Vframe_list))
585 abort ();
587 prev = Qnil;
588 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
590 Lisp_Object f;
592 f = XCONS (tail)->car;
593 if (XTYPE (f) != Lisp_Frame)
594 abort ();
596 if (EQ (frame, f) && !NILP (prev))
597 return prev;
599 /* Decide whether this frame is eligible to be returned,
600 according to minibuf. */
601 if (NILP (minibuf))
603 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
604 prev = f;
606 else if (XTYPE (minibuf) == Lisp_Window)
608 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
609 prev = f;
611 else if (EQ (minibuf, Qvisible))
613 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
614 if (FRAME_VISIBLE_P (XFRAME (f)))
615 prev = f;
617 else
618 prev = f;
621 /* We've scanned the entire list. */
622 if (NILP (prev))
623 /* We went through the whole frame list without finding a single
624 acceptable frame. Return the original frame. */
625 return frame;
626 else
627 /* There were no acceptable frames in the list before FRAME; otherwise,
628 we would have returned directly from the loop. Since PREV is the last
629 acceptable frame in the list, return it. */
630 return prev;
634 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
635 "Return the next frame in the frame list after FRAME.\n\
636 By default, skip minibuffer-only frames.\n\
637 If omitted, FRAME defaults to the selected frame.\n\
638 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
639 If MINIFRAME is a window, include only frames using that window for their\n\
640 minibuffer.\n\
641 If MINIFRAME is `visible', include all visible frames.\n\
642 Otherwise, include all frames.")
643 (frame, miniframe)
644 Lisp_Object frame, miniframe;
646 Lisp_Object tail;
648 if (NILP (frame))
649 XSET (frame, Lisp_Frame, selected_frame);
650 else
651 CHECK_LIVE_FRAME (frame, 0);
653 return next_frame (frame, miniframe);
656 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
657 "Return the previous frame in the frame list before FRAME.\n\
658 By default, skip minibuffer-only frames.\n\
659 If omitted, FRAME defaults to the selected frame.\n\
660 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
661 If MINIFRAME is a window, include only frames using that window for their\n\
662 minibuffer.\n\
663 If MINIFRAME is `visible', include all visible frames.\n\
664 Otherwise, include all frames.")
665 (frame, miniframe)
666 Lisp_Object frame, miniframe;
668 Lisp_Object tail;
670 if (NILP (frame))
671 XSET (frame, Lisp_Frame, selected_frame);
672 else
673 CHECK_LIVE_FRAME (frame, 0);
675 return prev_frame (frame, miniframe);
678 /* Return 1 if it is ok to delete frame F;
679 0 if all frames aside from F are invisible.
680 (Exception: if F is the terminal frame, and we are using X, return 1.) */
682 static int
683 other_visible_frames (f)
684 FRAME_PTR f;
686 /* We know the selected frame is visible,
687 so if F is some other frame, it can't be the sole visible one. */
688 if (f == selected_frame)
690 Lisp_Object frames;
691 int count = 0;
693 for (frames = Vframe_list;
694 CONSP (frames);
695 frames = XCONS (frames)->cdr)
697 Lisp_Object this;
699 this = XCONS (frames)->car;
700 /* Verify that the frame's window still exists
701 and we can still talk to it. And note any recent change
702 in visibility. */
703 #ifdef HAVE_X_WINDOWS
704 if (FRAME_X_P (XFRAME (this)))
706 x_sync (this);
707 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
709 #endif
711 if (FRAME_VISIBLE_P (XFRAME (this))
712 || FRAME_ICONIFIED_P (XFRAME (this))
713 /* Allow deleting the terminal frame when at least
714 one X frame exists! */
715 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
716 count++;
718 return count > 1;
720 return 1;
723 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
724 "Delete FRAME, permanently eliminating it from use.\n\
725 If omitted, FRAME defaults to the selected frame.\n\
726 A frame may not be deleted if its minibuffer is used by other frames.\n\
727 Normally, you may not delete a frame if all other frames are invisible,\n\
728 but if the second optional argument FORCE is non-nil, you may do so.")
729 (frame, force)
730 Lisp_Object frame, force;
732 struct frame *f;
734 if (EQ (frame, Qnil))
736 f = selected_frame;
737 XSET (frame, Lisp_Frame, f);
739 else
741 CHECK_FRAME (frame, 0);
742 f = XFRAME (frame);
745 if (! FRAME_LIVE_P (f))
746 return Qnil;
748 if (NILP (force) && !other_visible_frames (f))
749 error ("Attempt to delete the sole visible or iconified frame");
751 /* Does this frame have a minibuffer, and is it the surrogate
752 minibuffer for any other frame? */
753 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
755 Lisp_Object frames;
757 for (frames = Vframe_list;
758 CONSP (frames);
759 frames = XCONS (frames)->cdr)
761 Lisp_Object this;
762 this = XCONS (frames)->car;
764 if (! EQ (this, frame)
765 && EQ (frame,
766 WINDOW_FRAME (XWINDOW
767 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
768 error ("Attempt to delete a surrogate minibuffer frame");
772 /* Don't let the frame remain selected. */
773 if (f == selected_frame)
774 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
776 /* Don't allow minibuf_window to remain on a deleted frame. */
777 if (EQ (f->minibuffer_window, minibuf_window))
779 Fset_window_buffer (selected_frame->minibuffer_window,
780 XWINDOW (minibuf_window)->buffer);
781 minibuf_window = selected_frame->minibuffer_window;
784 /* Mark all the windows that used to be on FRAME as deleted, and then
785 remove the reference to them. */
786 delete_all_subwindows (XWINDOW (f->root_window));
787 f->root_window = Qnil;
789 Vframe_list = Fdelq (frame, Vframe_list);
790 FRAME_SET_VISIBLE (f, 0);
792 /* Since some events are handled at the interrupt level, we may get
793 an event for f at any time; if we zero out the frame's display
794 now, then we may trip up the event-handling code. Instead, we'll
795 promise that the display of the frame must be valid until we have
796 called the window-system-dependent frame destruction routine. */
798 /* I think this should be done with a hook. */
799 #ifdef HAVE_X_WINDOWS
800 if (FRAME_X_P (f))
801 x_destroy_window (f);
802 #endif
804 f->display.nothing = 0;
806 /* If we've deleted the last_nonminibuf_frame, then try to find
807 another one. */
808 if (f == last_nonminibuf_frame)
810 Lisp_Object frames;
812 last_nonminibuf_frame = 0;
814 for (frames = Vframe_list;
815 CONSP (frames);
816 frames = XCONS (frames)->cdr)
818 f = XFRAME (XCONS (frames)->car);
819 if (!FRAME_MINIBUF_ONLY_P (f))
821 last_nonminibuf_frame = f;
822 break;
827 /* If we've deleted Vdefault_minibuffer_frame, try to find another
828 one. Prefer minibuffer-only frames, but also notice frames
829 with other windows. */
830 if (EQ (frame, Vdefault_minibuffer_frame))
832 Lisp_Object frames;
834 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
835 Lisp_Object frame_with_minibuf;
837 frame_with_minibuf = Qnil;
838 for (frames = Vframe_list;
839 CONSP (frames);
840 frames = XCONS (frames)->cdr)
842 Lisp_Object this;
844 this = XCONS (frames)->car;
845 if (XTYPE (this) != Lisp_Frame)
846 abort ();
847 f = XFRAME (this);
849 if (FRAME_HAS_MINIBUF_P (f))
851 frame_with_minibuf = this;
852 if (FRAME_MINIBUF_ONLY_P (f))
853 break;
857 /* We know that there must be some frame with a minibuffer out
858 there. If this were not true, all of the frames present
859 would have to be minibufferless, which implies that at some
860 point their minibuffer frames must have been deleted, but
861 that is prohibited at the top; you can't delete surrogate
862 minibuffer frames. */
863 if (NILP (frame_with_minibuf))
864 abort ();
866 Vdefault_minibuffer_frame = frame_with_minibuf;
869 return Qnil;
872 /* Return mouse position in character cell units. */
874 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
875 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
876 The position is given in character cells, where (0, 0) is the\n\
877 upper-left corner.\n\
878 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
879 to read the mouse position, it returns the selected frame for FRAME\n\
880 and nil for X and Y.")
883 FRAME_PTR f;
884 Lisp_Object lispy_dummy;
885 enum scroll_bar_part party_dummy;
886 Lisp_Object x, y;
887 int col, row;
888 unsigned long long_dummy;
890 f = selected_frame;
891 x = y = Qnil;
893 /* It's okay for the hook to refrain from storing anything. */
894 if (mouse_position_hook)
895 (*mouse_position_hook) (&f,
896 &lispy_dummy, &party_dummy,
897 &x, &y,
898 &long_dummy);
899 col = XINT (x);
900 row = XINT (y);
901 glyph_to_pixel_coords (f, col, row, &col, &row);
902 XSETINT (x, col);
903 XSETINT (y, row);
904 XSET (lispy_dummy, Lisp_Frame, f);
905 return Fcons (lispy_dummy, Fcons (x, y));
908 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
909 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
910 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
911 (frame, x, y)
912 Lisp_Object frame, x, y;
914 CHECK_LIVE_FRAME (frame, 0);
915 CHECK_NUMBER (x, 2);
916 CHECK_NUMBER (y, 1);
918 /* I think this should be done with a hook. */
919 #ifdef HAVE_X_WINDOWS
920 if (FRAME_X_P (XFRAME (frame)))
921 /* Warping the mouse will cause enternotify and focus events. */
922 x_set_mouse_position (XFRAME (frame), x, y);
923 #endif
925 return Qnil;
928 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
929 0, 1, "",
930 "Make the frame FRAME visible (assuming it is an X-window).\n\
931 If omitted, FRAME defaults to the currently selected frame.")
932 (frame)
933 Lisp_Object frame;
935 if (NILP (frame))
936 XSET (frame, Lisp_Frame, selected_frame);
938 CHECK_LIVE_FRAME (frame, 0);
940 /* I think this should be done with a hook. */
941 #ifdef HAVE_X_WINDOWS
942 if (FRAME_X_P (XFRAME (frame)))
944 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
945 x_make_frame_visible (XFRAME (frame));
947 #endif
949 return frame;
952 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
953 0, 2, "",
954 "Make the frame FRAME invisible (assuming it is an X-window).\n\
955 If omitted, FRAME defaults to the currently selected frame.\n\
956 Normally you may not make FRAME invisible if all other frames are invisible,\n\
957 but if the second optional argument FORCE is non-nil, you may do so.")
958 (frame, force)
959 Lisp_Object frame, force;
961 if (NILP (frame))
962 XSET (frame, Lisp_Frame, selected_frame);
964 CHECK_LIVE_FRAME (frame, 0);
966 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
967 error ("Attempt to make invisible the sole visible or iconified frame");
969 /* Don't let the frame remain selected. */
970 if (XFRAME (frame) == selected_frame)
971 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
973 /* Don't allow minibuf_window to remain on a deleted frame. */
974 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
976 Fset_window_buffer (selected_frame->minibuffer_window,
977 XWINDOW (minibuf_window)->buffer);
978 minibuf_window = selected_frame->minibuffer_window;
981 /* I think this should be done with a hook. */
982 #ifdef HAVE_X_WINDOWS
983 if (FRAME_X_P (XFRAME (frame)))
984 x_make_frame_invisible (XFRAME (frame));
985 #endif
987 return Qnil;
990 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
991 0, 1, "",
992 "Make the frame FRAME into an icon.\n\
993 If omitted, FRAME defaults to the currently selected frame.")
994 (frame)
995 Lisp_Object frame;
997 if (NILP (frame))
998 XSET (frame, Lisp_Frame, selected_frame);
1000 CHECK_LIVE_FRAME (frame, 0);
1002 /* Don't let the frame remain selected. */
1003 if (XFRAME (frame) == selected_frame)
1004 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1006 /* Don't allow minibuf_window to remain on a deleted frame. */
1007 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1009 Fset_window_buffer (selected_frame->minibuffer_window,
1010 XWINDOW (minibuf_window)->buffer);
1011 minibuf_window = selected_frame->minibuffer_window;
1014 /* I think this should be done with a hook. */
1015 #ifdef HAVE_X_WINDOWS
1016 if (FRAME_X_P (XFRAME (frame)))
1017 x_iconify_frame (XFRAME (frame));
1018 #endif
1020 return Qnil;
1023 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1024 1, 1, 0,
1025 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1026 A frame that is not \"visible\" is not updated and, if it works through\n\
1027 a window system, it may not show at all.\n\
1028 Return the symbol `icon' if frame is visible only as an icon.")
1029 (frame)
1030 Lisp_Object frame;
1032 CHECK_LIVE_FRAME (frame, 0);
1034 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1036 if (FRAME_VISIBLE_P (XFRAME (frame)))
1037 return Qt;
1038 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1039 return Qicon;
1040 return Qnil;
1043 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1044 0, 0, 0,
1045 "Return a list of all frames now \"visible\" (being updated).")
1048 Lisp_Object tail, frame;
1049 struct frame *f;
1050 Lisp_Object value;
1052 value = Qnil;
1053 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1055 frame = XCONS (tail)->car;
1056 if (XTYPE (frame) != Lisp_Frame)
1057 continue;
1058 f = XFRAME (frame);
1059 if (FRAME_VISIBLE_P (f))
1060 value = Fcons (frame, value);
1062 return value;
1066 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
1067 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1068 If FRAME is invisible, make it visible.\n\
1069 If Emacs is displaying on an ordinary terminal or some other device which\n\
1070 doesn't support multiple overlapping frames, this function does nothing.")
1071 (frame)
1072 Lisp_Object frame;
1074 CHECK_LIVE_FRAME (frame, 0);
1076 /* Do like the documentation says. */
1077 Fmake_frame_visible (frame);
1079 if (frame_raise_lower_hook)
1080 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1082 return Qnil;
1085 /* Should we have a corresponding function called Flower_Power? */
1086 DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
1087 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1088 If Emacs is displaying on an ordinary terminal or some other device which\n\
1089 doesn't support multiple overlapping frames, this function does nothing.")
1090 (frame)
1091 Lisp_Object frame;
1093 CHECK_LIVE_FRAME (frame, 0);
1095 if (frame_raise_lower_hook)
1096 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1098 return Qnil;
1102 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1103 1, 2, 0,
1104 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1105 In other words, switch-frame events caused by events in FRAME will\n\
1106 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1107 FOCUS-FRAME after reading an event typed at FRAME.\n\
1109 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1110 cancelled, and the frame again receives its own keystrokes.\n\
1112 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1113 a surrogate minibuffer frame when a frame doesn't have its own\n\
1114 minibuffer window.\n\
1116 A frame's focus redirection can be changed by select-frame. If frame\n\
1117 FOO is selected, and then a different frame BAR is selected, any\n\
1118 frames redirecting their focus to FOO are shifted to redirect their\n\
1119 focus to BAR. This allows focus redirection to work properly when the\n\
1120 user switches from one frame to another using `select-window'.\n\
1122 This means that a frame whose focus is redirected to itself is treated\n\
1123 differently from a frame whose focus is redirected to nil; the former\n\
1124 is affected by select-frame, while the latter is not.\n\
1126 The redirection lasts until `redirect-frame-focus' is called to change it.")
1127 (frame, focus_frame)
1128 Lisp_Object frame, focus_frame;
1130 /* Note that we don't check for a live frame here. It's reasonable
1131 to redirect the focus of a frame you're about to delete, if you
1132 know what other frame should receive those keystrokes. */
1133 CHECK_FRAME (frame, 0);
1135 if (! NILP (focus_frame))
1136 CHECK_LIVE_FRAME (focus_frame, 1);
1138 XFRAME (frame)->focus_frame = focus_frame;
1140 /* I think this should be done with a hook. */
1141 #ifdef HAVE_X_WINDOWS
1142 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1143 && FRAME_X_P (XFRAME (focus_frame)))
1144 Ffocus_frame (focus_frame);
1145 #endif
1147 if (frame_rehighlight_hook)
1148 (*frame_rehighlight_hook) ();
1150 return Qnil;
1154 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1155 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1156 This returns nil if FRAME's focus is not redirected.\n\
1157 See `redirect-frame-focus'.")
1158 (frame)
1159 Lisp_Object frame;
1161 CHECK_LIVE_FRAME (frame, 0);
1163 return FRAME_FOCUS_FRAME (XFRAME (frame));
1168 Lisp_Object
1169 get_frame_param (frame, prop)
1170 register struct frame *frame;
1171 Lisp_Object prop;
1173 register Lisp_Object tem;
1175 tem = Fassq (prop, frame->param_alist);
1176 if (EQ (tem, Qnil))
1177 return tem;
1178 return Fcdr (tem);
1181 void
1182 store_in_alist (alistptr, prop, val)
1183 Lisp_Object *alistptr, val;
1184 Lisp_Object prop;
1186 register Lisp_Object tem;
1188 tem = Fassq (prop, *alistptr);
1189 if (EQ (tem, Qnil))
1190 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1191 else
1192 Fsetcdr (tem, val);
1195 void
1196 store_frame_param (f, prop, val)
1197 struct frame *f;
1198 Lisp_Object prop, val;
1200 register Lisp_Object tem;
1202 tem = Fassq (prop, f->param_alist);
1203 if (EQ (tem, Qnil))
1204 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1205 else
1206 Fsetcdr (tem, val);
1208 if (EQ (prop, Qminibuffer)
1209 && XTYPE (val) == Lisp_Window)
1211 if (! MINI_WINDOW_P (XWINDOW (val)))
1212 error ("Surrogate minibuffer windows must be minibuffer windows.");
1214 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1215 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1217 /* Install the chosen minibuffer window, with proper buffer. */
1218 f->minibuffer_window = val;
1222 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1223 "Return the parameters-alist of frame FRAME.\n\
1224 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1225 The meaningful PARMs depend on the kind of frame.\n\
1226 If FRAME is omitted, return information on the currently selected frame.")
1227 (frame)
1228 Lisp_Object frame;
1230 Lisp_Object alist;
1231 struct frame *f;
1233 if (EQ (frame, Qnil))
1234 f = selected_frame;
1235 else
1237 CHECK_FRAME (frame, 0);
1238 f = XFRAME (frame);
1241 if (f->display.nothing == 0)
1242 return Qnil;
1244 alist = Fcopy_alist (f->param_alist);
1245 store_in_alist (&alist, Qname, f->name);
1246 store_in_alist (&alist, Qheight, make_number (f->height));
1247 store_in_alist (&alist, Qwidth, make_number (f->width));
1248 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1249 store_in_alist (&alist, Qminibuffer,
1250 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1251 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1252 : FRAME_MINIBUF_WINDOW (f))));
1253 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1254 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
1256 /* I think this should be done with a hook. */
1257 #ifdef HAVE_X_WINDOWS
1258 if (FRAME_X_P (f))
1259 x_report_frame_params (f, &alist);
1260 #endif
1261 return alist;
1264 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1265 Smodify_frame_parameters, 2, 2, 0,
1266 "Modify the parameters of frame FRAME according to ALIST.\n\
1267 ALIST is an alist of parameters to change and their new values.\n\
1268 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1269 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1270 (frame, alist)
1271 Lisp_Object frame, alist;
1273 FRAME_PTR f;
1274 register Lisp_Object tail, elt, prop, val;
1276 if (EQ (frame, Qnil))
1277 f = selected_frame;
1278 else
1280 CHECK_LIVE_FRAME (frame, 0);
1281 f = XFRAME (frame);
1284 /* I think this should be done with a hook. */
1285 #ifdef HAVE_X_WINDOWS
1286 if (FRAME_X_P (f))
1287 #if 1
1288 x_set_frame_parameters (f, alist);
1289 #else
1290 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1292 elt = Fcar (tail);
1293 prop = Fcar (elt);
1294 val = Fcdr (elt);
1295 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1296 store_frame_param (f, prop, val);
1298 #endif
1299 #endif
1301 return Qnil;
1304 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1305 0, 1, 0,
1306 "Height in pixels of a line in the font in frame FRAME.\n\
1307 If FRAME is omitted, the selected frame is used.\n\
1308 For a terminal frame, the value is always 1.")
1309 (frame)
1310 Lisp_Object frame;
1312 struct frame *f;
1314 if (NILP (frame))
1315 f = selected_frame;
1316 else
1318 CHECK_FRAME (frame, 0);
1319 f = XFRAME (frame);
1322 #ifdef HAVE_X_WINDOWS
1323 if (FRAME_X_P (f))
1324 return make_number (x_char_height (f));
1325 else
1326 #endif
1327 return make_number (1);
1331 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1332 0, 1, 0,
1333 "Width in pixels of characters in the font in frame FRAME.\n\
1334 If FRAME is omitted, the selected frame is used.\n\
1335 The width is the same for all characters, because\n\
1336 currently Emacs supports only fixed-width fonts.\n\
1337 For a terminal screen, the value is always 1.")
1338 (frame)
1339 Lisp_Object frame;
1341 struct frame *f;
1343 if (NILP (frame))
1344 f = selected_frame;
1345 else
1347 CHECK_FRAME (frame, 0);
1348 f = XFRAME (frame);
1351 #ifdef HAVE_X_WINDOWS
1352 if (FRAME_X_P (f))
1353 return make_number (x_char_width (f));
1354 else
1355 #endif
1356 return make_number (1);
1359 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1360 Sframe_pixel_height, 0, 1, 0,
1361 "Return a FRAME's height in pixels.\n\
1362 For a terminal frame, the result really gives the height in characters.\n\
1363 If FRAME is omitted, the selected frame is used.")
1364 (frame)
1365 Lisp_Object frame;
1367 struct frame *f;
1369 if (NILP (frame))
1370 f = selected_frame;
1371 else
1373 CHECK_FRAME (frame, 0);
1374 f = XFRAME (frame);
1377 #ifdef HAVE_X_WINDOWS
1378 if (FRAME_X_P (f))
1379 return make_number (x_pixel_height (f));
1380 else
1381 #endif
1382 return make_number (FRAME_HEIGHT (f));
1385 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1386 Sframe_pixel_width, 0, 1, 0,
1387 "Return FRAME's width in pixels.\n\
1388 For a terminal frame, the result really gives the width in characters.\n\
1389 If FRAME is omitted, the selected frame is used.")
1390 (frame)
1391 Lisp_Object frame;
1393 struct frame *f;
1395 if (NILP (frame))
1396 f = selected_frame;
1397 else
1399 CHECK_FRAME (frame, 0);
1400 f = XFRAME (frame);
1403 #ifdef HAVE_X_WINDOWS
1404 if (FRAME_X_P (f))
1405 return make_number (x_pixel_width (f));
1406 else
1407 #endif
1408 return make_number (FRAME_WIDTH (f));
1411 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1412 "Specify that the frame FRAME has LINES lines.\n\
1413 Optional third arg non-nil means that redisplay should use LINES lines\n\
1414 but that the idea of the actual height of the frame should not be changed.")
1415 (frame, rows, pretend)
1416 Lisp_Object frame, rows, pretend;
1418 register struct frame *f;
1420 CHECK_NUMBER (rows, 0);
1421 if (NILP (frame))
1422 f = selected_frame;
1423 else
1425 CHECK_LIVE_FRAME (frame, 0);
1426 f = XFRAME (frame);
1429 /* I think this should be done with a hook. */
1430 #ifdef HAVE_X_WINDOWS
1431 if (FRAME_X_P (f))
1433 if (XINT (rows) != f->width)
1434 x_set_window_size (f, 1, f->width, XINT (rows));
1436 else
1437 #endif
1438 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1439 return Qnil;
1442 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1443 "Specify that the frame FRAME has COLS columns.\n\
1444 Optional third arg non-nil means that redisplay should use COLS columns\n\
1445 but that the idea of the actual width of the frame should not be changed.")
1446 (frame, cols, pretend)
1447 Lisp_Object frame, cols, pretend;
1449 register struct frame *f;
1450 CHECK_NUMBER (cols, 0);
1451 if (NILP (frame))
1452 f = selected_frame;
1453 else
1455 CHECK_LIVE_FRAME (frame, 0);
1456 f = XFRAME (frame);
1459 /* I think this should be done with a hook. */
1460 #ifdef HAVE_X_WINDOWS
1461 if (FRAME_X_P (f))
1463 if (XINT (cols) != f->width)
1464 x_set_window_size (f, 1, XINT (cols), f->height);
1466 else
1467 #endif
1468 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1469 return Qnil;
1472 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1473 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1474 (frame, cols, rows)
1475 Lisp_Object frame, cols, rows;
1477 register struct frame *f;
1478 int mask;
1480 CHECK_LIVE_FRAME (frame, 0);
1481 CHECK_NUMBER (cols, 2);
1482 CHECK_NUMBER (rows, 1);
1483 f = XFRAME (frame);
1485 /* I think this should be done with a hook. */
1486 #ifdef HAVE_X_WINDOWS
1487 if (FRAME_X_P (f))
1489 if (XINT (rows) != f->height || XINT (cols) != f->width)
1490 x_set_window_size (f, 1, XINT (cols), XINT (rows));
1492 else
1493 #endif
1494 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1496 return Qnil;
1499 DEFUN ("set-frame-position", Fset_frame_position,
1500 Sset_frame_position, 3, 3, 0,
1501 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1502 This is actually the position of the upper left corner of the frame.\n\
1503 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1504 the rightmost or bottommost possible position (that stays within the screen).")
1505 (frame, xoffset, yoffset)
1506 Lisp_Object frame, xoffset, yoffset;
1508 register struct frame *f;
1509 int mask;
1511 CHECK_LIVE_FRAME (frame, 0);
1512 CHECK_NUMBER (xoffset, 1);
1513 CHECK_NUMBER (yoffset, 2);
1514 f = XFRAME (frame);
1516 /* I think this should be done with a hook. */
1517 #ifdef HAVE_X_WINDOWS
1518 if (FRAME_X_P (f))
1519 x_set_offset (f, XINT (xoffset), XINT (yoffset));
1520 #endif
1522 return Qt;
1526 choose_minibuf_frame ()
1528 /* For lowest-level minibuf, put it on currently selected frame
1529 if frame has a minibuffer. */
1531 if (minibuf_level == 0
1532 && selected_frame != 0
1533 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1535 /* I don't think that any frames may validly have a null minibuffer
1536 window anymore. */
1537 if (NILP (selected_frame->minibuffer_window))
1538 abort ();
1540 Fset_window_buffer (selected_frame->minibuffer_window,
1541 XWINDOW (minibuf_window)->buffer);
1542 minibuf_window = selected_frame->minibuffer_window;
1546 syms_of_frame ()
1548 /*&&& init symbols here &&&*/
1549 Qframep = intern ("framep");
1550 staticpro (&Qframep);
1551 Qframe_live_p = intern ("frame-live-p");
1552 staticpro (&Qframe_live_p);
1553 Qheight = intern ("height");
1554 staticpro (&Qheight);
1555 Qicon = intern ("icon");
1556 staticpro (&Qicon);
1557 Qminibuffer = intern ("minibuffer");
1558 staticpro (&Qminibuffer);
1559 Qmodeline = intern ("modeline");
1560 staticpro (&Qmodeline);
1561 Qname = intern ("name");
1562 staticpro (&Qname);
1563 Qonly = intern ("only");
1564 staticpro (&Qonly);
1565 Qunsplittable = intern ("unsplittable");
1566 staticpro (&Qunsplittable);
1567 Qmenu_bar_lines = intern ("menu-bar-lines");
1568 staticpro (&Qmenu_bar_lines);
1569 Qwidth = intern ("width");
1570 staticpro (&Qwidth);
1571 Qx = intern ("x");
1572 staticpro (&Qx);
1573 Qvisible = intern ("visible");
1574 staticpro (&Qvisible);
1576 staticpro (&Vframe_list);
1578 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1579 "The initial frame-object, which represents Emacs's stdout.");
1581 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1582 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1583 Vemacs_iconified = Qnil;
1585 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1586 "Minibufferless frames use this frame's minibuffer.\n\
1588 Emacs cannot create minibufferless frames unless this is set to an\n\
1589 appropriate surrogate.\n\
1591 Emacs consults this variable only when creating minibufferless\n\
1592 frames; once the frame is created, it sticks with its assigned\n\
1593 minibuffer, no matter what this variable is set to. This means that\n\
1594 this variable doesn't necessarily say anything meaningful about the\n\
1595 current set of frames, or where the minibuffer is currently being\n\
1596 displayed.");
1597 Vdefault_minibuffer_frame = Qnil;
1599 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1600 "Alist of default values for frame creation.\n\
1601 These may be set in your init file, like this:\n\
1602 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1603 These override values given in window system configuration data, like\n\
1604 X Windows' defaults database.\n\
1605 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1606 For values specific to the separate minibuffer frame, see\n\
1607 `minibuffer-frame-alist'.");
1608 Vdefault_frame_alist = Qnil;
1610 defsubr (&Sframep);
1611 defsubr (&Sframe_live_p);
1612 defsubr (&Shandle_switch_frame);
1613 defsubr (&Sselect_frame);
1614 defsubr (&Sselected_frame);
1615 defsubr (&Swindow_frame);
1616 defsubr (&Sframe_root_window);
1617 defsubr (&Sframe_selected_window);
1618 defsubr (&Sframe_list);
1619 defsubr (&Snext_frame);
1620 defsubr (&Sprevious_frame);
1621 defsubr (&Sdelete_frame);
1622 defsubr (&Smouse_position);
1623 defsubr (&Sset_mouse_position);
1624 #if 0
1625 defsubr (&Sframe_configuration);
1626 defsubr (&Srestore_frame_configuration);
1627 #endif
1628 defsubr (&Smake_frame_visible);
1629 defsubr (&Smake_frame_invisible);
1630 defsubr (&Siconify_frame);
1631 defsubr (&Sframe_visible_p);
1632 defsubr (&Svisible_frame_list);
1633 defsubr (&Sraise_frame);
1634 defsubr (&Slower_frame);
1635 defsubr (&Sredirect_frame_focus);
1636 defsubr (&Sframe_focus);
1637 defsubr (&Sframe_parameters);
1638 defsubr (&Smodify_frame_parameters);
1639 defsubr (&Sframe_char_height);
1640 defsubr (&Sframe_char_width);
1641 defsubr (&Sframe_pixel_height);
1642 defsubr (&Sframe_pixel_width);
1643 defsubr (&Sset_frame_height);
1644 defsubr (&Sset_frame_width);
1645 defsubr (&Sset_frame_size);
1646 defsubr (&Sset_frame_position);
1649 keys_of_frame ()
1651 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
1654 #else /* not MULTI_FRAME */
1656 /* If we're not using multi-frame stuff, we still need to provide some
1657 support functions. */
1659 Lisp_Object Vterminal_frame;
1661 /* Unless this function is defined, providing set-frame-height and
1662 set-frame-width doesn't help compatibility any, since they both
1663 want this as their first argument. */
1664 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1665 /* Don't confuse make-docfile by having two doc strings for this function.
1666 make-docfile does not pay attention to #if, for good reason! */
1670 Lisp_Object tem;
1671 XFASTINT (tem) = 0;
1672 return tem;
1674 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1675 /* Don't confuse make-docfile by having two doc strings for this function.
1676 make-docfile does not pay attention to #if, for good reason! */
1678 (object)
1679 Lisp_Object object;
1681 return Qnil;
1684 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1685 /* Don't confuse make-docfile by having two doc strings for this function.
1686 make-docfile does not pay attention to #if, for good reason! */
1688 (frame, rows, pretend)
1689 Lisp_Object frame, rows, pretend;
1691 CHECK_NUMBER (rows, 0);
1693 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1694 return Qnil;
1697 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1698 /* Don't confuse make-docfile by having two doc strings for this function.
1699 make-docfile does not pay attention to #if, for good reason! */
1701 (frame, cols, pretend)
1702 Lisp_Object frame, cols, pretend;
1704 CHECK_NUMBER (cols, 0);
1706 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1707 return Qnil;
1710 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1711 /* Don't confuse make-docfile by having two doc strings for this function.
1712 make-docfile does not pay attention to #if, for good reason! */
1714 (frame, cols, rows)
1715 Lisp_Object frame, cols, rows;
1717 CHECK_NUMBER (cols, 2);
1718 CHECK_NUMBER (rows, 1);
1720 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1722 return Qnil;
1725 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1726 "Return number of lines available for display on FRAME.\n\
1727 If FRAME is omitted, describe the currently selected frame.")
1728 (frame)
1729 Lisp_Object frame;
1731 return make_number (FRAME_HEIGHT (selected_frame));
1734 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1735 "Return number of columns available for display on FRAME.\n\
1736 If FRAME is omitted, describe the currently selected frame.")
1737 (frame)
1738 Lisp_Object frame;
1740 return make_number (FRAME_WIDTH (selected_frame));
1743 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1744 0, 1, 0,
1745 /* Don't confuse make-docfile by having two doc strings for this function.
1746 make-docfile does not pay attention to #if, for good reason! */
1748 (frame)
1749 Lisp_Object frame;
1751 return make_number (1);
1755 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1756 0, 1, 0,
1757 /* Don't confuse make-docfile by having two doc strings for this function.
1758 make-docfile does not pay attention to #if, for good reason! */
1760 (frame)
1761 Lisp_Object frame;
1763 return make_number (1);
1766 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1767 Sframe_pixel_height, 0, 1, 0,
1768 /* Don't confuse make-docfile by having two doc strings for this function.
1769 make-docfile does not pay attention to #if, for good reason! */
1771 (frame)
1772 Lisp_Object frame;
1774 return make_number (FRAME_HEIGHT (f));
1777 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1778 Sframe_pixel_width, 0, 1, 0,
1779 /* Don't confuse make-docfile by having two doc strings for this function.
1780 make-docfile does not pay attention to #if, for good reason! */
1782 (frame)
1783 Lisp_Object frame;
1785 return make_number (FRAME_WIDTH (f));
1788 /* These are for backward compatibility with Emacs 18. */
1790 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1791 "Tell redisplay that the screen has LINES lines.\n\
1792 Optional second arg non-nil means that redisplay should use LINES lines\n\
1793 but that the idea of the actual height of the screen should not be changed.")
1794 (lines, pretend)
1795 Lisp_Object lines, pretend;
1797 CHECK_NUMBER (lines, 0);
1799 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1800 return Qnil;
1803 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1804 "Tell redisplay that the screen has COLS columns.\n\
1805 Optional second arg non-nil means that redisplay should use COLS columns\n\
1806 but that the idea of the actual width of the screen should not be changed.")
1807 (cols, pretend)
1808 Lisp_Object cols, pretend;
1810 CHECK_NUMBER (cols, 0);
1812 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1813 return Qnil;
1816 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1817 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1818 The position is given in character cells, where (0, 0) is the\n\
1819 upper-left corner.\n\
1820 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1821 to read the mouse position, it returns the selected frame for FRAME\n\
1822 and nil for X and Y.")
1825 FRAME_PTR f;
1826 Lisp_Object lispy_dummy;
1827 enum scroll_bar_part party_dummy;
1828 Lisp_Object x, y;
1829 unsigned long long_dummy;
1831 f = selected_frame;
1832 x = y = Qnil;
1834 /* It's okay for the hook to refrain from storing anything. */
1835 if (mouse_position_hook)
1836 (*mouse_position_hook) (&f,
1837 &lispy_dummy, &party_dummy,
1838 &x, &y,
1839 &long_dummy);
1841 col = XINT (x);
1842 row = XINT (y);
1843 glyph_to_pixel_coords (f, col, row, &col, &row);
1844 XSETINT (x, col);
1845 XSETINT (y, row);
1846 /* Always return nil for frame. */
1847 return Fcons (Qnil, Fcons (x, y));
1850 syms_of_frame ()
1852 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1853 "The initial frame-object, which represents Emacs's stdout.");
1854 XFASTINT (Vterminal_frame) = 0;
1856 defsubr (&Sselected_frame);
1857 defsubr (&Sframep);
1858 defsubr (&Sframe_char_height);
1859 defsubr (&Sframe_char_width);
1860 defsubr (&Sframe_pixel_height);
1861 defsubr (&Sframe_pixel_width);
1862 defsubr (&Sset_frame_height);
1863 defsubr (&Sset_frame_width);
1864 defsubr (&Sset_frame_size);
1865 defsubr (&Sset_screen_height);
1866 defsubr (&Sset_screen_width);
1867 defsubr (&Sframe_height);
1868 Ffset (intern ("screen-height"), intern ("frame-height"));
1869 defsubr (&Sframe_width);
1870 Ffset (intern ("screen-width"), intern ("frame-width"));
1871 defsubr (&Smouse_position);
1874 keys_of_frame ()
1878 #endif /* not MULTI_FRAME */