* frame.c (Fframe_parameters): Report the `minibuffer' parameter of
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1989, 1992, 1993 Free Software Foundation.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21
22 #include "config.h"
23 #include "lisp.h"
24 #include "frame.h"
25
26 #ifdef MULTI_FRAME
27
28 #include "buffer.h"
29 #include "window.h"
30 #include "termhooks.h"
31
32 /* These help us bind and responding to switch-frame events. */
33 #include "commands.h"
34 #include "keyboard.h"
35
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;
41
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.
46
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 */
74
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 Qwidth;
86 Lisp_Object Qx;
87
88 extern Lisp_Object Vminibuffer_list;
89 extern Lisp_Object get_minibuffer ();
90 \f
91 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
92 "Return non-nil if OBJECT is a frame.\n\
93 Value is t for a termcap frame (a character-only terminal),\n\
94 `x' for an Emacs frame that is really an X window.\n\
95 Also see `live-frame-p'.")
96 (object)
97 Lisp_Object object;
98 {
99 if (XTYPE (object) != Lisp_Frame)
100 return Qnil;
101 switch (XFRAME (object)->output_method)
102 {
103 case output_termcap:
104 return Qt;
105 case output_x_window:
106 return Qx;
107 default:
108 abort ();
109 }
110 }
111
112 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
113 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
114 Value is nil if OBJECT is not a live frame. If object is a live\n\
115 frame, the return value indicates what sort of output device it is\n\
116 displayed on. Value is t for a termcap frame (a character-only\n\
117 terminal), `x' for an Emacs frame being displayed in an X window.")
118 (object)
119 Lisp_Object object;
120 {
121 return ((FRAMEP (object)
122 && FRAME_LIVE_P (XFRAME (object)))
123 ? Fframep (object)
124 : Qnil);
125 }
126
127 struct frame *
128 make_frame (mini_p)
129 int mini_p;
130 {
131 Lisp_Object frame;
132 register struct frame *f;
133 register Lisp_Object root_window;
134 register Lisp_Object mini_window;
135
136 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
137 - sizeof (Lisp_Object)))
138 / sizeof (Lisp_Object)),
139 make_number (0));
140 XSETTYPE (frame, Lisp_Frame);
141 f = XFRAME (frame);
142
143 f->cursor_x = 0;
144 f->cursor_y = 0;
145 f->current_glyphs = 0;
146 f->desired_glyphs = 0;
147 f->visible = 0;
148 f->async_visible = 0;
149 f->display.nothing = 0;
150 f->iconified = 0;
151 f->async_iconified = 0;
152 f->wants_modeline = 1;
153 f->auto_raise = 0;
154 f->auto_lower = 0;
155 f->no_split = 0;
156 f->garbaged = 0;
157 f->has_minibuffer = mini_p;
158 f->focus_frame = Qnil;
159 f->explicit_name = 0;
160 f->can_have_scrollbars = 0;
161 f->has_vertical_scrollbars = 0;
162 f->param_alist = Qnil;
163 f->scrollbars = Qnil;
164 f->condemned_scrollbars = Qnil;
165
166 root_window = make_window ();
167 if (mini_p)
168 {
169 mini_window = make_window ();
170 XWINDOW (root_window)->next = mini_window;
171 XWINDOW (mini_window)->prev = root_window;
172 XWINDOW (mini_window)->mini_p = Qt;
173 XWINDOW (mini_window)->frame = frame;
174 f->minibuffer_window = mini_window;
175 }
176 else
177 {
178 mini_window = Qnil;
179 XWINDOW (root_window)->next = Qnil;
180 f->minibuffer_window = Qnil;
181 }
182
183 XWINDOW (root_window)->frame = frame;
184
185 /* 10 is arbitrary,
186 just so that there is "something there."
187 Correct size will be set up later with change_frame_size. */
188
189 f->width = 10;
190 f->height = 10;
191
192 XFASTINT (XWINDOW (root_window)->width) = 10;
193 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
194
195 if (mini_p)
196 {
197 XFASTINT (XWINDOW (mini_window)->width) = 10;
198 XFASTINT (XWINDOW (mini_window)->top) = 9;
199 XFASTINT (XWINDOW (mini_window)->height) = 1;
200 }
201
202 /* Choose a buffer for the frame's root window. */
203 {
204 Lisp_Object buf;
205
206 XWINDOW (root_window)->buffer = Qt;
207 buf = Fcurrent_buffer ();
208 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
209 a space), try to find another one. */
210 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
211 buf = Fother_buffer (buf, Qnil);
212 Fset_window_buffer (root_window, buf);
213 }
214
215 if (mini_p)
216 {
217 XWINDOW (mini_window)->buffer = Qt;
218 Fset_window_buffer (mini_window,
219 (NILP (Vminibuffer_list)
220 ? get_minibuffer (0)
221 : Fcar (Vminibuffer_list)));
222 }
223
224 f->root_window = root_window;
225 f->selected_window = root_window;
226 /* Make sure this window seems more recently used than
227 a newly-created, never-selected window. */
228 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
229
230 Vframe_list = Fcons (frame, Vframe_list);
231
232 return f;
233 }
234 \f
235 /* Make a frame using a separate minibuffer window on another frame.
236 MINI_WINDOW is the minibuffer window to use. nil means use the
237 default (the global minibuffer). */
238
239 struct frame *
240 make_frame_without_minibuffer (mini_window)
241 register Lisp_Object mini_window;
242 {
243 register struct frame *f;
244
245 /* Choose the minibuffer window to use. */
246 if (NILP (mini_window))
247 {
248 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
249 error ("default-minibuffer-frame must be set when creating minibufferless frames");
250 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
251 error ("default-minibuffer-frame must be a live frame");
252 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
253 }
254 else
255 {
256 CHECK_LIVE_WINDOW (mini_window, 0);
257 }
258
259 /* Make a frame containing just a root window. */
260 f = make_frame (0);
261
262 /* Install the chosen minibuffer window, with proper buffer. */
263 f->minibuffer_window = mini_window;
264 Fset_window_buffer (mini_window,
265 (NILP (Vminibuffer_list)
266 ? get_minibuffer (0)
267 : Fcar (Vminibuffer_list)));
268 return f;
269 }
270
271 /* Make a frame containing only a minibuffer window. */
272
273 struct frame *
274 make_minibuffer_frame ()
275 {
276 /* First make a frame containing just a root window, no minibuffer. */
277
278 register struct frame *f = make_frame (0);
279 register Lisp_Object mini_window;
280 register Lisp_Object frame;
281
282 XSET (frame, Lisp_Frame, f);
283
284 f->auto_raise = 0;
285 f->auto_lower = 0;
286 f->no_split = 1;
287 f->wants_modeline = 0;
288 f->has_minibuffer = 1;
289
290 /* Now label the root window as also being the minibuffer.
291 Avoid infinite looping on the window chain by marking next pointer
292 as nil. */
293
294 mini_window = f->minibuffer_window = f->root_window;
295 XWINDOW (mini_window)->mini_p = Qt;
296 XWINDOW (mini_window)->next = Qnil;
297 XWINDOW (mini_window)->prev = Qnil;
298 XWINDOW (mini_window)->frame = frame;
299
300 /* Put the proper buffer in that window. */
301
302 Fset_window_buffer (mini_window,
303 (NILP (Vminibuffer_list)
304 ? get_minibuffer (0)
305 : Fcar (Vminibuffer_list)));
306 return f;
307 }
308 \f
309 /* Construct a frame that refers to the terminal (stdin and stdout). */
310
311 struct frame *
312 make_terminal_frame ()
313 {
314 register struct frame *f;
315
316 Vframe_list = Qnil;
317 f = make_frame (1);
318 f->name = build_string ("terminal");
319 FRAME_SET_VISIBLE (f, 1);
320 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
321 XSET (Vterminal_frame, Lisp_Frame, f);
322 return f;
323 }
324 \f
325 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
326 "Select the frame FRAME. FRAME's selected window becomes \"the\"\n\
327 selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
328 focus on that frame.\n\
329 \n\
330 This function is interactive, and may be bound to the ``switch-frame''\n\
331 event; when invoked this way, it switches to the frame named in the\n\
332 event. When called from lisp, FRAME may be a ``switch-frame'' event;\n\
333 if it is, select the frame named in the event.\n\
334 \n\
335 Changing the selected frame can change focus redirections. See\n\
336 `redirect-frame-focus' for details.")
337 (frame, no_enter)
338 Lisp_Object frame, no_enter;
339 {
340 /* If FRAME is a switch-frame event, extract the frame we should
341 switch to. */
342 if (CONSP (frame)
343 && EQ (XCONS (frame)->car, Qswitch_frame)
344 && CONSP (XCONS (frame)->cdr))
345 frame = XCONS (XCONS (frame)->cdr)->car;
346
347 CHECK_LIVE_FRAME (frame, 0);
348
349 if (selected_frame == XFRAME (frame))
350 return frame;
351
352 /* If a frame's focus has been redirected toward the currently
353 selected frame, we should change the redirection to point to the
354 newly selected frame. This means that if the focus is redirected
355 from a minibufferless frame to a surrogate minibuffer frame, we
356 can use `other-window' to switch between all the frames using
357 that minibuffer frame, and the focus redirection will follow us
358 around. */
359 {
360 Lisp_Object tail;
361
362 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
363 {
364 Lisp_Object focus;
365
366 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
367 abort ();
368
369 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
370
371 if (XTYPE (focus) == Lisp_Frame
372 && XFRAME (focus) == selected_frame)
373 Fredirect_frame_focus (XCONS (tail)->car, frame);
374 }
375 }
376
377 selected_frame = XFRAME (frame);
378 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
379 last_nonminibuf_frame = selected_frame;
380
381 Fselect_window (XFRAME (frame)->selected_window);
382
383 /* I think this should be done with a hook. */
384 #ifdef HAVE_X_WINDOWS
385 if (FRAME_X_P (XFRAME (frame))
386 && NILP (no_enter))
387 {
388 Ffocus_frame (frame);
389 }
390 #endif
391 choose_minibuf_frame ();
392
393 return frame;
394 }
395
396 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
397 "Return the frame that is now selected.")
398 ()
399 {
400 Lisp_Object tem;
401 XSET (tem, Lisp_Frame, selected_frame);
402 return tem;
403 }
404
405 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
406 "Return the frame object that window WINDOW is on.")
407 (window)
408 Lisp_Object window;
409 {
410 CHECK_LIVE_WINDOW (window, 0);
411 return XWINDOW (window)->frame;
412 }
413
414 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
415 "Returns the root-window of FRAME.\n\
416 If omitted, FRAME defaults to the currently selected frame.")
417 (frame)
418 Lisp_Object frame;
419 {
420 if (NILP (frame))
421 XSET (frame, Lisp_Frame, selected_frame);
422 else
423 CHECK_LIVE_FRAME (frame, 0);
424
425 return XFRAME (frame)->root_window;
426 }
427
428 DEFUN ("frame-selected-window", Fframe_selected_window,
429 Sframe_selected_window, 0, 1, 0,
430 "Return the selected window of frame object FRAME.\n\
431 If omitted, FRAME defaults to the currently selected frame.")
432 (frame)
433 Lisp_Object frame;
434 {
435 if (NILP (frame))
436 XSET (frame, Lisp_Frame, selected_frame);
437 else
438 CHECK_LIVE_FRAME (frame, 0);
439
440 return XFRAME (frame)->selected_window;
441 }
442
443 DEFUN ("frame-list", Fframe_list, Sframe_list,
444 0, 0, 0,
445 "Return a list of all frames.")
446 ()
447 {
448 return Fcopy_sequence (Vframe_list);
449 }
450
451 /* Return the next frame in the frame list after FRAME.
452 If MINIBUF is nil, exclude minibuffer-only frames.
453 If MINIBUF is a window, include only frames using that window for
454 their minibuffer.
455 If MINIBUF is non-nil, and not a window, include all frames. */
456 Lisp_Object
457 next_frame (frame, minibuf)
458 Lisp_Object frame;
459 Lisp_Object minibuf;
460 {
461 Lisp_Object tail;
462 int passed = 0;
463
464 /* There must always be at least one frame in Vframe_list. */
465 if (! CONSP (Vframe_list))
466 abort ();
467
468 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
469 forever. Forestall that. */
470 CHECK_LIVE_FRAME (frame, 0);
471
472 while (1)
473 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
474 {
475 Lisp_Object f = XCONS (tail)->car;
476
477 if (passed)
478 {
479 /* Decide whether this frame is eligible to be returned. */
480
481 /* If we've looped all the way around without finding any
482 eligible frames, return the original frame. */
483 if (EQ (f, frame))
484 return f;
485
486 /* Let minibuf decide if this frame is acceptable. */
487 if (NILP (minibuf))
488 {
489 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
490 return f;
491 }
492 else if (XTYPE (minibuf) == Lisp_Window)
493 {
494 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
495 return f;
496 }
497 else
498 return f;
499 }
500
501 if (EQ (frame, f))
502 passed++;
503 }
504 }
505
506 /* Return the previous frame in the frame list before FRAME.
507 If MINIBUF is nil, exclude minibuffer-only frames.
508 If MINIBUF is a window, include only frames using that window for
509 their minibuffer.
510 If MINIBUF is non-nil and not a window, include all frames. */
511 Lisp_Object
512 prev_frame (frame, minibuf)
513 Lisp_Object frame;
514 Lisp_Object minibuf;
515 {
516 Lisp_Object tail;
517 Lisp_Object prev;
518
519 /* There must always be at least one frame in Vframe_list. */
520 if (! CONSP (Vframe_list))
521 abort ();
522
523 prev = Qnil;
524 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
525 {
526 Lisp_Object f = XCONS (tail)->car;
527
528 if (XTYPE (f) != Lisp_Frame)
529 abort ();
530
531 if (EQ (frame, f) && !NILP (prev))
532 return prev;
533
534 /* Decide whether this frame is eligible to be returned,
535 according to minibuf. */
536 if (NILP (minibuf))
537 {
538 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
539 prev = f;
540 }
541 else if (XTYPE (minibuf) == Lisp_Window)
542 {
543 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
544 prev = f;
545 }
546 else
547 prev = f;
548 }
549
550 /* We've scanned the entire list. */
551 if (NILP (prev))
552 /* We went through the whole frame list without finding a single
553 acceptable frame. Return the original frame. */
554 return frame;
555 else
556 /* There were no acceptable frames in the list before FRAME; otherwise,
557 we would have returned directly from the loop. Since PREV is the last
558 acceptable frame in the list, return it. */
559 return prev;
560 }
561
562 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
563 "Return the next frame in the frame list after FRAME.\n\
564 By default, skip minibuffer-only frames.\n\
565 If omitted, FRAME defaults to the selected frame.\n\
566 If optional argument MINIFRAME is non-nil, include minibuffer-only frames.\n\
567 If MINIFRAME is a window, include only frames using that window for their\n\
568 minibuffer.\n\
569 If MINIFRAME is non-nil and not a window, include all frames.")
570 (frame, miniframe)
571 Lisp_Object frame, miniframe;
572 {
573 Lisp_Object tail;
574
575 if (NILP (frame))
576 XSET (frame, Lisp_Frame, selected_frame);
577 else
578 CHECK_LIVE_FRAME (frame, 0);
579
580 return next_frame (frame, miniframe);
581 }
582
583 \f
584 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
585 "Delete FRAME, permanently eliminating it from use.\n\
586 If omitted, FRAME defaults to the selected frame.\n\
587 A frame may not be deleted if its minibuffer is used by other frames.")
588 (frame)
589 Lisp_Object frame;
590 {
591 struct frame *f;
592
593 if (EQ (frame, Qnil))
594 {
595 f = selected_frame;
596 XSET (frame, Lisp_Frame, f);
597 }
598 else
599 {
600 CHECK_FRAME (frame, 0);
601 f = XFRAME (frame);
602 }
603
604 if (! FRAME_LIVE_P (f))
605 return;
606
607 /* Are there any other frames besides this one? */
608 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
609 error ("Attempt to delete the only frame");
610
611 /* Does this frame have a minibuffer, and is it the surrogate
612 minibuffer for any other frame? */
613 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
614 {
615 Lisp_Object frames;
616
617 for (frames = Vframe_list;
618 CONSP (frames);
619 frames = XCONS (frames)->cdr)
620 {
621 Lisp_Object this = XCONS (frames)->car;
622
623 if (! EQ (this, frame)
624 && EQ (frame,
625 (WINDOW_FRAME
626 (XWINDOW
627 (FRAME_MINIBUF_WINDOW
628 (XFRAME (this)))))))
629 error ("Attempt to delete a surrogate minibuffer frame");
630 }
631 }
632
633 /* Don't let the frame remain selected. */
634 if (f == selected_frame)
635 Fselect_frame (next_frame (frame, Qt), Qnil);
636
637 /* Don't allow minibuf_window to remain on a deleted frame. */
638 if (EQ (f->minibuffer_window, minibuf_window))
639 {
640 Fset_window_buffer (selected_frame->minibuffer_window,
641 XWINDOW (minibuf_window)->buffer);
642 minibuf_window = selected_frame->minibuffer_window;
643 }
644
645 /* Mark all the windows that used to be on FRAME as deleted, and then
646 remove the reference to them. */
647 delete_all_subwindows (XWINDOW (f->root_window));
648 f->root_window = Qnil;
649
650 Vframe_list = Fdelq (frame, Vframe_list);
651 FRAME_SET_VISIBLE (f, 0);
652
653 /* Since some events are handled at the interrupt level, we may get
654 an event for f at any time; if we zero out the frame's display
655 now, then we may trip up the event-handling code. Instead, we'll
656 promise that the display of the frame must be valid until we have
657 called the window-system-dependent frame destruction routine. */
658
659 /* I think this should be done with a hook. */
660 #ifdef HAVE_X_WINDOWS
661 if (FRAME_X_P (f))
662 x_destroy_window (f);
663 #endif
664
665 f->display.nothing = 0;
666
667 /* If we've deleted the last_nonminibuf_frame, then try to find
668 another one. */
669 if (f == last_nonminibuf_frame)
670 {
671 Lisp_Object frames;
672
673 last_nonminibuf_frame = 0;
674
675 for (frames = Vframe_list;
676 CONSP (frames);
677 frames = XCONS (frames)->cdr)
678 {
679 f = XFRAME (XCONS (frames)->car);
680 if (!FRAME_MINIBUF_ONLY_P (f))
681 {
682 last_nonminibuf_frame = f;
683 break;
684 }
685 }
686 }
687
688 /* If we've deleted Vdefault_minibuffer_frame, try to find another
689 one. Prefer minibuffer-only frames, but also notice frames
690 with other windows. */
691 if (EQ (frame, Vdefault_minibuffer_frame))
692 {
693 Lisp_Object frames;
694
695 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
696 Lisp_Object frame_with_minibuf = Qnil;
697
698 for (frames = Vframe_list;
699 CONSP (frames);
700 frames = XCONS (frames)->cdr)
701 {
702 Lisp_Object this = XCONS (frames)->car;
703
704 if (XTYPE (this) != Lisp_Frame)
705 abort ();
706 f = XFRAME (this);
707
708 if (FRAME_HAS_MINIBUF_P (f))
709 {
710 frame_with_minibuf = this;
711 if (FRAME_MINIBUF_ONLY_P (f))
712 break;
713 }
714 }
715
716 /* We know that there must be some frame with a minibuffer out
717 there. If this were not true, all of the frames present
718 would have to be minibufferless, which implies that at some
719 point their minibuffer frames must have been deleted, but
720 that is prohibited at the top; you can't delete surrogate
721 minibuffer frames. */
722 if (NILP (frame_with_minibuf))
723 abort ();
724
725 Vdefault_minibuffer_frame = frame_with_minibuf;
726 }
727
728 return Qnil;
729 }
730 \f
731 /* Return mouse position in character cell units. */
732
733 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
734 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
735 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
736 to read the mouse position, it returns the selected frame for FRAME\n\
737 and nil for X and Y.")
738 ()
739 {
740 FRAME_PTR f;
741 Lisp_Object lispy_dummy;
742 enum scrollbar_part party_dummy;
743 Lisp_Object x, y;
744 unsigned long long_dummy;
745
746 if (mouse_position_hook)
747 (*mouse_position_hook) (&f,
748 &lispy_dummy, &party_dummy,
749 &x, &y,
750 &long_dummy);
751 else
752 {
753 f = selected_frame;
754 x = y = Qnil;
755 }
756
757 XSET (lispy_dummy, Lisp_Frame, f);
758 return Fcons (lispy_dummy, Fcons (make_number (x), make_number (y)));
759 }
760
761 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
762 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
763 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
764 (frame, x, y)
765 Lisp_Object frame, x, y;
766 {
767 CHECK_LIVE_FRAME (frame, 0);
768 CHECK_NUMBER (x, 2);
769 CHECK_NUMBER (y, 1);
770
771 /* I think this should be done with a hook. */
772 #ifdef HAVE_X_WINDOWS
773 if (FRAME_X_P (XFRAME (frame)))
774 /* Warping the mouse will cause enternotify and focus events. */
775 x_set_mouse_position (XFRAME (frame), x, y);
776 #endif
777
778 return Qnil;
779 }
780 \f
781 #if 0
782 /* ??? Can this be replaced with a Lisp function?
783 It is used in minibuf.c. Can we get rid of that?
784 Yes. All uses in minibuf.c are gone, and parallels to these
785 functions have been defined in frame.el. */
786
787 DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
788 0, 0, 0,
789 "Return object describing current frame configuration.\n\
790 The frame configuration is the current mouse position and selected frame.\n\
791 This object can be given to `restore-frame-configuration'\n\
792 to restore this frame configuration.")
793 ()
794 {
795 Lisp_Object c, time;
796
797 c = Fmake_vector (make_number(4), Qnil);
798 XVECTOR (c)->contents[0] = Fselected_frame();
799 if (mouse_position_hook)
800 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
801 &XVECTOR (c)->contents[2],
802 &XVECTOR (c)->contents[3],
803 &time);
804 return c;
805 }
806
807 DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
808 Srestore_frame_configuration,
809 1, 1, 0,
810 "Restores frame configuration CONFIGURATION.")
811 (config)
812 Lisp_Object config;
813 {
814 Lisp_Object x_pos, y_pos, frame;
815
816 CHECK_VECTOR (config, 0);
817 if (XVECTOR (config)->size != 3)
818 {
819 error ("Wrong size vector passed to restore-frame-configuration");
820 }
821 frame = XVECTOR (config)->contents[0];
822 CHECK_LIVE_FRAME (frame, 0);
823
824 Fselect_frame (frame, Qnil);
825
826 #if 0
827 /* This seems to interfere with the frame selection mechanism. jla */
828 x_pos = XVECTOR (config)->contents[2];
829 y_pos = XVECTOR (config)->contents[3];
830 set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
831 #endif
832
833 return frame;
834 }
835 #endif
836 \f
837 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
838 0, 1, 0,
839 "Make the frame FRAME visible (assuming it is an X-window).\n\
840 Also raises the frame so that nothing obscures it.\n\
841 If omitted, FRAME defaults to the currently selected frame.")
842 (frame)
843 Lisp_Object frame;
844 {
845 if (NILP (frame))
846 XSET (frame, Lisp_Frame, selected_frame);
847
848 CHECK_LIVE_FRAME (frame, 0);
849
850 /* I think this should be done with a hook. */
851 #ifdef HAVE_X_WINDOWS
852 if (FRAME_X_P (XFRAME (frame)))
853 x_make_frame_visible (XFRAME (frame));
854 #endif
855
856 return frame;
857 }
858
859 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
860 0, 1, "",
861 "Make the frame FRAME invisible (assuming it is an X-window).\n\
862 If omitted, FRAME defaults to the currently selected frame.")
863 (frame)
864 Lisp_Object frame;
865 {
866 if (NILP (frame))
867 XSET (frame, Lisp_Frame, selected_frame);
868
869 CHECK_LIVE_FRAME (frame, 0);
870
871 /* I think this should be done with a hook. */
872 #ifdef HAVE_X_WINDOWS
873 if (FRAME_X_P (XFRAME (frame)))
874 x_make_frame_invisible (XFRAME (frame));
875 #endif
876
877 return Qnil;
878 }
879
880 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
881 0, 1, "",
882 "Make the frame FRAME into an icon.\n\
883 If omitted, FRAME defaults to the currently selected frame.")
884 (frame)
885 Lisp_Object frame;
886 {
887 if (NILP (frame))
888 XSET (frame, Lisp_Frame, selected_frame);
889
890 CHECK_LIVE_FRAME (frame, 0);
891
892 /* I think this should be done with a hook. */
893 #ifdef HAVE_X_WINDOWS
894 if (FRAME_X_P (XFRAME (frame)))
895 x_iconify_frame (XFRAME (frame));
896 #endif
897
898 return Qnil;
899 }
900
901 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
902 1, 1, 0,
903 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
904 A frame that is not \"visible\" is not updated and, if it works through\n\
905 a window system, it may not show at all.\n\
906 Return the symbol `icon' if frame is visible only as an icon.")
907 (frame)
908 Lisp_Object frame;
909 {
910 CHECK_LIVE_FRAME (frame, 0);
911
912 if (FRAME_VISIBLE_P (XFRAME (frame)))
913 return Qt;
914 if (FRAME_ICONIFIED_P (XFRAME (frame)))
915 return Qicon;
916 return Qnil;
917 }
918
919 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
920 0, 0, 0,
921 "Return a list of all frames now \"visible\" (being updated).")
922 ()
923 {
924 Lisp_Object tail, frame;
925 struct frame *f;
926 Lisp_Object value;
927
928 value = Qnil;
929 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
930 {
931 frame = XCONS (tail)->car;
932 if (XTYPE (frame) != Lisp_Frame)
933 continue;
934 f = XFRAME (frame);
935 if (FRAME_VISIBLE_P (f))
936 value = Fcons (frame, value);
937 }
938 return value;
939 }
940
941
942 DEFUN ("frame-to-front", Fframe_to_front, Sframe_to_front, 1, 1, 0,
943 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
944 If FRAME is invisible, make it visible.\n\
945 If Emacs is displaying on an ordinary terminal or some other device which\n\
946 doesn't support multiple overlapping frames, this function does nothing.")
947 (frame)
948 Lisp_Object frame;
949 {
950 CHECK_LIVE_FRAME (frame, 0);
951
952 if (frame_raise_lower_hook)
953 (*frame_raise_lower_hook) (XFRAME (frame), 1);
954
955 return Qnil;
956 }
957
958 DEFUN ("frame-to-back", Fframe_to_back, Sframe_to_back, 1, 1, 0,
959 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
960 If Emacs is displaying on an ordinary terminal or some other device which\n\
961 doesn't support multiple overlapping frames, this function does nothing.")
962 (frame)
963 Lisp_Object frame;
964 {
965 CHECK_LIVE_FRAME (frame, 0);
966
967 if (frame_raise_lower_hook)
968 (*frame_raise_lower_hook) (XFRAME (frame), 0);
969
970 return Qnil;
971 }
972
973 \f
974 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
975 1, 2, 0,
976 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
977 In other words, switch-frame events caused by events in FRAME will\n\
978 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
979 FOCUS-FRAME after reading an event typed at FRAME.\n\
980 \n\
981 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
982 cancelled, and the frame again receives its own keystrokes.\n\
983 \n\
984 Focus redirection is useful for temporarily redirecting keystrokes to\n\
985 a surrogate minibuffer frame when a frame doesn't have its own\n\
986 minibuffer window.\n\
987 \n\
988 A frame's focus redirection can be changed by select-frame. If frame\n\
989 FOO is selected, and then a different frame BAR is selected, any\n\
990 frames redirecting their focus to FOO are shifted to redirect their\n\
991 focus to BAR. This allows focus redirection to work properly when the\n\
992 user switches from one frame to another using `select-window'.\n\
993 \n\
994 This means that a frame whose focus is redirected to itself is treated\n\
995 differently from a frame whose focus is redirected to nil; the former\n\
996 is affected by select-frame, while the latter is not.\n\
997 \n\
998 The redirection lasts until `redirect-frame-focus' is called to change it.")
999 (frame, focus_frame)
1000 Lisp_Object frame, focus_frame;
1001 {
1002 CHECK_LIVE_FRAME (frame, 0);
1003
1004 if (! NILP (focus_frame))
1005 CHECK_LIVE_FRAME (focus_frame, 1);
1006
1007 XFRAME (frame)->focus_frame = focus_frame;
1008
1009 if (frame_rehighlight_hook)
1010 (*frame_rehighlight_hook) ();
1011
1012 return Qnil;
1013 }
1014
1015
1016 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1017 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1018 This returns nil if FRAME's focus is not redirected.\n\
1019 See `redirect-frame-focus'.")
1020 (frame)
1021 Lisp_Object frame;
1022 {
1023 CHECK_LIVE_FRAME (frame, 0);
1024
1025 return FRAME_FOCUS_FRAME (XFRAME (frame));
1026 }
1027
1028
1029 \f
1030 Lisp_Object
1031 get_frame_param (frame, prop)
1032 register struct frame *frame;
1033 Lisp_Object prop;
1034 {
1035 register Lisp_Object tem;
1036
1037 tem = Fassq (prop, frame->param_alist);
1038 if (EQ (tem, Qnil))
1039 return tem;
1040 return Fcdr (tem);
1041 }
1042
1043 void
1044 store_in_alist (alistptr, prop, val)
1045 Lisp_Object *alistptr, val;
1046 Lisp_Object prop;
1047 {
1048 register Lisp_Object tem;
1049
1050 tem = Fassq (prop, *alistptr);
1051 if (EQ (tem, Qnil))
1052 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1053 else
1054 Fsetcdr (tem, val);
1055 }
1056
1057 void
1058 store_frame_param (f, prop, val)
1059 struct frame *f;
1060 Lisp_Object prop, val;
1061 {
1062 register Lisp_Object tem;
1063
1064 tem = Fassq (prop, f->param_alist);
1065 if (EQ (tem, Qnil))
1066 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1067 else
1068 Fsetcdr (tem, val);
1069
1070 if (EQ (prop, Qminibuffer)
1071 && XTYPE (val) == Lisp_Window)
1072 {
1073 if (! MINI_WINDOW_P (XWINDOW (val)))
1074 error ("Surrogate minibuffer windows must be minibuffer windows.");
1075
1076 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1077 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
1078
1079 /* Install the chosen minibuffer window, with proper buffer. */
1080 f->minibuffer_window = val;
1081 }
1082 }
1083
1084 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1085 "Return the parameters-alist of frame FRAME.\n\
1086 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1087 The meaningful PARMs depend on the kind of frame.\n\
1088 If FRAME is omitted, return information on the currently selected frame.")
1089 (frame)
1090 Lisp_Object frame;
1091 {
1092 Lisp_Object alist;
1093 struct frame *f;
1094
1095 if (EQ (frame, Qnil))
1096 f = selected_frame;
1097 else
1098 {
1099 CHECK_FRAME (frame, 0);
1100 f = XFRAME (frame);
1101 }
1102
1103 if (f->display.nothing == 0)
1104 return Qnil;
1105
1106 alist = Fcopy_alist (f->param_alist);
1107 store_in_alist (&alist, Qname, f->name);
1108 store_in_alist (&alist, Qheight, make_number (f->height));
1109 store_in_alist (&alist, Qwidth, make_number (f->width));
1110 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1111 store_in_alist (&alist, Qminibuffer,
1112 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1113 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1114 : FRAME_MINIBUF_WINDOW (f))));
1115 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1116
1117 /* I think this should be done with a hook. */
1118 #ifdef HAVE_X_WINDOWS
1119 if (FRAME_X_P (f))
1120 x_report_frame_params (f, &alist);
1121 #endif
1122 return alist;
1123 }
1124
1125 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1126 Smodify_frame_parameters, 2, 2, 0,
1127 "Modify the parameters of frame FRAME according to ALIST.\n\
1128 ALIST is an alist of parameters to change and their new values.\n\
1129 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1130 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1131 (frame, alist)
1132 Lisp_Object frame, alist;
1133 {
1134 FRAME_PTR f;
1135 register Lisp_Object tail, elt, prop, val;
1136
1137 if (EQ (frame, Qnil))
1138 f = selected_frame;
1139 else
1140 {
1141 CHECK_LIVE_FRAME (frame, 0);
1142 f = XFRAME (frame);
1143 }
1144
1145 /* I think this should be done with a hook. */
1146 #ifdef HAVE_X_WINDOWS
1147 if (FRAME_X_P (f))
1148 #if 1
1149 x_set_frame_parameters (f, alist);
1150 #else
1151 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1152 {
1153 elt = Fcar (tail);
1154 prop = Fcar (elt);
1155 val = Fcdr (elt);
1156 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1157 store_frame_param (f, prop, val);
1158 }
1159 #endif
1160 #endif
1161
1162 return Qnil;
1163 }
1164 \f
1165
1166 #if 0
1167 /* This function isn't useful enough by itself to include; we need to
1168 add functions to allow the user to find the size of a font before
1169 this is actually useful. */
1170
1171 DEFUN ("frame-pixel-size", Fframe_pixel_size,
1172 Sframe_pixel_size, 1, 1, 0,
1173 "Return a cons (width . height) of FRAME's size in pixels.")
1174 (frame)
1175 Lisp_Object frame;
1176 {
1177 register struct frame *f;
1178 int width, height;
1179
1180 CHECK_LIVE_FRAME (frame, 0);
1181 f = XFRAME (frame);
1182
1183 return Fcons (make_number (x_pixel_width (f)),
1184 make_number (x_pixel_height (f)));
1185 }
1186 #endif
1187
1188 #if 0
1189 /* These functions have no C callers, and can be written nicely in lisp. */
1190
1191 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1192 "Return number of lines available for display on selected frame.")
1193 ()
1194 {
1195 return make_number (FRAME_HEIGHT (selected_frame));
1196 }
1197
1198 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1199 "Return number of columns available for display on selected frame.")
1200 ()
1201 {
1202 return make_number (FRAME_WIDTH (selected_frame));
1203 }
1204 #endif
1205
1206 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1207 "Specify that the frame FRAME has LINES lines.\n\
1208 Optional third arg non-nil means that redisplay should use LINES lines\n\
1209 but that the idea of the actual height of the frame should not be changed.")
1210 (frame, rows, pretend)
1211 Lisp_Object frame, rows, pretend;
1212 {
1213 register struct frame *f;
1214
1215 CHECK_NUMBER (rows, 0);
1216 if (NILP (frame))
1217 f = selected_frame;
1218 else
1219 {
1220 CHECK_LIVE_FRAME (frame, 0);
1221 f = XFRAME (frame);
1222 }
1223
1224 /* I think this should be done with a hook. */
1225 #ifdef HAVE_X_WINDOWS
1226 if (FRAME_X_P (f))
1227 {
1228 if (XINT (rows) != f->width)
1229 x_set_window_size (f, f->width, XINT (rows));
1230 }
1231 else
1232 #endif
1233 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1234 return Qnil;
1235 }
1236
1237 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1238 "Specify that the frame FRAME has COLS columns.\n\
1239 Optional third arg non-nil means that redisplay should use COLS columns\n\
1240 but that the idea of the actual width of the frame should not be changed.")
1241 (frame, cols, pretend)
1242 Lisp_Object frame, cols, pretend;
1243 {
1244 register struct frame *f;
1245 CHECK_NUMBER (cols, 0);
1246 if (NILP (frame))
1247 f = selected_frame;
1248 else
1249 {
1250 CHECK_LIVE_FRAME (frame, 0);
1251 f = XFRAME (frame);
1252 }
1253
1254 /* I think this should be done with a hook. */
1255 #ifdef HAVE_X_WINDOWS
1256 if (FRAME_X_P (f))
1257 {
1258 if (XINT (cols) != f->width)
1259 x_set_window_size (f, XINT (cols), f->height);
1260 }
1261 else
1262 #endif
1263 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1264 return Qnil;
1265 }
1266
1267 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1268 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1269 (frame, cols, rows)
1270 Lisp_Object frame, cols, rows;
1271 {
1272 register struct frame *f;
1273 int mask;
1274
1275 CHECK_LIVE_FRAME (frame, 0);
1276 CHECK_NUMBER (cols, 2);
1277 CHECK_NUMBER (rows, 1);
1278 f = XFRAME (frame);
1279
1280 /* I think this should be done with a hook. */
1281 #ifdef HAVE_X_WINDOWS
1282 if (FRAME_X_P (f))
1283 {
1284 if (XINT (rows) != f->height || XINT (cols) != f->width)
1285 x_set_window_size (f, XINT (cols), XINT (rows));
1286 }
1287 else
1288 #endif
1289 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1290
1291 return Qnil;
1292 }
1293
1294 DEFUN ("set-frame-position", Fset_frame_position,
1295 Sset_frame_position, 3, 3, 0,
1296 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1297 If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1298 the leftmost or bottommost position FRAME could occupy without going\n\
1299 off the screen.")
1300 (frame, xoffset, yoffset)
1301 Lisp_Object frame, xoffset, yoffset;
1302 {
1303 register struct frame *f;
1304 int mask;
1305
1306 CHECK_LIVE_FRAME (frame, 0);
1307 CHECK_NUMBER (xoffset, 1);
1308 CHECK_NUMBER (yoffset, 2);
1309 f = XFRAME (frame);
1310
1311 /* I think this should be done with a hook. */
1312 #ifdef HAVE_X_WINDOWS
1313 if (FRAME_X_P (f))
1314 x_set_offset (f, XINT (xoffset), XINT (yoffset));
1315 #endif
1316
1317 return Qt;
1318 }
1319
1320 \f
1321 #ifndef HAVE_X11
1322 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1323 3, 3, "",
1324 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1325 Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
1326 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1327 specify defaults for some sizes/positions. If GEO specifies everything,\n\
1328 the mouse is not used.\n\
1329 Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1330 (frame, name, geo)
1331 Lisp_Object frame;
1332 Lisp_Object name;
1333 Lisp_Object geo;
1334 {
1335 int vals[4];
1336 Lisp_Object nums[4];
1337 int i;
1338
1339 CHECK_FRAME (frame, 0);
1340 CHECK_STRING (name, 1);
1341 CHECK_STRING (geo, 2);
1342
1343 switch (XFRAME (frame)->output_method)
1344 {
1345 case output_x_window:
1346 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
1347 XSTRING (geo)->data, XSTRING (name)->data);
1348 break;
1349
1350 default:
1351 return Qnil;
1352 }
1353
1354 for (i = 0; i < 4; i++)
1355 XFASTINT (nums[i]) = vals[i];
1356 return Fcons (frame, Flist (4, nums));
1357 return Qnil;
1358 }
1359 #endif /* not HAVE_X11 */
1360 \f
1361 choose_minibuf_frame ()
1362 {
1363 /* For lowest-level minibuf, put it on currently selected frame
1364 if frame has a minibuffer. */
1365
1366 if (minibuf_level == 0
1367 && selected_frame != 0
1368 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1369 {
1370 /* I don't think that any frames may validly have a null minibuffer
1371 window anymore. */
1372 if (NILP (selected_frame->minibuffer_window))
1373 abort ();
1374
1375 Fset_window_buffer (selected_frame->minibuffer_window,
1376 XWINDOW (minibuf_window)->buffer);
1377 minibuf_window = selected_frame->minibuffer_window;
1378 }
1379 }
1380 \f
1381 syms_of_frame ()
1382 {
1383 /*&&& init symbols here &&&*/
1384 Qframep = intern ("framep");
1385 staticpro (&Qframep);
1386 Qframe_live_p = intern ("frame-live-p");
1387 staticpro (&Qframe_live_p);
1388 Qheight = intern ("height");
1389 staticpro (&Qheight);
1390 Qicon = intern ("icon");
1391 staticpro (&Qicon);
1392 Qminibuffer = intern ("minibuffer");
1393 staticpro (&Qminibuffer);
1394 Qmodeline = intern ("modeline");
1395 staticpro (&Qmodeline);
1396 Qname = intern ("name");
1397 staticpro (&Qname);
1398 Qonly = intern ("only");
1399 staticpro (&Qonly);
1400 Qunsplittable = intern ("unsplittable");
1401 staticpro (&Qunsplittable);
1402 Qwidth = intern ("width");
1403 staticpro (&Qwidth);
1404 Qx = intern ("x");
1405 staticpro (&Qx);
1406
1407 staticpro (&Vframe_list);
1408
1409 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1410 "The initial frame-object, which represents Emacs's stdout.");
1411
1412 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1413 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1414 Vemacs_iconified = Qnil;
1415
1416 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1417 "Minibufferless frames use this frame's minibuffer.\n\
1418 \n\
1419 Emacs cannot create minibufferless frames unless this is set to an\n\
1420 appropriate surrogate.\n\
1421 \n\
1422 Emacs consults this variable only when creating minibufferless\n\
1423 frames; once the frame is created, it sticks with its assigned\n\
1424 minibuffer, no matter what this variable is set to. This means that\n\
1425 this variable doesn't necessarily say anything meaningful about the\n\
1426 current set of frames, or where the minibuffer is currently being\n\
1427 displayed.");
1428 Vdefault_minibuffer_frame = Qnil;
1429
1430 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1431 "Alist of default values for frame creation.\n\
1432 These may be set in your init file, like this:\n\
1433 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1434 These override values given in window system configuration data, like\n\
1435 X Windows' defaults database.\n\
1436 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1437 For values specific to the separate minibuffer frame, see\n\
1438 `minibuffer-frame-alist'.");
1439 Vdefault_frame_alist = Qnil;
1440
1441 defsubr (&Sframep);
1442 defsubr (&Sframe_live_p);
1443 defsubr (&Sselect_frame);
1444 defsubr (&Sselected_frame);
1445 defsubr (&Swindow_frame);
1446 defsubr (&Sframe_root_window);
1447 defsubr (&Sframe_selected_window);
1448 defsubr (&Sframe_list);
1449 defsubr (&Snext_frame);
1450 defsubr (&Sdelete_frame);
1451 defsubr (&Smouse_position);
1452 defsubr (&Sset_mouse_position);
1453 #if 0
1454 defsubr (&Sframe_configuration);
1455 defsubr (&Srestore_frame_configuration);
1456 #endif
1457 defsubr (&Smake_frame_visible);
1458 defsubr (&Smake_frame_invisible);
1459 defsubr (&Siconify_frame);
1460 defsubr (&Sframe_visible_p);
1461 defsubr (&Svisible_frame_list);
1462 defsubr (&Sframe_to_front);
1463 defsubr (&Sframe_to_back);
1464 defsubr (&Sredirect_frame_focus);
1465 defsubr (&Sframe_focus);
1466 defsubr (&Sframe_parameters);
1467 defsubr (&Smodify_frame_parameters);
1468 #if 0
1469 defsubr (&Sframe_pixel_size);
1470 defsubr (&Sframe_height);
1471 defsubr (&Sframe_width);
1472 #endif
1473 defsubr (&Sset_frame_height);
1474 defsubr (&Sset_frame_width);
1475 defsubr (&Sset_frame_size);
1476 defsubr (&Sset_frame_position);
1477 #ifndef HAVE_X11
1478 defsubr (&Srubber_band_rectangle);
1479 #endif /* HAVE_X11 */
1480 }
1481
1482 keys_of_frame ()
1483 {
1484 initial_define_lispy_key (global_map, "switch-frame", "select-frame");
1485 }
1486
1487 #else /* not MULTI_FRAME */
1488
1489 /* If we're not using multi-frame stuff, we still need to provide some
1490 support functions. */
1491
1492 /* Unless this function is defined, providing set-frame-height and
1493 set-frame-width doesn't help compatibility any, since they both
1494 want this as their first argument. */
1495 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1496 "Return the frame that is now selected.")
1497 ()
1498 {
1499 Lisp_Object tem;
1500 XFASTINT (tem) = 0;
1501 return tem;
1502 }
1503
1504 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1505 "Specify that the frame FRAME has LINES lines.\n\
1506 Optional third arg non-nil means that redisplay should use LINES lines\n\
1507 but that the idea of the actual height of the frame should not be changed.")
1508 (frame, rows, pretend)
1509 Lisp_Object frame, rows, pretend;
1510 {
1511 CHECK_NUMBER (rows, 0);
1512
1513 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1514 return Qnil;
1515 }
1516
1517 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1518 "Specify that the frame FRAME has COLS columns.\n\
1519 Optional third arg non-nil means that redisplay should use COLS columns\n\
1520 but that the idea of the actual width of the frame should not be changed.")
1521 (frame, cols, pretend)
1522 Lisp_Object frame, cols, pretend;
1523 {
1524 CHECK_NUMBER (cols, 0);
1525
1526 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1527 return Qnil;
1528 }
1529
1530 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1531 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1532 (frame, cols, rows)
1533 Lisp_Object frame, cols, rows;
1534 {
1535 CHECK_NUMBER (cols, 2);
1536 CHECK_NUMBER (rows, 1);
1537
1538 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1539
1540 return Qnil;
1541 }
1542
1543 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1544 "Return number of lines available for display on selected frame.")
1545 ()
1546 {
1547 return make_number (FRAME_HEIGHT (selected_frame));
1548 }
1549
1550 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1551 "Return number of columns available for display on selected frame.")
1552 ()
1553 {
1554 return make_number (FRAME_WIDTH (selected_frame));
1555 }
1556
1557 /* These are for backward compatibility with Emacs 18. */
1558
1559 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1560 "Tell redisplay that the screen has LINES lines.\n\
1561 Optional second arg non-nil means that redisplay should use LINES lines\n\
1562 but that the idea of the actual height of the screen should not be changed.")
1563 (lines, pretend)
1564 Lisp_Object lines, pretend;
1565 {
1566 CHECK_NUMBER (lines, 0);
1567
1568 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1569 return Qnil;
1570 }
1571
1572 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1573 "Tell redisplay that the screen has COLS columns.\n\
1574 Optional second arg non-nil means that redisplay should use COLS columns\n\
1575 but that the idea of the actual width of the screen should not be changed.")
1576 (cols, pretend)
1577 Lisp_Object cols, pretend;
1578 {
1579 CHECK_NUMBER (cols, 0);
1580
1581 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1582 return Qnil;
1583 }
1584
1585 syms_of_frame ()
1586 {
1587 defsubr (&Sset_frame_height);
1588 defsubr (&Sset_frame_width);
1589 defsubr (&Sset_frame_size);
1590 defsubr (&Sset_screen_height);
1591 defsubr (&Sset_screen_width);
1592 defsubr (&Sframe_height);
1593 Ffset (intern ("screen-height"), intern ("frame-height"));
1594 defsubr (&Sframe_width);
1595 Ffset (intern ("screen-width"), intern ("frame-width"));
1596 }
1597
1598 keys_of_frame ()
1599 {
1600 }
1601
1602 #endif /* not MULTI_FRAME */
1603
1604
1605
1606