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