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