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