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