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