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