entered into RCS
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1989, 1992 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
24 #ifdef MULTI_FRAME
25
26 #include "lisp.h"
27 #include "frame.h"
28 #include "window.h"
29 #include "termhooks.h"
30
31 Lisp_Object Vemacs_iconified;
32 Lisp_Object Qframep;
33 Lisp_Object Qlive_frame_p;
34 Lisp_Object Vframe_list;
35 Lisp_Object Vterminal_frame;
36 Lisp_Object Vdefault_minibuffer_frame;
37 Lisp_Object Vdefault_frame_alist;
38 Lisp_Object Qminibuffer;
39
40 extern Lisp_Object Vminibuffer_list;
41 extern Lisp_Object get_minibuffer ();
42 \f
43 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
44 "Return non-nil if OBJECT is a frame.\n\
45 Value is t for a termcap frame (a character-only terminal),\n\
46 `x' for an Emacs frame that is really an X window.\n\
47 Also see `live-frame-p'.")
48 (object)
49 Lisp_Object object;
50 {
51 if (XTYPE (object) != Lisp_Frame)
52 return Qnil;
53 switch (XFRAME (object)->output_method)
54 {
55 case output_termcap:
56 return Qt;
57 case output_x_window:
58 return intern ("x");
59 default:
60 abort ();
61 }
62 }
63
64 DEFUN ("live-frame-p", Flive_frame_p, Slive_frame_p, 1, 1, 0,
65 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
66 Value is nil if OBJECT is not a live frame. If object is a live\n\
67 frame, the return value indicates what sort of output device it is\n\
68 displayed on. Value is t for a termcap frame (a character-only\n\
69 terminal), `x' for an Emacs frame being displayed in an X window.")
70 (object)
71 Lisp_Object object;
72 {
73 return ((FRAMEP (object)
74 && FRAME_LIVE_P (XFRAME (object)))
75 ? Fframep (object)
76 : Qnil);
77 }
78
79 struct frame *
80 make_frame (mini_p)
81 int mini_p;
82 {
83 Lisp_Object frame;
84 register struct frame *f;
85 register Lisp_Object root_window;
86 register Lisp_Object mini_window;
87
88 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
89 - sizeof (Lisp_Object)))
90 / sizeof (Lisp_Object)),
91 make_number (0));
92 XSETTYPE (frame, Lisp_Frame);
93 f = XFRAME (frame);
94
95 f->cursor_x = 0;
96 f->cursor_y = 0;
97 f->current_glyphs = 0;
98 f->desired_glyphs = 0;
99 f->visible = 0;
100 f->display.nothing = 0;
101 f->iconified = 0;
102 f->wants_modeline = 1;
103 f->auto_raise = 0;
104 f->auto_lower = 0;
105 f->no_split = 0;
106 f->garbaged = 0;
107 f->has_minibuffer = mini_p;
108 f->focus_frame = frame;
109
110 f->param_alist = Qnil;
111
112 root_window = make_window (0);
113 if (mini_p)
114 {
115 mini_window = make_window (0);
116 XWINDOW (root_window)->next = mini_window;
117 XWINDOW (mini_window)->prev = root_window;
118 XWINDOW (mini_window)->mini_p = Qt;
119 XWINDOW (mini_window)->frame = frame;
120 f->minibuffer_window = mini_window;
121 }
122 else
123 {
124 mini_window = Qnil;
125 XWINDOW (root_window)->next = Qnil;
126 f->minibuffer_window = Qnil;
127 }
128
129 XWINDOW (root_window)->frame = frame;
130
131 /* 10 is arbitrary,
132 just so that there is "something there."
133 Correct size will be set up later with change_frame_size. */
134
135 f->width = 10;
136 f->height = 10;
137
138 XFASTINT (XWINDOW (root_window)->width) = 10;
139 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
140
141 if (mini_p)
142 {
143 XFASTINT (XWINDOW (mini_window)->width) = 10;
144 XFASTINT (XWINDOW (mini_window)->top) = 9;
145 XFASTINT (XWINDOW (mini_window)->height) = 1;
146 }
147
148 /* Choose a buffer for the frame's root window. */
149 {
150 Lisp_Object buf;
151
152 XWINDOW (root_window)->buffer = Qt;
153 buf = Fcurrent_buffer ();
154 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
155 a space), try to find another one. */
156 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
157 buf = Fother_buffer (buf);
158 Fset_window_buffer (root_window, buf);
159 }
160
161 if (mini_p)
162 {
163 XWINDOW (mini_window)->buffer = Qt;
164 Fset_window_buffer (mini_window,
165 (NILP (Vminibuffer_list)
166 ? get_minibuffer (0)
167 : Fcar (Vminibuffer_list)));
168 }
169
170 f->root_window = root_window;
171 f->selected_window = root_window;
172 /* Make sure this window seems more recently used than
173 a newly-created, never-selected window. */
174 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
175
176 Vframe_list = Fcons (frame, Vframe_list);
177
178 return f;
179 }
180 \f
181 /* Make a frame using a separate minibuffer window on another frame.
182 MINI_WINDOW is the minibuffer window to use. nil means use the
183 default (the global minibuffer). */
184
185 struct frame *
186 make_frame_without_minibuffer (mini_window)
187 register Lisp_Object mini_window;
188 {
189 register struct frame *f;
190
191 /* Choose the minibuffer window to use. */
192 if (NILP (mini_window))
193 {
194 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
195 error ("default-minibuffer-frame must be set when creating minibufferless frames");
196 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
197 error ("default-minibuffer-frame must be a live frame");
198 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
199 }
200 else
201 {
202 CHECK_WINDOW (mini_window, 0);
203 }
204
205 /* Make a frame containing just a root window. */
206 f = make_frame (0);
207
208 /* Install the chosen minibuffer window, with proper buffer. */
209 f->minibuffer_window = mini_window;
210 Fset_window_buffer (mini_window,
211 (NILP (Vminibuffer_list)
212 ? get_minibuffer (0)
213 : Fcar (Vminibuffer_list)));
214 return f;
215 }
216
217 /* Make a frame containing only a minibuffer window. */
218
219 struct frame *
220 make_minibuffer_frame ()
221 {
222 /* First make a frame containing just a root window, no minibuffer. */
223
224 register struct frame *f = make_frame (0);
225 register Lisp_Object mini_window;
226 register Lisp_Object frame;
227
228 XSET (frame, Lisp_Frame, f);
229
230 /* ??? Perhaps leave it to the user program to set auto_raise. */
231 f->auto_raise = 1;
232 f->auto_lower = 0;
233 f->no_split = 1;
234 f->wants_modeline = 0;
235 f->has_minibuffer = 1;
236
237 /* Now label the root window as also being the minibuffer.
238 Avoid infinite looping on the window chain by marking next pointer
239 as nil. */
240
241 mini_window = f->minibuffer_window = f->root_window;
242 XWINDOW (mini_window)->mini_p = Qt;
243 XWINDOW (mini_window)->next = Qnil;
244 XWINDOW (mini_window)->prev = mini_window;
245 XWINDOW (mini_window)->frame = frame;
246
247 /* Put the proper buffer in that window. */
248
249 Fset_window_buffer (mini_window,
250 (NILP (Vminibuffer_list)
251 ? get_minibuffer (0)
252 : Fcar (Vminibuffer_list)));
253 return f;
254 }
255 \f
256 /* Construct a frame that refers to the terminal (stdin and stdout). */
257
258 struct frame *
259 make_terminal_frame ()
260 {
261 register struct frame *f;
262
263 Vframe_list = Qnil;
264 f = make_frame (1);
265 f->name = build_string ("terminal");
266 f->visible = 1;
267 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
268 XSET (Vterminal_frame, Lisp_Frame, f);
269 return f;
270 }
271 \f
272 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, 0,
273 "Select the frame FRAME. FRAMES's selected window becomes \"the\"\n\
274 selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
275 focus on that frame.")
276 (frame, no_enter)
277 Lisp_Object frame, no_enter;
278 {
279 CHECK_LIVE_FRAME (frame, 0);
280
281 if (selected_frame == XFRAME (frame))
282 return frame;
283
284 selected_frame = XFRAME (frame);
285 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
286 last_nonminibuf_frame = selected_frame;
287
288 Fselect_window (XFRAME (frame)->selected_window);
289
290 #ifdef HAVE_X_WINDOWS
291 #ifdef MULTI_FRAME
292 if (FRAME_IS_X (XFRAME (frame))
293 && NILP (no_enter))
294 {
295 Ffocus_frame (frame);
296 }
297 #endif
298 #endif
299 choose_minibuf_frame ();
300
301 return frame;
302 }
303
304 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
305 "Return the frame that is now selected.")
306 ()
307 {
308 Lisp_Object tem;
309 XSET (tem, Lisp_Frame, selected_frame);
310 return tem;
311 }
312
313 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
314 "Return the frame object that window WINDOW is on.")
315 (window)
316 Lisp_Object window;
317 {
318 CHECK_WINDOW (window, 0);
319 return XWINDOW (window)->frame;
320 }
321
322 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
323 "Returns the root-window of FRAME.")
324 (frame)
325 Lisp_Object frame;
326 {
327 if (NILP (frame))
328 XSET (frame, Lisp_Frame, selected_frame);
329 else
330 CHECK_LIVE_FRAME (frame, 0);
331
332 return XFRAME (frame)->root_window;
333 }
334
335 DEFUN ("frame-selected-window", Fframe_selected_window,
336 Sframe_selected_window, 0, 1, 0,
337 "Return the selected window of frame object FRAME.")
338 (frame)
339 Lisp_Object frame;
340 {
341 if (NILP (frame))
342 XSET (frame, Lisp_Frame, selected_frame);
343 else
344 CHECK_LIVE_FRAME (frame, 0);
345
346 return XFRAME (frame)->selected_window;
347 }
348
349 DEFUN ("frame-list", Fframe_list, Sframe_list,
350 0, 0, 0,
351 "Return a list of all frames.")
352 ()
353 {
354 return Fcopy_sequence (Vframe_list);
355 }
356
357 #ifdef MULTI_FRAME
358
359 /* Return the next frame in the frame list after FRAME.
360 If MINIBUF is non-nil, include all frames.
361 If MINIBUF is nil, exclude minibuffer-only frames.
362 If MINIBUF is a window, include only frames using that window for
363 their minibuffer. */
364 Lisp_Object
365 next_frame (frame, minibuf)
366 Lisp_Object frame;
367 Lisp_Object minibuf;
368 {
369 Lisp_Object tail;
370 int passed = 0;
371
372 /* There must always be at least one frame in Vframe_list. */
373 if (! CONSP (Vframe_list))
374 abort ();
375
376 while (1)
377 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
378 {
379 if (passed)
380 {
381 Lisp_Object f = XCONS (tail)->car;
382
383 /* Decide whether this frame is eligible to be returned,
384 according to minibuf. */
385 if ((NILP (minibuf) && ! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
386 || XTYPE (minibuf) != Lisp_Window
387 || EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
388 || EQ (f, frame))
389 return f;
390 }
391
392 if (EQ (frame, XCONS (tail)->car))
393 passed++;
394 }
395 }
396
397 /* Return the previous frame in the frame list before FRAME.
398 If MINIBUF is non-nil, include all frames.
399 If MINIBUF is nil, exclude minibuffer-only frames.
400 If MINIBUF is a window, include only frames using that window for
401 their minibuffer. */
402 Lisp_Object
403 prev_frame (frame, minibuf)
404 Lisp_Object frame;
405 Lisp_Object minibuf;
406 {
407 Lisp_Object tail;
408 Lisp_Object prev;
409
410 /* There must always be at least one frame in Vframe_list. */
411 if (! CONSP (Vframe_list))
412 abort ();
413
414 prev = Qnil;
415 while (1)
416 {
417 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
418 {
419 Lisp_Object scr = XCONS (tail)->car;
420
421 if (XTYPE (scr) != Lisp_Frame)
422 abort ();
423
424 if (EQ (frame, scr) && !NILP (prev))
425 return prev;
426
427 /* Decide whether this frame is eligible to be returned,
428 according to minibuf. */
429 if ((NILP (minibuf) && ! FRAME_MINIBUF_ONLY_P (XFRAME (scr)))
430 || XTYPE (minibuf) != Lisp_Window
431 || EQ (FRAME_MINIBUF_WINDOW (XFRAME (scr)), minibuf))
432 prev = scr;
433 }
434
435 if (NILP (prev))
436 /* We went through the whole frame list without finding a single
437 acceptable frame. Return the original frame. */
438 prev = frame;
439 }
440
441 }
442
443 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
444 "Return the next frame in the frame list after FRAME.\n\
445 If optional argument MINIBUF is non-nil, include all frames. If\n\
446 MINIBUF is nil or omitted, exclude minibuffer-only frames. If\n\
447 MINIBUF is a window, include only frames using that window for their\n\
448 minibuffer.")
449 (frame, miniframe)
450 Lisp_Object frame, miniframe;
451 {
452 Lisp_Object tail;
453
454 if (NILP (frame))
455 XSET (frame, Lisp_Frame, selected_frame);
456 else
457 CHECK_LIVE_FRAME (frame, 0);
458
459 return next_frame (frame, miniframe);
460 }
461 #endif /* MULTI_FRAME */
462 \f
463 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
464 "Delete FRAME, permanently eliminating it from use.\n\
465 If omitted, FRAME defaults to the selected frame.\n\
466 A frame may not be deleted if its minibuffer is used by other frames.")
467 (frame)
468 Lisp_Object frame;
469 {
470 struct frame *f;
471 union display displ;
472
473 if (EQ (frame, Qnil))
474 {
475 f = selected_frame;
476 XSET (frame, Lisp_Frame, f);
477 }
478 else
479 {
480 CHECK_FRAME (frame, 0);
481 f = XFRAME (frame);
482 }
483
484 if (! FRAME_LIVE_P (f))
485 return;
486
487 /* Are there any other frames besides this one? */
488 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
489 error ("Attempt to delete the only frame");
490
491 /* Does this frame have a minibuffer, and is it the surrogate
492 minibuffer for any other frame? */
493 if (FRAME_HAS_MINIBUF (XFRAME (frame)))
494 {
495 Lisp_Object frames;
496
497 for (frames = Vframe_list;
498 CONSP (frames);
499 frames = XCONS (frames)->cdr)
500 {
501 Lisp_Object this = XCONS (frames)->car;
502
503 if (! EQ (this, frame)
504 && EQ (frame,
505 (WINDOW_FRAME
506 (XWINDOW
507 (FRAME_MINIBUF_WINDOW
508 (XFRAME (this)))))))
509 error ("Attempt to delete a surrogate minibuffer frame");
510 }
511 }
512
513 /* Don't let the frame remain selected. */
514 if (f == selected_frame)
515 Fselect_frame (next_frame (frame, Qt));
516
517 /* Don't allow minibuf_window to remain on a deleted frame. */
518 if (EQ (f->minibuffer_window, minibuf_window))
519 {
520 Fset_window_buffer (selected_frame->minibuffer_window,
521 XWINDOW (minibuf_window)->buffer);
522 minibuf_window = selected_frame->minibuffer_window;
523 }
524
525 Vframe_list = Fdelq (frame, Vframe_list);
526 f->visible = 0;
527 displ = f->display;
528 f->display.nothing = 0;
529
530 #ifdef HAVE_X_WINDOWS
531 if (FRAME_IS_X (f))
532 x_destroy_window (f, displ);
533 #endif
534
535 /* If we've deleted the last_nonminibuf_frame, then try to find
536 another one. */
537 if (f == last_nonminibuf_frame)
538 {
539 Lisp_Object frames;
540
541 last_nonminibuf_frame = 0;
542
543 for (frames = Vframe_list;
544 CONSP (frames);
545 frames = XCONS (frames)->cdr)
546 {
547 f = XFRAME (XCONS (frames)->car);
548 if (!FRAME_MINIBUF_ONLY_P (f))
549 {
550 last_nonminibuf_frame = f;
551 break;
552 }
553 }
554 }
555
556 /* If we've deleted Vdefault_minibuffer_frame, try to find another
557 one. Prefer minibuffer-only frames, but also notice frames
558 with other windows. */
559 if (EQ (frame, Vdefault_minibuffer_frame))
560 {
561 Lisp_Object frames;
562
563 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
564 Lisp_Object frame_with_minibuf = Qnil;
565
566 for (frames = Vframe_list;
567 CONSP (frames);
568 frames = XCONS (frames)->cdr)
569 {
570 Lisp_Object this = XCONS (frames)->car;
571
572 if (XTYPE (this) != Lisp_Frame)
573 abort ();
574 f = XFRAME (this);
575
576 if (FRAME_HAS_MINIBUF (f))
577 {
578 frame_with_minibuf = this;
579 if (FRAME_MINIBUF_ONLY_P (f))
580 break;
581 }
582 }
583
584 /* We know that there must be some frame with a minibuffer out
585 there. If this were not true, all of the frames present
586 would have to be minibufferless, which implies that at some
587 point their minibuffer frames must have been deleted, but
588 that is prohibited at the top; you can't delete surrogate
589 minibuffer frames. */
590 if (NILP (frame_with_minibuf))
591 abort ();
592
593 Vdefault_minibuffer_frame = frame_with_minibuf;
594 }
595
596 return Qnil;
597 }
598 \f
599 /* Return mouse position in character cell units. */
600
601 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
602 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
603 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
604 to read the mouse position, it returns the selected frame for FRAME\n\
605 and nil for X and Y.")
606 ()
607 {
608 Lisp_Object x, y, dummy;
609 FRAME_PTR f;
610
611 if (mouse_position_hook)
612 (*mouse_position_hook) (&f, &x, &y, &dummy);
613 else
614 {
615 f = selected_frame;
616 x = y = Qnil;
617 }
618
619 XSET (dummy, Lisp_Frame, f);
620 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
621 }
622
623 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
624 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
625 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
626 (frame, x, y)
627 Lisp_Object frame, x, y;
628 {
629 CHECK_LIVE_FRAME (frame, 0);
630 CHECK_NUMBER (x, 2);
631 CHECK_NUMBER (y, 1);
632
633 #ifdef HAVE_X_WINDOWS
634 if (FRAME_IS_X (XFRAME (frame)))
635 /* Warping the mouse will cause enternotify and focus events. */
636 x_set_mouse_position (XFRAME (frame), x, y);
637 #endif
638
639 return Qnil;
640 }
641 \f
642 #if 0
643 /* ??? Can this be replaced with a Lisp function?
644 It is used in minibuf.c. Can we get rid of that?
645 Yes. All uses in minibuf.c are gone, and parallels to these
646 functions have been defined in frame.el. */
647
648 DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
649 0, 0, 0,
650 "Return object describing current frame configuration.\n\
651 The frame configuration is the current mouse position and selected frame.\n\
652 This object can be given to `restore-frame-configuration'\n\
653 to restore this frame configuration.")
654 ()
655 {
656 Lisp_Object c, time;
657
658 c = Fmake_vector (make_number(4), Qnil);
659 XVECTOR (c)->contents[0] = Fselected_frame();
660 if (mouse_position_hook)
661 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
662 &XVECTOR (c)->contents[2],
663 &XVECTOR (c)->contents[3],
664 &time);
665 return c;
666 }
667
668 DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
669 Srestore_frame_configuration,
670 1, 1, 0,
671 "Restores frame configuration CONFIGURATION.")
672 (config)
673 Lisp_Object config;
674 {
675 Lisp_Object x_pos, y_pos, frame;
676
677 CHECK_VECTOR (config, 0);
678 if (XVECTOR (config)->size != 3)
679 {
680 error ("Wrong size vector passed to restore-frame-configuration");
681 }
682 frame = XVECTOR (config)->contents[0];
683 CHECK_LIVE_FRAME (frame, 0);
684
685 Fselect_frame (frame, Qnil);
686
687 #if 0
688 /* This seems to interfere with the frame selection mechanism. jla */
689 x_pos = XVECTOR (config)->contents[2];
690 y_pos = XVECTOR (config)->contents[3];
691 set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
692 #endif
693
694 return frame;
695 }
696 #endif
697 \f
698 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
699 1, 1, 0,
700 "Make the frame FRAME visible (assuming it is an X-window).\n\
701 Also raises the frame so that nothing obscures it.")
702 (frame)
703 Lisp_Object frame;
704 {
705 CHECK_LIVE_FRAME (frame, 0);
706
707 if (FRAME_IS_X (XFRAME (frame)))
708 x_make_frame_visible (XFRAME (frame));
709
710 return frame;
711 }
712
713 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
714 1, 1, 0,
715 "Make the frame FRAME invisible (assuming it is an X-window).")
716 (frame)
717 Lisp_Object frame;
718 {
719 CHECK_LIVE_FRAME (frame, 0);
720
721 if (FRAME_IS_X (XFRAME (frame)))
722 x_make_frame_invisible (XFRAME (frame));
723
724 return Qnil;
725 }
726
727 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
728 1, 1, 0,
729 "Make the frame FRAME into an icon.")
730 (frame)
731 Lisp_Object frame;
732 {
733 CHECK_LIVE_FRAME (frame, 0);
734
735 if (FRAME_IS_X (XFRAME (frame)))
736 x_iconify_frame (XFRAME (frame));
737
738 return Qnil;
739 }
740
741 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
742 1, 1, 0,
743 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
744 A frame that is not \"visible\" is not updated and, if it works through\n\
745 a window system, it may not show at all.\n\
746 Return the symbol `icon' if window is visible only as an icon.")
747 (frame)
748 Lisp_Object frame;
749 {
750 CHECK_LIVE_FRAME (frame, 0);
751
752 if (XFRAME (frame)->visible)
753 return Qt;
754 if (XFRAME (frame)->iconified)
755 return intern ("icon");
756 return Qnil;
757 }
758
759 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
760 0, 0, 0,
761 "Return a list of all frames now \"visible\" (being updated).")
762 ()
763 {
764 Lisp_Object tail, frame;
765 struct frame *f;
766 Lisp_Object value;
767
768 value = Qnil;
769 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
770 {
771 frame = XCONS (tail)->car;
772 if (XTYPE (frame) != Lisp_Frame)
773 continue;
774 f = XFRAME (frame);
775 if (f->visible)
776 value = Fcons (frame, value);
777 }
778 return value;
779 }
780
781
782 \f
783 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
784 1, 2, 0,
785 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
786 This means that, after reading a keystroke typed at FRAME,\n\
787 `last-event-frame' will be FOCUS-FRAME.\n\
788 \n\
789 If FOCUS-FRAME is omitted or eq to FRAME, any existing redirection is\n\
790 cancelled, and the frame again receives its own keystrokes.\n\
791 \n\
792 The redirection lasts until the next call to `redirect-frame-focus'\n\
793 or `select-frame'.\n\
794 \n\
795 This is useful for temporarily redirecting keystrokes to the minibuffer\n\
796 window when a frame doesn't have its own minibuffer.")
797 (frame, focus_frame)
798 Lisp_Object frame, focus_frame;
799 {
800 CHECK_LIVE_FRAME (frame, 0);
801
802 if (NILP (focus_frame))
803 focus_frame = frame;
804 else
805 CHECK_LIVE_FRAME (focus_frame, 1);
806
807 XFRAME (frame)->focus_frame = focus_frame;
808
809 if (frame_rehighlight_hook)
810 (*frame_rehighlight_hook) ();
811
812 return Qnil;
813 }
814
815
816 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
817 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
818 See `redirect-frame-focus'.")
819 (frame)
820 Lisp_Object frame;
821 {
822 CHECK_LIVE_FRAME (frame, 0);
823 return FRAME_FOCUS_FRAME (XFRAME (frame));
824 }
825
826
827 \f
828 Lisp_Object
829 get_frame_param (frame, prop)
830 register struct frame *frame;
831 Lisp_Object prop;
832 {
833 register Lisp_Object tem;
834
835 tem = Fassq (prop, frame->param_alist);
836 if (EQ (tem, Qnil))
837 return tem;
838 return Fcdr (tem);
839 }
840
841 void
842 store_in_alist (alistptr, propname, val)
843 Lisp_Object *alistptr, val;
844 char *propname;
845 {
846 register Lisp_Object tem;
847 register Lisp_Object prop;
848
849 prop = intern (propname);
850 tem = Fassq (prop, *alistptr);
851 if (EQ (tem, Qnil))
852 *alistptr = Fcons (Fcons (prop, val), *alistptr);
853 else
854 Fsetcdr (tem, val);
855 }
856
857 void
858 store_frame_param (f, prop, val)
859 struct frame *f;
860 Lisp_Object prop, val;
861 {
862 register Lisp_Object tem;
863
864 tem = Fassq (prop, f->param_alist);
865 if (EQ (tem, Qnil))
866 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
867 else
868 Fsetcdr (tem, val);
869
870 if (EQ (prop, Qminibuffer)
871 && XTYPE (val) == Lisp_Window)
872 {
873 if (! MINI_WINDOW_P (XWINDOW (val)))
874 error ("Surrogate minibuffer windows must be minibuffer windows.");
875
876 if (FRAME_HAS_MINIBUF (f) || FRAME_MINIBUF_ONLY_P (f))
877 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
878
879 /* Install the chosen minibuffer window, with proper buffer. */
880 f->minibuffer_window = val;
881 }
882 }
883
884 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
885 "Return the parameters-alist of frame FRAME.\n\
886 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
887 The meaningful PARMs depend on the kind of frame.")
888 (frame)
889 Lisp_Object frame;
890 {
891 Lisp_Object alist;
892 struct frame *f;
893
894 if (EQ (frame, Qnil))
895 f = selected_frame;
896 else
897 {
898 CHECK_FRAME (frame, 0);
899 f = XFRAME (frame);
900 }
901
902 if (f->display.nothing == 0)
903 return Qnil;
904
905 alist = Fcopy_alist (f->param_alist);
906 store_in_alist (&alist, "name", f->name);
907 store_in_alist (&alist, "height", make_number (f->height));
908 store_in_alist (&alist, "width", make_number (f->width));
909 store_in_alist (&alist, "modeline", (f->wants_modeline ? Qt : Qnil));
910 store_in_alist (&alist, "minibuffer",
911 (FRAME_HAS_MINIBUF (f)
912 ? (FRAME_MINIBUF_ONLY_P (f) ? intern ("only") : Qt)
913 : FRAME_MINIBUF_WINDOW (f)));
914 store_in_alist (&alist, "unsplittable", (f->no_split ? Qt : Qnil));
915
916 if (FRAME_IS_X (f))
917 x_report_frame_params (f, &alist);
918 return alist;
919 }
920
921 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
922 Smodify_frame_parameters, 2, 2, 0,
923 "Modify the parameters of frame FRAME according to ALIST.\n\
924 ALIST is an alist of parameters to change and their new values.\n\
925 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
926 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
927 (frame, alist)
928 Lisp_Object frame, alist;
929 {
930 register struct frame *f;
931 register Lisp_Object tail, elt, prop, val;
932
933 if (EQ (frame, Qnil))
934 f = selected_frame;
935 else
936 {
937 CHECK_LIVE_FRAME (frame, 0);
938 f = XFRAME (frame);
939 }
940
941 if (FRAME_IS_X (f))
942 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
943 {
944 elt = Fcar (tail);
945 prop = Fcar (elt);
946 val = Fcdr (elt);
947 x_set_frame_param (f, prop, val,
948 get_frame_param (f, prop));
949 store_frame_param (f, prop, val);
950 }
951
952 return Qnil;
953 }
954 \f
955
956 DEFUN ("frame-pixel-size", Fframe_pixel_size,
957 Sframe_pixel_size, 1, 1, 0,
958 "Return a cons (width . height) of FRAME's size in pixels.")
959 (frame)
960 Lisp_Object frame;
961 {
962 register struct frame *f;
963 int width, height;
964
965 CHECK_LIVE_FRAME (frame, 0);
966 f = XFRAME (frame);
967
968 return Fcons (make_number (x_pixel_width (f)),
969 make_number (x_pixel_height (f)));
970 }
971
972 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
973 "Return number of lines available for display on selected frame.")
974 ()
975 {
976 return make_number (FRAME_HEIGHT (selected_frame));
977 }
978
979 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
980 "Return number of columns available for display on selected frame.")
981 ()
982 {
983 return make_number (FRAME_WIDTH (selected_frame));
984 }
985
986 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
987 "Specify that the frame FRAME has LINES lines.\n\
988 Optional third arg non-nil means that redisplay should use LINES lines\n\
989 but that the idea of the actual height of the frame should not be changed.")
990 (frame, rows, pretend)
991 Lisp_Object rows, pretend;
992 {
993 register struct frame *f;
994
995 CHECK_NUMBER (rows, 0);
996 if (NILP (frame))
997 f = selected_frame;
998 else
999 {
1000 CHECK_LIVE_FRAME (frame, 0);
1001 f = XFRAME (frame);
1002 }
1003
1004 if (FRAME_IS_X (f))
1005 {
1006 if (XINT (rows) != f->width)
1007 x_set_window_size (f, f->width, XINT (rows));
1008 }
1009 else
1010 change_frame_size (f, XINT (rows), 0, !NILP (pretend));
1011 return Qnil;
1012 }
1013
1014 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1015 "Specify that the frame FRAME has COLS columns.\n\
1016 Optional third arg non-nil means that redisplay should use COLS columns\n\
1017 but that the idea of the actual width of the frame should not be changed.")
1018 (frame, cols, pretend)
1019 Lisp_Object cols, pretend;
1020 {
1021 register struct frame *f;
1022 CHECK_NUMBER (cols, 0);
1023 if (NILP (frame))
1024 f = selected_frame;
1025 else
1026 {
1027 CHECK_LIVE_FRAME (frame, 0);
1028 f = XFRAME (frame);
1029 }
1030
1031 if (FRAME_IS_X (f))
1032 {
1033 if (XINT (cols) != f->width)
1034 x_set_window_size (f, XINT (cols), f->height);
1035 }
1036 else
1037 change_frame_size (selected_frame, 0, XINT (cols), !NILP (pretend));
1038 return Qnil;
1039 }
1040
1041 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1042 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1043 (frame, cols, rows)
1044 Lisp_Object frame, cols, rows;
1045 {
1046 register struct frame *f;
1047 int mask;
1048
1049 CHECK_LIVE_FRAME (frame, 0);
1050 CHECK_NUMBER (cols, 2);
1051 CHECK_NUMBER (rows, 1);
1052 f = XFRAME (frame);
1053
1054 if (FRAME_IS_X (f))
1055 {
1056 if (XINT (rows) != f->height || XINT (cols) != f->width)
1057 x_set_window_size (f, XINT (cols), XINT (rows));
1058 }
1059 else
1060 change_frame_size (f, XINT (rows), XINT (cols), 0);
1061
1062 return Qnil;
1063 }
1064
1065 DEFUN ("set-frame-position", Fset_frame_position,
1066 Sset_frame_position, 3, 3, 0,
1067 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1068 If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1069 the leftmost or bottommost position FRAME could occupy without going\n\
1070 off the frame.")
1071 (frame, xoffset, yoffset)
1072 Lisp_Object frame, xoffset, yoffset;
1073 {
1074 register struct frame *f;
1075 int mask;
1076
1077 CHECK_LIVE_FRAME (frame, 0);
1078 CHECK_NUMBER (xoffset, 1);
1079 CHECK_NUMBER (yoffset, 2);
1080 f = XFRAME (frame);
1081
1082 if (FRAME_IS_X (f))
1083 x_set_offset (f, XINT (xoffset), XINT (yoffset));
1084
1085 return Qt;
1086 }
1087 \f
1088 #ifndef HAVE_X11
1089 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1090 3, 3, "",
1091 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1092 Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
1093 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1094 specify defaults for some sizes/positions. If GEO specifies everything,\n\
1095 the mouse is not used.\n\
1096 Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1097 (frame, name, geo)
1098 Lisp_Object frame;
1099 Lisp_Object name;
1100 Lisp_Object geo;
1101 {
1102 int vals[4];
1103 Lisp_Object nums[4];
1104 int i;
1105
1106 CHECK_FRAME (frame, 0);
1107 CHECK_STRING (name, 1);
1108 CHECK_STRING (geo, 2);
1109
1110 switch (XFRAME (frame)->output_method)
1111 {
1112 case output_x_window:
1113 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
1114 XSTRING (geo)->data, XSTRING (name)->data);
1115 break;
1116
1117 default:
1118 return Qnil;
1119 }
1120
1121 for (i = 0; i < 4; i++)
1122 XFASTINT (nums[i]) = vals[i];
1123 return Fcons (frame, Flist (4, nums));
1124 return Qnil;
1125 }
1126 #endif /* not HAVE_X11 */
1127 \f
1128 choose_minibuf_frame ()
1129 {
1130 /* For lowest-level minibuf, put it on currently selected frame
1131 if frame has a minibuffer. */
1132 if (minibuf_level == 0
1133 && selected_frame != 0
1134 && !EQ (minibuf_window, selected_frame->minibuffer_window)
1135 && !EQ (Qnil, selected_frame->minibuffer_window))
1136 {
1137 Fset_window_buffer (selected_frame->minibuffer_window,
1138 XWINDOW (minibuf_window)->buffer);
1139 minibuf_window = selected_frame->minibuffer_window;
1140 }
1141 }
1142 \f
1143 syms_of_frame ()
1144 {
1145 Qframep = intern ("framep");
1146 Qlive_frame_p = intern ("live_frame_p");
1147 Qminibuffer = intern ("minibuffer");
1148
1149 staticpro (&Qframep);
1150 staticpro (&Qlive_frame_p);
1151 staticpro (&Qminibuffer);
1152
1153 staticpro (&Vframe_list);
1154
1155 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1156 "The initial frame-object, which represents Emacs's stdout.");
1157
1158 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1159 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1160 Vemacs_iconified = Qnil;
1161
1162 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1163 "Minibufferless frames use this frame's minibuffer.\n\
1164 \n\
1165 Emacs cannot create minibufferless frames unless this is set to an\n\
1166 appropriate surrogate.\n\
1167 \n\
1168 Emacs consults this variable only when creating minibufferless\n\
1169 frames; once the frame is created, it sticks with its assigned\n\
1170 minibuffer, no matter what this variable is set to. This means that\n\
1171 this variable doesn't necessarily say anything meaningful about the\n\
1172 current set of frames, or where the minibuffer is currently being\n\
1173 displayed.");
1174 Vdefault_minibuffer_frame = Qnil;
1175
1176 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1177 "Alist of default values for frame creation.\n\
1178 These may be set in your init file, like this:\n\
1179 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1180 These override values given in window system configuration data, like\n\
1181 X Windows' defaults database.\n\
1182 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1183 For values specific to the separate minibuffer frame, see\n\
1184 `minibuffer-frame-alist'.");
1185 Vdefault_frame_alist = Qnil;
1186
1187 defsubr (&Sframep);
1188 defsubr (&Slive_frame_p);
1189 defsubr (&Sselect_frame);
1190 defsubr (&Sselected_frame);
1191 defsubr (&Swindow_frame);
1192 defsubr (&Sframe_root_window);
1193 defsubr (&Sframe_selected_window);
1194 defsubr (&Sframe_list);
1195 defsubr (&Snext_frame);
1196 defsubr (&Sdelete_frame);
1197 defsubr (&Smouse_position);
1198 defsubr (&Sset_mouse_position);
1199 #if 0
1200 defsubr (&Sframe_configuration);
1201 defsubr (&Srestore_frame_configuration);
1202 #endif
1203 defsubr (&Smake_frame_visible);
1204 defsubr (&Smake_frame_invisible);
1205 defsubr (&Siconify_frame);
1206 defsubr (&Sframe_visible_p);
1207 defsubr (&Svisible_frame_list);
1208 defsubr (&Sredirect_frame_focus);
1209 defsubr (&Sframe_focus);
1210 defsubr (&Sframe_parameters);
1211 defsubr (&Smodify_frame_parameters);
1212 defsubr (&Sframe_pixel_size);
1213 defsubr (&Sframe_height);
1214 defsubr (&Sframe_width);
1215 defsubr (&Sset_frame_height);
1216 defsubr (&Sset_frame_width);
1217 defsubr (&Sset_frame_size);
1218 defsubr (&Sset_frame_position);
1219 #ifndef HAVE_X11
1220 defsubr (&Srubber_band_rectangle);
1221 #endif /* HAVE_X11 */
1222 }
1223
1224 #endif