[MULTI_FRAME] (Factive_minibuffer_window): New function.
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995 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 <config.h>
21
22 #include <stdio.h>
23 #include "lisp.h"
24 #include "frame.h"
25 #include "termhooks.h"
26 #include "window.h"
27 #ifdef MSDOS
28 #include "msdos.h"
29 #endif
30
31 #ifdef MULTI_FRAME
32
33 #include "buffer.h"
34
35 /* These help us bind and responding to switch-frame events. */
36 #include "commands.h"
37 #include "keyboard.h"
38
39 Lisp_Object Vemacs_iconified;
40 Lisp_Object Vframe_list;
41 Lisp_Object Vterminal_frame;
42 Lisp_Object Vdefault_minibuffer_frame;
43 Lisp_Object Vdefault_frame_alist;
44
45 /* Evaluate this expression to rebuild the section of syms_of_frame
46 that initializes and staticpros the symbols declared below. Note
47 that Emacs 18 has a bug that keeps C-x C-e from being able to
48 evaluate this expression.
49
50 (progn
51 ;; Accumulate a list of the symbols we want to initialize from the
52 ;; declarations at the top of the file.
53 (goto-char (point-min))
54 (search-forward "/\*&&& symbols declared here &&&*\/\n")
55 (let (symbol-list)
56 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
57 (setq symbol-list
58 (cons (buffer-substring (match-beginning 1) (match-end 1))
59 symbol-list))
60 (forward-line 1))
61 (setq symbol-list (nreverse symbol-list))
62 ;; Delete the section of syms_of_... where we initialize the symbols.
63 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
64 (let ((start (point)))
65 (while (looking-at "^ Q")
66 (forward-line 2))
67 (kill-region start (point)))
68 ;; Write a new symbol initialization section.
69 (while symbol-list
70 (insert (format " %s = intern (\"" (car symbol-list)))
71 (let ((start (point)))
72 (insert (substring (car symbol-list) 1))
73 (subst-char-in-region start (point) ?_ ?-))
74 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
75 (setq symbol-list (cdr symbol-list)))))
76 */
77
78 /*&&& symbols declared here &&&*/
79 Lisp_Object Qframep;
80 Lisp_Object Qframe_live_p;
81 Lisp_Object Qheight;
82 Lisp_Object Qicon;
83 Lisp_Object Qminibuffer;
84 Lisp_Object Qmodeline;
85 Lisp_Object Qname;
86 Lisp_Object Qonly;
87 Lisp_Object Qunsplittable;
88 Lisp_Object Qmenu_bar_lines;
89 Lisp_Object Qwidth;
90 Lisp_Object Qx;
91 Lisp_Object Qvisible;
92 Lisp_Object Qbuffer_predicate;
93
94 extern Lisp_Object Vminibuffer_list;
95 extern Lisp_Object get_minibuffer ();
96 extern Lisp_Object Fhandle_switch_frame ();
97 extern Lisp_Object Fredirect_frame_focus ();
98 \f
99 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
100 "Return non-nil if OBJECT is a frame.\n\
101 Value is t for a termcap frame (a character-only terminal),\n\
102 `x' for an Emacs frame that is really an X window,\n\
103 `pc' for a direct-write MS-DOS frame.\n\
104 See also `frame-live-p'.")
105 (object)
106 Lisp_Object object;
107 {
108 if (!FRAMEP (object))
109 return Qnil;
110 switch (XFRAME (object)->output_method)
111 {
112 case output_termcap:
113 return Qt;
114 case output_x_window:
115 return Qx;
116 /* The `pc' case is in the Fframep below. */
117 default:
118 abort ();
119 }
120 }
121
122 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
123 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
124 Value is nil if OBJECT is not a live frame. If object is a live\n\
125 frame, the return value indicates what sort of output device it is\n\
126 displayed on. Value is t for a termcap frame (a character-only\n\
127 terminal), `x' for an Emacs frame being displayed in an X window.")
128 (object)
129 Lisp_Object object;
130 {
131 return ((FRAMEP (object)
132 && FRAME_LIVE_P (XFRAME (object)))
133 ? Fframep (object)
134 : Qnil);
135 }
136
137 struct frame *
138 make_frame (mini_p)
139 int mini_p;
140 {
141 Lisp_Object frame;
142 register struct frame *f;
143 register Lisp_Object root_window;
144 register Lisp_Object mini_window;
145 register struct Lisp_Vector *vec;
146 int i;
147
148 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
149 for (i = 0; i < VECSIZE (struct frame); i++)
150 XSETFASTINT (vec->contents[i], 0);
151 vec->size = VECSIZE (struct frame);
152 f = (struct frame *)vec;
153 XSETFRAME (frame, f);
154
155 f->cursor_x = 0;
156 f->cursor_y = 0;
157 f->current_glyphs = 0;
158 f->desired_glyphs = 0;
159 f->visible = 0;
160 f->async_visible = 0;
161 f->display.nothing = 0;
162 f->iconified = 0;
163 f->async_iconified = 0;
164 f->wants_modeline = 1;
165 f->auto_raise = 0;
166 f->auto_lower = 0;
167 f->no_split = 0;
168 f->garbaged = 0;
169 f->has_minibuffer = mini_p;
170 f->focus_frame = Qnil;
171 f->explicit_name = 0;
172 f->can_have_scroll_bars = 0;
173 f->has_vertical_scroll_bars = 0;
174 f->param_alist = Qnil;
175 f->scroll_bars = Qnil;
176 f->condemned_scroll_bars = Qnil;
177 f->face_alist = Qnil;
178 f->menu_bar_items = Qnil;
179 f->menu_bar_vector = Qnil;
180 f->menu_bar_items_used = 0;
181 f->buffer_predicate = Qnil;
182 #ifdef MULTI_KBOARD
183 f->kboard = initial_kboard;
184 #endif
185
186 root_window = make_window ();
187 if (mini_p)
188 {
189 mini_window = make_window ();
190 XWINDOW (root_window)->next = mini_window;
191 XWINDOW (mini_window)->prev = root_window;
192 XWINDOW (mini_window)->mini_p = Qt;
193 XWINDOW (mini_window)->frame = frame;
194 f->minibuffer_window = mini_window;
195 }
196 else
197 {
198 mini_window = Qnil;
199 XWINDOW (root_window)->next = Qnil;
200 f->minibuffer_window = Qnil;
201 }
202
203 XWINDOW (root_window)->frame = frame;
204
205 /* 10 is arbitrary,
206 just so that there is "something there."
207 Correct size will be set up later with change_frame_size. */
208
209 f->width = 10;
210 f->height = 10;
211
212 XSETFASTINT (XWINDOW (root_window)->width, 10);
213 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
214
215 if (mini_p)
216 {
217 XSETFASTINT (XWINDOW (mini_window)->width, 10);
218 XSETFASTINT (XWINDOW (mini_window)->top, 9);
219 XSETFASTINT (XWINDOW (mini_window)->height, 1);
220 }
221
222 /* Choose a buffer for the frame's root window. */
223 {
224 Lisp_Object buf;
225
226 XWINDOW (root_window)->buffer = Qt;
227 buf = Fcurrent_buffer ();
228 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
229 a space), try to find another one. */
230 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
231 buf = Fother_buffer (buf, Qnil);
232 Fset_window_buffer (root_window, buf);
233 }
234
235 if (mini_p)
236 {
237 XWINDOW (mini_window)->buffer = Qt;
238 Fset_window_buffer (mini_window,
239 (NILP (Vminibuffer_list)
240 ? get_minibuffer (0)
241 : Fcar (Vminibuffer_list)));
242 }
243
244 f->root_window = root_window;
245 f->selected_window = root_window;
246 /* Make sure this window seems more recently used than
247 a newly-created, never-selected window. */
248 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
249
250 return f;
251 }
252 \f
253 /* Make a frame using a separate minibuffer window on another frame.
254 MINI_WINDOW is the minibuffer window to use. nil means use the
255 default (the global minibuffer). */
256
257 struct frame *
258 make_frame_without_minibuffer (mini_window)
259 register Lisp_Object mini_window;
260 {
261 register struct frame *f;
262
263 /* Choose the minibuffer window to use. */
264 if (NILP (mini_window))
265 {
266 if (!FRAMEP (Vdefault_minibuffer_frame))
267 error ("default-minibuffer-frame must be set when creating minibufferless frames");
268 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
269 error ("default-minibuffer-frame must be a live frame");
270 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
271 }
272 else
273 {
274 CHECK_LIVE_WINDOW (mini_window, 0);
275 }
276
277 /* Make a frame containing just a root window. */
278 f = make_frame (0);
279
280 /* Install the chosen minibuffer window, with proper buffer. */
281 f->minibuffer_window = mini_window;
282 Fset_window_buffer (mini_window,
283 (NILP (Vminibuffer_list)
284 ? get_minibuffer (0)
285 : Fcar (Vminibuffer_list)));
286 return f;
287 }
288
289 /* Make a frame containing only a minibuffer window. */
290
291 struct frame *
292 make_minibuffer_frame ()
293 {
294 /* First make a frame containing just a root window, no minibuffer. */
295
296 register struct frame *f = make_frame (0);
297 register Lisp_Object mini_window;
298 register Lisp_Object frame;
299
300 XSETFRAME (frame, f);
301
302 f->auto_raise = 0;
303 f->auto_lower = 0;
304 f->no_split = 1;
305 f->wants_modeline = 0;
306 f->has_minibuffer = 1;
307
308 /* Now label the root window as also being the minibuffer.
309 Avoid infinite looping on the window chain by marking next pointer
310 as nil. */
311
312 mini_window = f->minibuffer_window = f->root_window;
313 XWINDOW (mini_window)->mini_p = Qt;
314 XWINDOW (mini_window)->next = Qnil;
315 XWINDOW (mini_window)->prev = Qnil;
316 XWINDOW (mini_window)->frame = frame;
317
318 /* Put the proper buffer in that window. */
319
320 Fset_window_buffer (mini_window,
321 (NILP (Vminibuffer_list)
322 ? get_minibuffer (0)
323 : Fcar (Vminibuffer_list)));
324 return f;
325 }
326 \f
327 /* Construct a frame that refers to the terminal (stdin and stdout). */
328
329 static int terminal_frame_count;
330
331 struct frame *
332 make_terminal_frame ()
333 {
334 register struct frame *f;
335 Lisp_Object frame;
336 char name[20];
337
338 #ifdef MULTI_KBOARD
339 if (!initial_kboard)
340 {
341 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
342 init_kboard (initial_kboard);
343 }
344 #endif
345
346 /* The first call must initialize Vframe_list. */
347 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
348 Vframe_list = Qnil;
349
350 f = make_frame (1);
351
352 XSETFRAME (frame, f);
353 Vframe_list = Fcons (frame, Vframe_list);
354
355 terminal_frame_count++;
356 sprintf (name, "terminal-%d", terminal_frame_count);
357
358 f->name = build_string (name);
359 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
360 f->async_visible = 1; /* Don't let visible be cleared later. */
361 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
362 XSETFRAME (Vterminal_frame, f);
363 return f;
364 }
365
366 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
367 1, 1, 0, "Create an additional terminal frame.\n\
368 You can create multiple frames on a text-only terminal in this way.\n\
369 Only the selected terminal frame is actually displayed.\n\
370 This function takes one argument, an alist specifying frame parameters.\n\
371 In practice, generally you don't need to specify any parameters.\n\
372 Note that changing the size of one terminal frame automatically affects all.")
373 (parms)
374 Lisp_Object parms;
375 {
376 struct frame *f;
377 Lisp_Object frame;
378
379 if (selected_frame->output_method != output_termcap)
380 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
381
382 f = make_terminal_frame ();
383 change_frame_size (f, FRAME_HEIGHT (selected_frame),
384 FRAME_WIDTH (selected_frame), 0, 0);
385 remake_frame_glyphs (f);
386 calculate_costs (f);
387 XSETFRAME (frame, f);
388 Fmodify_frame_parameters (frame, parms);
389 return frame;
390 }
391 \f
392 static Lisp_Object
393 do_switch_frame (frame, no_enter, track)
394 Lisp_Object frame, no_enter;
395 int track;
396 {
397 /* If FRAME is a switch-frame event, extract the frame we should
398 switch to. */
399 if (CONSP (frame)
400 && EQ (XCONS (frame)->car, Qswitch_frame)
401 && CONSP (XCONS (frame)->cdr))
402 frame = XCONS (XCONS (frame)->cdr)->car;
403
404 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
405 a switch-frame event to arrive after a frame is no longer live,
406 especially when deleting the initial frame during startup. */
407 CHECK_FRAME (frame, 0);
408 if (! FRAME_LIVE_P (XFRAME (frame)))
409 return Qnil;
410
411 if (selected_frame == XFRAME (frame))
412 return frame;
413
414 /* This is too greedy; it causes inappropriate focus redirection
415 that's hard to get rid of. */
416 #if 0
417 /* If a frame's focus has been redirected toward the currently
418 selected frame, we should change the redirection to point to the
419 newly selected frame. This means that if the focus is redirected
420 from a minibufferless frame to a surrogate minibuffer frame, we
421 can use `other-window' to switch between all the frames using
422 that minibuffer frame, and the focus redirection will follow us
423 around. */
424 if (track)
425 {
426 Lisp_Object tail;
427
428 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
429 {
430 Lisp_Object focus;
431
432 if (!FRAMEP (XCONS (tail)->car))
433 abort ();
434
435 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
436
437 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
438 Fredirect_frame_focus (XCONS (tail)->car, frame);
439 }
440 }
441 #else /* ! 0 */
442 /* Instead, apply it only to the frame we're pointing to. */
443 #ifdef HAVE_X_WINDOWS
444 if (track)
445 {
446 Lisp_Object focus, xfocus;
447
448 xfocus = x_get_focus_frame ();
449 if (FRAMEP (xfocus))
450 {
451 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
452 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
453 Fredirect_frame_focus (xfocus, frame);
454 }
455 }
456 #endif /* HAVE_X_WINDOWS */
457 #endif /* ! 0 */
458
459 if (FRAME_TERMCAP_P (XFRAME (frame)))
460 {
461 /* Since frames on an ASCII terminal share the same display area,
462 switching means we must redisplay the whole thing. */
463 windows_or_buffers_changed++;
464 SET_FRAME_GARBAGED (XFRAME (frame));
465 }
466
467 selected_frame = XFRAME (frame);
468 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
469 last_nonminibuf_frame = selected_frame;
470
471 Fselect_window (XFRAME (frame)->selected_window);
472 choose_minibuf_frame ();
473
474 /* We want to make sure that the next event generates a frame-switch
475 event to the appropriate frame. This seems kludgy to me, but
476 before you take it out, make sure that evaluating something like
477 (select-window (frame-root-window (new-frame))) doesn't end up
478 with your typing being interpreted in the new frame instead of
479 the one you're actually typing in. */
480 internal_last_event_frame = Qnil;
481
482 return frame;
483 }
484
485 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
486 "Select the frame FRAME.\n\
487 Subsequent editing commands apply to its selected window.\n\
488 The selection of FRAME lasts until the next time the user does\n\
489 something to select a different frame, or until the next time this\n\
490 function is called.")
491 (frame, no_enter)
492 Lisp_Object frame, no_enter;
493 {
494 return do_switch_frame (frame, no_enter, 1);
495 }
496
497
498 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
499 "Handle a switch-frame event EVENT.\n\
500 Switch-frame events are usually bound to this function.\n\
501 A switch-frame event tells Emacs that the window manager has requested\n\
502 that the user's events be directed to the frame mentioned in the event.\n\
503 This function selects the selected window of the frame of EVENT.\n\
504 \n\
505 If EVENT is frame object, handle it as if it were a switch-frame event\n\
506 to that frame.")
507 (frame, no_enter)
508 Lisp_Object frame, no_enter;
509 {
510 return do_switch_frame (frame, no_enter, 0);
511 }
512
513
514 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
515 "Return the frame that is now selected.")
516 ()
517 {
518 Lisp_Object tem;
519 XSETFRAME (tem, selected_frame);
520 return tem;
521 }
522 \f
523 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
524 "Return the frame object that window WINDOW is on.")
525 (window)
526 Lisp_Object window;
527 {
528 CHECK_LIVE_WINDOW (window, 0);
529 return XWINDOW (window)->frame;
530 }
531
532 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
533 "Returns the topmost, leftmost window of FRAME.\n\
534 If omitted, FRAME defaults to the currently selected frame.")
535 (frame)
536 Lisp_Object frame;
537 {
538 Lisp_Object w;
539
540 if (NILP (frame))
541 w = selected_frame->root_window;
542 else
543 {
544 CHECK_LIVE_FRAME (frame, 0);
545 w = XFRAME (frame)->root_window;
546 }
547 while (NILP (XWINDOW (w)->buffer))
548 {
549 if (! NILP (XWINDOW (w)->hchild))
550 w = XWINDOW (w)->hchild;
551 else if (! NILP (XWINDOW (w)->vchild))
552 w = XWINDOW (w)->vchild;
553 else
554 abort ();
555 }
556 return w;
557 }
558
559 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
560 Sactive_minibuffer_window, 0, 0, 0,
561 "Return the currently active minibuffer window, or nil if none.")
562 ()
563 {
564 return minibuf_level ? minibuf_window : Qnil;
565 }
566
567 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
568 "Returns the root-window of FRAME.\n\
569 If omitted, FRAME defaults to the currently selected frame.")
570 (frame)
571 Lisp_Object frame;
572 {
573 if (NILP (frame))
574 XSETFRAME (frame, selected_frame);
575 else
576 CHECK_LIVE_FRAME (frame, 0);
577
578 return XFRAME (frame)->root_window;
579 }
580
581 DEFUN ("frame-selected-window", Fframe_selected_window,
582 Sframe_selected_window, 0, 1, 0,
583 "Return the selected window of frame object FRAME.\n\
584 If omitted, FRAME defaults to the currently selected frame.")
585 (frame)
586 Lisp_Object frame;
587 {
588 if (NILP (frame))
589 XSETFRAME (frame, selected_frame);
590 else
591 CHECK_LIVE_FRAME (frame, 0);
592
593 return XFRAME (frame)->selected_window;
594 }
595
596 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
597 Sset_frame_selected_window, 2, 2, 0,
598 "Set the selected window of frame object FRAME to WINDOW.\n\
599 If FRAME is nil, the selected frame is used.\n\
600 If FRAME is the selected frame, this makes WINDOW the selected window.")
601 (frame, window)
602 Lisp_Object frame, window;
603 {
604 if (NILP (frame))
605 XSETFRAME (frame, selected_frame);
606 else
607 CHECK_LIVE_FRAME (frame, 0);
608
609 CHECK_LIVE_WINDOW (window, 1);
610
611 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
612 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
613
614 if (XFRAME (frame) == selected_frame)
615 return Fselect_window (window);
616
617 return XFRAME (frame)->selected_window = window;
618 }
619 \f
620 DEFUN ("frame-list", Fframe_list, Sframe_list,
621 0, 0, 0,
622 "Return a list of all frames.")
623 ()
624 {
625 return Fcopy_sequence (Vframe_list);
626 }
627
628 /* Return the next frame in the frame list after FRAME.
629 If MINIBUF is nil, exclude minibuffer-only frames.
630 If MINIBUF is a window, include only its own frame
631 and any frame now using that window as the minibuffer.
632 If MINIBUF is `visible', include all visible frames.
633 If MINIBUF is 0, include all visible and iconified frames.
634 Otherwise, include all frames. */
635
636 Lisp_Object
637 next_frame (frame, minibuf)
638 Lisp_Object frame;
639 Lisp_Object minibuf;
640 {
641 Lisp_Object tail;
642 int passed = 0;
643
644 /* There must always be at least one frame in Vframe_list. */
645 if (! CONSP (Vframe_list))
646 abort ();
647
648 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
649 forever. Forestall that. */
650 CHECK_LIVE_FRAME (frame, 0);
651
652 while (1)
653 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
654 {
655 Lisp_Object f;
656
657 f = XCONS (tail)->car;
658 if (passed)
659 {
660 /* Decide whether this frame is eligible to be returned. */
661
662 /* If we've looped all the way around without finding any
663 eligible frames, return the original frame. */
664 if (EQ (f, frame))
665 return f;
666
667 /* Let minibuf decide if this frame is acceptable. */
668 if (NILP (minibuf))
669 {
670 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
671 return f;
672 }
673 else if (EQ (minibuf, Qvisible))
674 {
675 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
676 if (FRAME_VISIBLE_P (XFRAME (f)))
677 return f;
678 }
679 else if (XFASTINT (minibuf) == 0)
680 {
681 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
682 if (FRAME_VISIBLE_P (XFRAME (f))
683 || FRAME_ICONIFIED_P (XFRAME (f)))
684 return f;
685 }
686 else if (WINDOWP (minibuf))
687 {
688 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
689 /* Check that F either is, or has forwarded its focus to,
690 MINIBUF's frame. */
691 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
692 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
693 FRAME_FOCUS_FRAME (XFRAME (f)))))
694 return f;
695 }
696 else
697 return f;
698 }
699
700 if (EQ (frame, f))
701 passed++;
702 }
703 }
704
705 /* Return the previous frame in the frame list before FRAME.
706 If MINIBUF is nil, exclude minibuffer-only frames.
707 If MINIBUF is a window, include only its own frame
708 and any frame now using that window as the minibuffer.
709 If MINIBUF is `visible', include all visible frames.
710 If MINIBUF is 0, include all visible and iconified frames.
711 Otherwise, include all frames. */
712
713 Lisp_Object
714 prev_frame (frame, minibuf)
715 Lisp_Object frame;
716 Lisp_Object minibuf;
717 {
718 Lisp_Object tail;
719 Lisp_Object prev;
720
721 /* There must always be at least one frame in Vframe_list. */
722 if (! CONSP (Vframe_list))
723 abort ();
724
725 prev = Qnil;
726 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
727 {
728 Lisp_Object f;
729
730 f = XCONS (tail)->car;
731 if (!FRAMEP (f))
732 abort ();
733
734 if (EQ (frame, f) && !NILP (prev))
735 return prev;
736
737 /* Decide whether this frame is eligible to be returned,
738 according to minibuf. */
739 if (NILP (minibuf))
740 {
741 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
742 prev = f;
743 }
744 else if (WINDOWP (minibuf))
745 {
746 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
747 /* Check that F either is, or has forwarded its focus to,
748 MINIBUF's frame. */
749 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
750 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
751 FRAME_FOCUS_FRAME (XFRAME (f)))))
752 prev = f;
753 }
754 else if (EQ (minibuf, Qvisible))
755 {
756 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
757 if (FRAME_VISIBLE_P (XFRAME (f)))
758 prev = f;
759 }
760 else if (XFASTINT (minibuf) == 0)
761 {
762 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
763 if (FRAME_VISIBLE_P (XFRAME (f))
764 || FRAME_ICONIFIED_P (XFRAME (f)))
765 prev = f;
766 }
767 else
768 prev = f;
769 }
770
771 /* We've scanned the entire list. */
772 if (NILP (prev))
773 /* We went through the whole frame list without finding a single
774 acceptable frame. Return the original frame. */
775 return frame;
776 else
777 /* There were no acceptable frames in the list before FRAME; otherwise,
778 we would have returned directly from the loop. Since PREV is the last
779 acceptable frame in the list, return it. */
780 return prev;
781 }
782
783
784 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
785 "Return the next frame in the frame list after FRAME.\n\
786 By default, skip minibuffer-only frames.\n\
787 If omitted, FRAME defaults to the selected frame.\n\
788 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
789 If MINIBUF is a window, include only its own frame\n\
790 and any frame now using that window as the minibuffer.\n\
791 If MINIFRAME is `visible', include all visible frames.\n\
792 If MINIBUF is 0, include all visible and iconified frames.\n\
793 Otherwise, include all frames.")
794 (frame, miniframe)
795 Lisp_Object frame, miniframe;
796 {
797 Lisp_Object tail;
798
799 if (NILP (frame))
800 XSETFRAME (frame, selected_frame);
801 else
802 CHECK_LIVE_FRAME (frame, 0);
803
804 return next_frame (frame, miniframe);
805 }
806
807 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
808 "Return the previous frame in the frame list before FRAME.\n\
809 By default, skip minibuffer-only frames.\n\
810 If omitted, FRAME defaults to the selected frame.\n\
811 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
812 If MINIBUF is a window, include only its own frame\n\
813 and any frame now using that window as the minibuffer.\n\
814 If MINIFRAME is `visible', include all visible frames.\n\
815 If MINIBUF is 0, include all visible and iconified frames.\n\
816 Otherwise, include all frames.")
817 (frame, miniframe)
818 Lisp_Object frame, miniframe;
819 {
820 Lisp_Object tail;
821
822 if (NILP (frame))
823 XSETFRAME (frame, selected_frame);
824 else
825 CHECK_LIVE_FRAME (frame, 0);
826
827 return prev_frame (frame, miniframe);
828 }
829 \f
830 /* Return 1 if it is ok to delete frame F;
831 0 if all frames aside from F are invisible.
832 (Exception: if F is the terminal frame, and we are using X, return 1.) */
833
834 int
835 other_visible_frames (f)
836 FRAME_PTR f;
837 {
838 /* We know the selected frame is visible,
839 so if F is some other frame, it can't be the sole visible one. */
840 if (f == selected_frame)
841 {
842 Lisp_Object frames;
843 int count = 0;
844
845 for (frames = Vframe_list;
846 CONSP (frames);
847 frames = XCONS (frames)->cdr)
848 {
849 Lisp_Object this;
850
851 this = XCONS (frames)->car;
852 /* Verify that the frame's window still exists
853 and we can still talk to it. And note any recent change
854 in visibility. */
855 #ifdef HAVE_X_WINDOWS
856 if (FRAME_X_P (XFRAME (this)))
857 {
858 x_sync (XFRAME (this));
859 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
860 }
861 #endif
862
863 if (FRAME_VISIBLE_P (XFRAME (this))
864 || FRAME_ICONIFIED_P (XFRAME (this))
865 /* Allow deleting the terminal frame when at least
866 one X frame exists! */
867 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
868 count++;
869 }
870 return count > 1;
871 }
872 return 1;
873 }
874
875 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
876 "Delete FRAME, permanently eliminating it from use.\n\
877 If omitted, FRAME defaults to the selected frame.\n\
878 A frame may not be deleted if its minibuffer is used by other frames.\n\
879 Normally, you may not delete a frame if all other frames are invisible,\n\
880 but if the second optional argument FORCE is non-nil, you may do so.")
881 (frame, force)
882 Lisp_Object frame, force;
883 {
884 struct frame *f;
885
886 if (EQ (frame, Qnil))
887 {
888 f = selected_frame;
889 XSETFRAME (frame, f);
890 }
891 else
892 {
893 CHECK_FRAME (frame, 0);
894 f = XFRAME (frame);
895 }
896
897 if (! FRAME_LIVE_P (f))
898 return Qnil;
899
900 if (NILP (force) && !other_visible_frames (f))
901 error ("Attempt to delete the sole visible or iconified frame");
902
903 /* Does this frame have a minibuffer, and is it the surrogate
904 minibuffer for any other frame? */
905 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
906 {
907 Lisp_Object frames;
908
909 for (frames = Vframe_list;
910 CONSP (frames);
911 frames = XCONS (frames)->cdr)
912 {
913 Lisp_Object this;
914 this = XCONS (frames)->car;
915
916 if (! EQ (this, frame)
917 && EQ (frame,
918 WINDOW_FRAME (XWINDOW
919 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
920 error ("Attempt to delete a surrogate minibuffer frame");
921 }
922 }
923
924 /* Don't let the frame remain selected. */
925 if (f == selected_frame)
926 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
927
928 /* Don't allow minibuf_window to remain on a deleted frame. */
929 if (EQ (f->minibuffer_window, minibuf_window))
930 {
931 Fset_window_buffer (selected_frame->minibuffer_window,
932 XWINDOW (minibuf_window)->buffer);
933 minibuf_window = selected_frame->minibuffer_window;
934 }
935
936 /* Clear any X selections for this frame. */
937 #ifdef HAVE_X_WINDOWS
938 if (FRAME_X_P (f))
939 x_clear_frame_selections (f);
940 #endif
941
942 /* Mark all the windows that used to be on FRAME as deleted, and then
943 remove the reference to them. */
944 delete_all_subwindows (XWINDOW (f->root_window));
945 f->root_window = Qnil;
946
947 Vframe_list = Fdelq (frame, Vframe_list);
948 FRAME_SET_VISIBLE (f, 0);
949
950 if (FRAME_CURRENT_GLYPHS (f))
951 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
952 if (FRAME_DESIRED_GLYPHS (f))
953 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
954 if (FRAME_TEMP_GLYPHS (f))
955 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
956 if (FRAME_INSERT_COST (f))
957 free (FRAME_INSERT_COST (f));
958 if (FRAME_DELETEN_COST (f))
959 free (FRAME_DELETEN_COST (f));
960 if (FRAME_INSERTN_COST (f))
961 free (FRAME_INSERTN_COST (f));
962 if (FRAME_DELETE_COST (f))
963 free (FRAME_DELETE_COST (f));
964
965 /* Since some events are handled at the interrupt level, we may get
966 an event for f at any time; if we zero out the frame's display
967 now, then we may trip up the event-handling code. Instead, we'll
968 promise that the display of the frame must be valid until we have
969 called the window-system-dependent frame destruction routine. */
970
971 /* I think this should be done with a hook. */
972 #ifdef HAVE_X_WINDOWS
973 if (FRAME_X_P (f))
974 x_destroy_window (f);
975 #endif
976
977 f->display.nothing = 0;
978
979 /* If we've deleted the last_nonminibuf_frame, then try to find
980 another one. */
981 if (f == last_nonminibuf_frame)
982 {
983 Lisp_Object frames;
984
985 last_nonminibuf_frame = 0;
986
987 for (frames = Vframe_list;
988 CONSP (frames);
989 frames = XCONS (frames)->cdr)
990 {
991 f = XFRAME (XCONS (frames)->car);
992 if (!FRAME_MINIBUF_ONLY_P (f))
993 {
994 last_nonminibuf_frame = f;
995 break;
996 }
997 }
998 }
999
1000 /* If we've deleted Vdefault_minibuffer_frame, try to find another
1001 one. Prefer minibuffer-only frames, but also notice frames
1002 with other windows. */
1003 if (EQ (frame, Vdefault_minibuffer_frame))
1004 {
1005 Lisp_Object frames;
1006
1007 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1008 Lisp_Object frame_with_minibuf;
1009
1010 frame_with_minibuf = Qnil;
1011 for (frames = Vframe_list;
1012 CONSP (frames);
1013 frames = XCONS (frames)->cdr)
1014 {
1015 Lisp_Object this;
1016
1017 this = XCONS (frames)->car;
1018 if (!FRAMEP (this))
1019 abort ();
1020 f = XFRAME (this);
1021
1022 if (FRAME_HAS_MINIBUF_P (f))
1023 {
1024 frame_with_minibuf = this;
1025 if (FRAME_MINIBUF_ONLY_P (f))
1026 break;
1027 }
1028 }
1029
1030 /* We know that there must be some frame with a minibuffer out
1031 there. If this were not true, all of the frames present
1032 would have to be minibufferless, which implies that at some
1033 point their minibuffer frames must have been deleted, but
1034 that is prohibited at the top; you can't delete surrogate
1035 minibuffer frames. */
1036 if (NILP (frame_with_minibuf))
1037 abort ();
1038
1039 Vdefault_minibuffer_frame = frame_with_minibuf;
1040 }
1041
1042 return Qnil;
1043 }
1044 \f
1045 /* Return mouse position in character cell units. */
1046
1047 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1048 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1049 The position is given in character cells, where (0, 0) is the\n\
1050 upper-left corner.\n\
1051 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1052 to read the mouse position, it returns the selected frame for FRAME\n\
1053 and nil for X and Y.")
1054 ()
1055 {
1056 FRAME_PTR f;
1057 Lisp_Object lispy_dummy;
1058 enum scroll_bar_part party_dummy;
1059 Lisp_Object x, y;
1060 int col, row;
1061 unsigned long long_dummy;
1062
1063 f = selected_frame;
1064 x = y = Qnil;
1065
1066 #ifdef HAVE_MOUSE
1067 /* It's okay for the hook to refrain from storing anything. */
1068 if (mouse_position_hook)
1069 (*mouse_position_hook) (&f, 0,
1070 &lispy_dummy, &party_dummy,
1071 &x, &y,
1072 &long_dummy);
1073 if (! NILP (x))
1074 {
1075 col = XINT (x);
1076 row = XINT (y);
1077 pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
1078 XSETINT (x, col);
1079 XSETINT (y, row);
1080 }
1081 #endif
1082 XSETFRAME (lispy_dummy, f);
1083 return Fcons (lispy_dummy, Fcons (x, y));
1084 }
1085
1086 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1087 Smouse_pixel_position, 0, 0, 0,
1088 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1089 The position is given in pixel units, where (0, 0) is the\n\
1090 upper-left corner.\n\
1091 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1092 to read the mouse position, it returns the selected frame for FRAME\n\
1093 and nil for X and Y.")
1094 ()
1095 {
1096 FRAME_PTR f;
1097 Lisp_Object lispy_dummy;
1098 enum scroll_bar_part party_dummy;
1099 Lisp_Object x, y;
1100 int col, row;
1101 unsigned long long_dummy;
1102
1103 f = selected_frame;
1104 x = y = Qnil;
1105
1106 #ifdef HAVE_MOUSE
1107 /* It's okay for the hook to refrain from storing anything. */
1108 if (mouse_position_hook)
1109 (*mouse_position_hook) (&f, 0,
1110 &lispy_dummy, &party_dummy,
1111 &x, &y,
1112 &long_dummy);
1113 #endif
1114 XSETFRAME (lispy_dummy, f);
1115 return Fcons (lispy_dummy, Fcons (x, y));
1116 }
1117
1118 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1119 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1120 WARNING: If you use this under X windows,\n\
1121 you should call `unfocus-frame' afterwards.")
1122 (frame, x, y)
1123 Lisp_Object frame, x, y;
1124 {
1125 CHECK_LIVE_FRAME (frame, 0);
1126 CHECK_NUMBER (x, 2);
1127 CHECK_NUMBER (y, 1);
1128
1129 /* I think this should be done with a hook. */
1130 #ifdef HAVE_X_WINDOWS
1131 if (FRAME_X_P (XFRAME (frame)))
1132 /* Warping the mouse will cause enternotify and focus events. */
1133 x_set_mouse_position (XFRAME (frame), x, y);
1134 #endif
1135
1136 return Qnil;
1137 }
1138
1139 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1140 Sset_mouse_pixel_position, 3, 3, 0,
1141 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1142 WARNING: If you use this under X windows,\n\
1143 you should call `unfocus-frame' afterwards.")
1144 (frame, x, y)
1145 Lisp_Object frame, x, y;
1146 {
1147 CHECK_LIVE_FRAME (frame, 0);
1148 CHECK_NUMBER (x, 2);
1149 CHECK_NUMBER (y, 1);
1150
1151 /* I think this should be done with a hook. */
1152 #ifdef HAVE_X_WINDOWS
1153 if (FRAME_X_P (XFRAME (frame)))
1154 /* Warping the mouse will cause enternotify and focus events. */
1155 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1156 #endif
1157
1158 return Qnil;
1159 }
1160 \f
1161 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1162 0, 1, "",
1163 "Make the frame FRAME visible (assuming it is an X-window).\n\
1164 If omitted, FRAME defaults to the currently selected frame.")
1165 (frame)
1166 Lisp_Object frame;
1167 {
1168 if (NILP (frame))
1169 XSETFRAME (frame, selected_frame);
1170
1171 CHECK_LIVE_FRAME (frame, 0);
1172
1173 /* I think this should be done with a hook. */
1174 #ifdef HAVE_X_WINDOWS
1175 if (FRAME_X_P (XFRAME (frame)))
1176 {
1177 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1178 x_make_frame_visible (XFRAME (frame));
1179 }
1180 #endif
1181
1182 /* Make menu bar update for the Buffers and Frams menus. */
1183 windows_or_buffers_changed++;
1184
1185 return frame;
1186 }
1187
1188 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1189 0, 2, "",
1190 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1191 If omitted, FRAME defaults to the currently selected frame.\n\
1192 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1193 but if the second optional argument FORCE is non-nil, you may do so.")
1194 (frame, force)
1195 Lisp_Object frame, force;
1196 {
1197 if (NILP (frame))
1198 XSETFRAME (frame, selected_frame);
1199
1200 CHECK_LIVE_FRAME (frame, 0);
1201
1202 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1203 error ("Attempt to make invisible the sole visible or iconified frame");
1204
1205 #if 0 /* This isn't logically necessary, and it can do GC. */
1206 /* Don't let the frame remain selected. */
1207 if (XFRAME (frame) == selected_frame)
1208 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1209 #endif
1210
1211 /* Don't allow minibuf_window to remain on a deleted frame. */
1212 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1213 {
1214 Fset_window_buffer (selected_frame->minibuffer_window,
1215 XWINDOW (minibuf_window)->buffer);
1216 minibuf_window = selected_frame->minibuffer_window;
1217 }
1218
1219 /* I think this should be done with a hook. */
1220 #ifdef HAVE_X_WINDOWS
1221 if (FRAME_X_P (XFRAME (frame)))
1222 x_make_frame_invisible (XFRAME (frame));
1223 #endif
1224
1225 /* Make menu bar update for the Buffers and Frams menus. */
1226 windows_or_buffers_changed++;
1227
1228 return Qnil;
1229 }
1230
1231 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1232 0, 1, "",
1233 "Make the frame FRAME into an icon.\n\
1234 If omitted, FRAME defaults to the currently selected frame.")
1235 (frame)
1236 Lisp_Object frame;
1237 {
1238 if (NILP (frame))
1239 XSETFRAME (frame, selected_frame);
1240
1241 CHECK_LIVE_FRAME (frame, 0);
1242
1243 #if 0 /* This isn't logically necessary, and it can do GC. */
1244 /* Don't let the frame remain selected. */
1245 if (XFRAME (frame) == selected_frame)
1246 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1247 #endif
1248
1249 /* Don't allow minibuf_window to remain on a deleted frame. */
1250 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1251 {
1252 Fset_window_buffer (selected_frame->minibuffer_window,
1253 XWINDOW (minibuf_window)->buffer);
1254 minibuf_window = selected_frame->minibuffer_window;
1255 }
1256
1257 /* I think this should be done with a hook. */
1258 #ifdef HAVE_X_WINDOWS
1259 if (FRAME_X_P (XFRAME (frame)))
1260 x_iconify_frame (XFRAME (frame));
1261 #endif
1262
1263 /* Make menu bar update for the Buffers and Frams menus. */
1264 windows_or_buffers_changed++;
1265
1266 return Qnil;
1267 }
1268
1269 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1270 1, 1, 0,
1271 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1272 A frame that is not \"visible\" is not updated and, if it works through\n\
1273 a window system, it may not show at all.\n\
1274 Return the symbol `icon' if frame is visible only as an icon.")
1275 (frame)
1276 Lisp_Object frame;
1277 {
1278 CHECK_LIVE_FRAME (frame, 0);
1279
1280 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1281
1282 if (FRAME_VISIBLE_P (XFRAME (frame)))
1283 return Qt;
1284 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1285 return Qicon;
1286 return Qnil;
1287 }
1288
1289 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1290 0, 0, 0,
1291 "Return a list of all frames now \"visible\" (being updated).")
1292 ()
1293 {
1294 Lisp_Object tail, frame;
1295 struct frame *f;
1296 Lisp_Object value;
1297
1298 value = Qnil;
1299 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1300 {
1301 frame = XCONS (tail)->car;
1302 if (!FRAMEP (frame))
1303 continue;
1304 f = XFRAME (frame);
1305 if (FRAME_VISIBLE_P (f))
1306 value = Fcons (frame, value);
1307 }
1308 return value;
1309 }
1310
1311
1312 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
1313 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1314 If FRAME is invisible, make it visible.\n\
1315 If Emacs is displaying on an ordinary terminal or some other device which\n\
1316 doesn't support multiple overlapping frames, this function does nothing.")
1317 (frame)
1318 Lisp_Object frame;
1319 {
1320 CHECK_LIVE_FRAME (frame, 0);
1321
1322 /* Do like the documentation says. */
1323 Fmake_frame_visible (frame);
1324
1325 if (frame_raise_lower_hook)
1326 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1327
1328 return Qnil;
1329 }
1330
1331 /* Should we have a corresponding function called Flower_Power? */
1332 DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
1333 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1334 If Emacs is displaying on an ordinary terminal or some other device which\n\
1335 doesn't support multiple overlapping frames, this function does nothing.")
1336 (frame)
1337 Lisp_Object frame;
1338 {
1339 CHECK_LIVE_FRAME (frame, 0);
1340
1341 if (frame_raise_lower_hook)
1342 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1343
1344 return Qnil;
1345 }
1346
1347 \f
1348 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1349 1, 2, 0,
1350 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1351 In other words, switch-frame events caused by events in FRAME will\n\
1352 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1353 FOCUS-FRAME after reading an event typed at FRAME.\n\
1354 \n\
1355 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1356 cancelled, and the frame again receives its own keystrokes.\n\
1357 \n\
1358 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1359 a surrogate minibuffer frame when a frame doesn't have its own\n\
1360 minibuffer window.\n\
1361 \n\
1362 A frame's focus redirection can be changed by select-frame. If frame\n\
1363 FOO is selected, and then a different frame BAR is selected, any\n\
1364 frames redirecting their focus to FOO are shifted to redirect their\n\
1365 focus to BAR. This allows focus redirection to work properly when the\n\
1366 user switches from one frame to another using `select-window'.\n\
1367 \n\
1368 This means that a frame whose focus is redirected to itself is treated\n\
1369 differently from a frame whose focus is redirected to nil; the former\n\
1370 is affected by select-frame, while the latter is not.\n\
1371 \n\
1372 The redirection lasts until `redirect-frame-focus' is called to change it.")
1373 (frame, focus_frame)
1374 Lisp_Object frame, focus_frame;
1375 {
1376 /* Note that we don't check for a live frame here. It's reasonable
1377 to redirect the focus of a frame you're about to delete, if you
1378 know what other frame should receive those keystrokes. */
1379 CHECK_FRAME (frame, 0);
1380
1381 if (! NILP (focus_frame))
1382 CHECK_LIVE_FRAME (focus_frame, 1);
1383
1384 XFRAME (frame)->focus_frame = focus_frame;
1385
1386 /* I think this should be done with a hook. */
1387 #ifdef HAVE_X_WINDOWS
1388 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1389 && FRAME_X_P (XFRAME (focus_frame)))
1390 Ffocus_frame (focus_frame);
1391 #endif
1392
1393 if (frame_rehighlight_hook)
1394 (*frame_rehighlight_hook) ();
1395
1396 return Qnil;
1397 }
1398
1399
1400 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1401 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1402 This returns nil if FRAME's focus is not redirected.\n\
1403 See `redirect-frame-focus'.")
1404 (frame)
1405 Lisp_Object frame;
1406 {
1407 CHECK_LIVE_FRAME (frame, 0);
1408
1409 return FRAME_FOCUS_FRAME (XFRAME (frame));
1410 }
1411
1412
1413 \f
1414 /* Return the value of frame parameter PROP in frame FRAME. */
1415
1416 Lisp_Object
1417 get_frame_param (frame, prop)
1418 register struct frame *frame;
1419 Lisp_Object prop;
1420 {
1421 register Lisp_Object tem;
1422
1423 tem = Fassq (prop, frame->param_alist);
1424 if (EQ (tem, Qnil))
1425 return tem;
1426 return Fcdr (tem);
1427 }
1428
1429 /* Return the buffer-predicate of the selected frame. */
1430
1431 Lisp_Object
1432 frame_buffer_predicate ()
1433 {
1434 return selected_frame->buffer_predicate;
1435 }
1436
1437 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1438 If the alist already has an element for PROP, we change it. */
1439
1440 void
1441 store_in_alist (alistptr, prop, val)
1442 Lisp_Object *alistptr, val;
1443 Lisp_Object prop;
1444 {
1445 register Lisp_Object tem;
1446
1447 tem = Fassq (prop, *alistptr);
1448 if (EQ (tem, Qnil))
1449 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1450 else
1451 Fsetcdr (tem, val);
1452 }
1453
1454 void
1455 store_frame_param (f, prop, val)
1456 struct frame *f;
1457 Lisp_Object prop, val;
1458 {
1459 register Lisp_Object tem;
1460
1461 tem = Fassq (prop, f->param_alist);
1462 if (EQ (tem, Qnil))
1463 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1464 else
1465 Fsetcdr (tem, val);
1466
1467 if (EQ (prop, Qbuffer_predicate))
1468 f->buffer_predicate = val;
1469
1470 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1471 {
1472 if (! MINI_WINDOW_P (XWINDOW (val)))
1473 error ("Surrogate minibuffer windows must be minibuffer windows.");
1474
1475 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1476 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1477
1478 /* Install the chosen minibuffer window, with proper buffer. */
1479 f->minibuffer_window = val;
1480 }
1481 }
1482
1483 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1484 "Return the parameters-alist of frame FRAME.\n\
1485 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1486 The meaningful PARMs depend on the kind of frame.\n\
1487 If FRAME is omitted, return information on the currently selected frame.")
1488 (frame)
1489 Lisp_Object frame;
1490 {
1491 Lisp_Object alist;
1492 FRAME_PTR f;
1493
1494 if (EQ (frame, Qnil))
1495 f = selected_frame;
1496 else
1497 {
1498 CHECK_FRAME (frame, 0);
1499 f = XFRAME (frame);
1500 }
1501
1502 if (!FRAME_LIVE_P (f))
1503 return Qnil;
1504
1505 alist = Fcopy_alist (f->param_alist);
1506 store_in_alist (&alist, Qname, f->name);
1507 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
1508 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
1509 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
1510 store_in_alist (&alist, Qminibuffer,
1511 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1512 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1513 : FRAME_MINIBUF_WINDOW (f)));
1514 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
1515
1516 /* I think this should be done with a hook. */
1517 #ifdef HAVE_X_WINDOWS
1518 if (FRAME_X_P (f))
1519 x_report_frame_params (f, &alist);
1520 else
1521 #endif
1522 {
1523 /* This ought to be correct in f->param_alist for an X frame. */
1524 Lisp_Object lines;
1525 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
1526 store_in_alist (&alist, Qmenu_bar_lines, lines);
1527 }
1528 return alist;
1529 }
1530
1531 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1532 Smodify_frame_parameters, 2, 2, 0,
1533 "Modify the parameters of frame FRAME according to ALIST.\n\
1534 ALIST is an alist of parameters to change and their new values.\n\
1535 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1536 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1537 (frame, alist)
1538 Lisp_Object frame, alist;
1539 {
1540 FRAME_PTR f;
1541 register Lisp_Object tail, elt, prop, val;
1542
1543 if (EQ (frame, Qnil))
1544 f = selected_frame;
1545 else
1546 {
1547 CHECK_LIVE_FRAME (frame, 0);
1548 f = XFRAME (frame);
1549 }
1550
1551 /* I think this should be done with a hook. */
1552 #ifdef HAVE_X_WINDOWS
1553 if (FRAME_X_P (f))
1554 x_set_frame_parameters (f, alist);
1555 else
1556 #endif
1557 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1558 {
1559 elt = Fcar (tail);
1560 prop = Fcar (elt);
1561 val = Fcdr (elt);
1562 store_frame_param (f, prop, val);
1563 }
1564
1565 return Qnil;
1566 }
1567 \f
1568 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1569 0, 1, 0,
1570 "Height in pixels of a line in the font in frame FRAME.\n\
1571 If FRAME is omitted, the selected frame is used.\n\
1572 For a terminal frame, the value is always 1.")
1573 (frame)
1574 Lisp_Object frame;
1575 {
1576 struct frame *f;
1577
1578 if (NILP (frame))
1579 f = selected_frame;
1580 else
1581 {
1582 CHECK_FRAME (frame, 0);
1583 f = XFRAME (frame);
1584 }
1585
1586 #ifdef HAVE_X_WINDOWS
1587 if (FRAME_X_P (f))
1588 return make_number (x_char_height (f));
1589 else
1590 #endif
1591 return make_number (1);
1592 }
1593
1594
1595 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1596 0, 1, 0,
1597 "Width in pixels of characters in the font in frame FRAME.\n\
1598 If FRAME is omitted, the selected frame is used.\n\
1599 The width is the same for all characters, because\n\
1600 currently Emacs supports only fixed-width fonts.\n\
1601 For a terminal screen, the value is always 1.")
1602 (frame)
1603 Lisp_Object frame;
1604 {
1605 struct frame *f;
1606
1607 if (NILP (frame))
1608 f = selected_frame;
1609 else
1610 {
1611 CHECK_FRAME (frame, 0);
1612 f = XFRAME (frame);
1613 }
1614
1615 #ifdef HAVE_X_WINDOWS
1616 if (FRAME_X_P (f))
1617 return make_number (x_char_width (f));
1618 else
1619 #endif
1620 return make_number (1);
1621 }
1622
1623 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1624 Sframe_pixel_height, 0, 1, 0,
1625 "Return a FRAME's height in pixels.\n\
1626 For a terminal frame, the result really gives the height in characters.\n\
1627 If FRAME is omitted, the selected frame is used.")
1628 (frame)
1629 Lisp_Object frame;
1630 {
1631 struct frame *f;
1632
1633 if (NILP (frame))
1634 f = selected_frame;
1635 else
1636 {
1637 CHECK_FRAME (frame, 0);
1638 f = XFRAME (frame);
1639 }
1640
1641 #ifdef HAVE_X_WINDOWS
1642 if (FRAME_X_P (f))
1643 return make_number (x_pixel_height (f));
1644 else
1645 #endif
1646 return make_number (FRAME_HEIGHT (f));
1647 }
1648
1649 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1650 Sframe_pixel_width, 0, 1, 0,
1651 "Return FRAME's width in pixels.\n\
1652 For a terminal frame, the result really gives the width in characters.\n\
1653 If FRAME is omitted, the selected frame is used.")
1654 (frame)
1655 Lisp_Object frame;
1656 {
1657 struct frame *f;
1658
1659 if (NILP (frame))
1660 f = selected_frame;
1661 else
1662 {
1663 CHECK_FRAME (frame, 0);
1664 f = XFRAME (frame);
1665 }
1666
1667 #ifdef HAVE_X_WINDOWS
1668 if (FRAME_X_P (f))
1669 return make_number (x_pixel_width (f));
1670 else
1671 #endif
1672 return make_number (FRAME_WIDTH (f));
1673 }
1674 \f
1675 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1676 "Specify that the frame FRAME has LINES lines.\n\
1677 Optional third arg non-nil means that redisplay should use LINES lines\n\
1678 but that the idea of the actual height of the frame should not be changed.")
1679 (frame, rows, pretend)
1680 Lisp_Object frame, rows, pretend;
1681 {
1682 register struct frame *f;
1683
1684 CHECK_NUMBER (rows, 0);
1685 if (NILP (frame))
1686 f = selected_frame;
1687 else
1688 {
1689 CHECK_LIVE_FRAME (frame, 0);
1690 f = XFRAME (frame);
1691 }
1692
1693 /* I think this should be done with a hook. */
1694 #ifdef HAVE_X_WINDOWS
1695 if (FRAME_X_P (f))
1696 {
1697 if (XINT (rows) != f->height)
1698 x_set_window_size (f, 1, f->width, XINT (rows));
1699 }
1700 else
1701 #endif
1702 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1703 return Qnil;
1704 }
1705
1706 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1707 "Specify that the frame FRAME has COLS columns.\n\
1708 Optional third arg non-nil means that redisplay should use COLS columns\n\
1709 but that the idea of the actual width of the frame should not be changed.")
1710 (frame, cols, pretend)
1711 Lisp_Object frame, cols, pretend;
1712 {
1713 register struct frame *f;
1714 CHECK_NUMBER (cols, 0);
1715 if (NILP (frame))
1716 f = selected_frame;
1717 else
1718 {
1719 CHECK_LIVE_FRAME (frame, 0);
1720 f = XFRAME (frame);
1721 }
1722
1723 /* I think this should be done with a hook. */
1724 #ifdef HAVE_X_WINDOWS
1725 if (FRAME_X_P (f))
1726 {
1727 if (XINT (cols) != f->width)
1728 x_set_window_size (f, 1, XINT (cols), f->height);
1729 }
1730 else
1731 #endif
1732 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1733 return Qnil;
1734 }
1735
1736 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1737 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1738 (frame, cols, rows)
1739 Lisp_Object frame, cols, rows;
1740 {
1741 register struct frame *f;
1742 int mask;
1743
1744 CHECK_LIVE_FRAME (frame, 0);
1745 CHECK_NUMBER (cols, 2);
1746 CHECK_NUMBER (rows, 1);
1747 f = XFRAME (frame);
1748
1749 /* I think this should be done with a hook. */
1750 #ifdef HAVE_X_WINDOWS
1751 if (FRAME_X_P (f))
1752 {
1753 if (XINT (rows) != f->height || XINT (cols) != f->width)
1754 x_set_window_size (f, 1, XINT (cols), XINT (rows));
1755 }
1756 else
1757 #endif
1758 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1759
1760 return Qnil;
1761 }
1762
1763 DEFUN ("set-frame-position", Fset_frame_position,
1764 Sset_frame_position, 3, 3, 0,
1765 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1766 This is actually the position of the upper left corner of the frame.\n\
1767 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1768 the rightmost or bottommost possible position (that stays within the screen).")
1769 (frame, xoffset, yoffset)
1770 Lisp_Object frame, xoffset, yoffset;
1771 {
1772 register struct frame *f;
1773 int mask;
1774
1775 CHECK_LIVE_FRAME (frame, 0);
1776 CHECK_NUMBER (xoffset, 1);
1777 CHECK_NUMBER (yoffset, 2);
1778 f = XFRAME (frame);
1779
1780 /* I think this should be done with a hook. */
1781 #ifdef HAVE_X_WINDOWS
1782 if (FRAME_X_P (f))
1783 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
1784 #endif
1785
1786 return Qt;
1787 }
1788
1789 \f
1790 choose_minibuf_frame ()
1791 {
1792 /* For lowest-level minibuf, put it on currently selected frame
1793 if frame has a minibuffer. */
1794
1795 if (minibuf_level == 0
1796 && selected_frame != 0
1797 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1798 {
1799 /* I don't think that any frames may validly have a null minibuffer
1800 window anymore. */
1801 if (NILP (selected_frame->minibuffer_window))
1802 abort ();
1803
1804 Fset_window_buffer (selected_frame->minibuffer_window,
1805 XWINDOW (minibuf_window)->buffer);
1806 minibuf_window = selected_frame->minibuffer_window;
1807 }
1808 }
1809 \f
1810 syms_of_frame ()
1811 {
1812 /*&&& init symbols here &&&*/
1813 Qframep = intern ("framep");
1814 staticpro (&Qframep);
1815 Qframe_live_p = intern ("frame-live-p");
1816 staticpro (&Qframe_live_p);
1817 Qheight = intern ("height");
1818 staticpro (&Qheight);
1819 Qicon = intern ("icon");
1820 staticpro (&Qicon);
1821 Qminibuffer = intern ("minibuffer");
1822 staticpro (&Qminibuffer);
1823 Qmodeline = intern ("modeline");
1824 staticpro (&Qmodeline);
1825 Qname = intern ("name");
1826 staticpro (&Qname);
1827 Qonly = intern ("only");
1828 staticpro (&Qonly);
1829 Qunsplittable = intern ("unsplittable");
1830 staticpro (&Qunsplittable);
1831 Qmenu_bar_lines = intern ("menu-bar-lines");
1832 staticpro (&Qmenu_bar_lines);
1833 Qwidth = intern ("width");
1834 staticpro (&Qwidth);
1835 Qx = intern ("x");
1836 staticpro (&Qx);
1837 Qvisible = intern ("visible");
1838 staticpro (&Qvisible);
1839 Qbuffer_predicate = intern ("buffer-predicate");
1840 staticpro (&Qbuffer_predicate);
1841
1842 staticpro (&Vframe_list);
1843
1844 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1845 "The initial frame-object, which represents Emacs's stdout.");
1846
1847 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1848 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1849 Vemacs_iconified = Qnil;
1850
1851 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1852 "Minibufferless frames use this frame's minibuffer.\n\
1853 \n\
1854 Emacs cannot create minibufferless frames unless this is set to an\n\
1855 appropriate surrogate.\n\
1856 \n\
1857 Emacs consults this variable only when creating minibufferless\n\
1858 frames; once the frame is created, it sticks with its assigned\n\
1859 minibuffer, no matter what this variable is set to. This means that\n\
1860 this variable doesn't necessarily say anything meaningful about the\n\
1861 current set of frames, or where the minibuffer is currently being\n\
1862 displayed.");
1863 Vdefault_minibuffer_frame = Qnil;
1864
1865 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1866 "Alist of default values for frame creation.\n\
1867 These may be set in your init file, like this:\n\
1868 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
1869 These override values given in window system configuration data,\n\
1870 including X Windows' defaults database.\n\
1871 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1872 For values specific to the separate minibuffer frame, see\n\
1873 `minibuffer-frame-alist'.\n\
1874 The `menu-bar-lines' element of the list controls whether new frames\n\
1875 have menu bars; `menu-bar-mode' works by altering this element.");
1876 Vdefault_frame_alist = Qnil;
1877
1878 defsubr (&Sactive_minibuffer_window);
1879 defsubr (&Sframep);
1880 defsubr (&Sframe_live_p);
1881 defsubr (&Smake_terminal_frame);
1882 defsubr (&Shandle_switch_frame);
1883 defsubr (&Sselect_frame);
1884 defsubr (&Sselected_frame);
1885 defsubr (&Swindow_frame);
1886 defsubr (&Sframe_root_window);
1887 defsubr (&Sframe_first_window);
1888 defsubr (&Sframe_selected_window);
1889 defsubr (&Sset_frame_selected_window);
1890 defsubr (&Sframe_list);
1891 defsubr (&Snext_frame);
1892 defsubr (&Sprevious_frame);
1893 defsubr (&Sdelete_frame);
1894 defsubr (&Smouse_position);
1895 defsubr (&Smouse_pixel_position);
1896 defsubr (&Sset_mouse_position);
1897 defsubr (&Sset_mouse_pixel_position);
1898 #if 0
1899 defsubr (&Sframe_configuration);
1900 defsubr (&Srestore_frame_configuration);
1901 #endif
1902 defsubr (&Smake_frame_visible);
1903 defsubr (&Smake_frame_invisible);
1904 defsubr (&Siconify_frame);
1905 defsubr (&Sframe_visible_p);
1906 defsubr (&Svisible_frame_list);
1907 defsubr (&Sraise_frame);
1908 defsubr (&Slower_frame);
1909 defsubr (&Sredirect_frame_focus);
1910 defsubr (&Sframe_focus);
1911 defsubr (&Sframe_parameters);
1912 defsubr (&Smodify_frame_parameters);
1913 defsubr (&Sframe_char_height);
1914 defsubr (&Sframe_char_width);
1915 defsubr (&Sframe_pixel_height);
1916 defsubr (&Sframe_pixel_width);
1917 defsubr (&Sset_frame_height);
1918 defsubr (&Sset_frame_width);
1919 defsubr (&Sset_frame_size);
1920 defsubr (&Sset_frame_position);
1921 }
1922
1923 keys_of_frame ()
1924 {
1925 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
1926 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1927 initial_define_lispy_key (global_map, "iconify-frame", "ignore");
1928 initial_define_lispy_key (global_map, "make-frame-visible", "ignore");
1929 }
1930 \f
1931 #else /* not MULTI_FRAME */
1932
1933 /* If we're not using multi-frame stuff, we still need to provide some
1934 support functions. */
1935
1936 Lisp_Object Qheight;
1937 Lisp_Object Qminibuffer;
1938 Lisp_Object Qmodeline;
1939 Lisp_Object Qname;
1940 Lisp_Object Qunsplittable;
1941 Lisp_Object Qmenu_bar_lines;
1942 Lisp_Object Qwidth;
1943
1944 Lisp_Object Vterminal_frame;
1945
1946 /* Unless this function is defined, providing set-frame-height and
1947 set-frame-width doesn't help compatibility any, since they both
1948 want this as their first argument. */
1949 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1950 /* Don't confuse make-docfile by having two doc strings for this function.
1951 make-docfile does not pay attention to #if, for good reason! */
1952 0)
1953 ()
1954 {
1955 /* For your possible information, this code is unfolded into the
1956 second WINDOW_FRAME in frame.h. */
1957 Lisp_Object tem;
1958 XSETFASTINT (tem, 0);
1959 return tem;
1960 }
1961
1962 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
1963 /* Don't confuse make-docfile by having two doc strings for this function.
1964 make-docfile does not pay attention to #if, for good reason! */
1965 0)
1966 (window)
1967 Lisp_Object window;
1968 {
1969 /* For your possible information, this code is unfolded into the
1970 second WINDOW_FRAME in frame.h. */
1971 Lisp_Object tem;
1972 XSETFASTINT (tem, 0);
1973 return tem;
1974 }
1975
1976 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
1977 0)
1978 (frame)
1979 Lisp_Object frame;
1980 {
1981 Lisp_Object w;
1982
1983 w = FRAME_ROOT_WINDOW (selected_frame);
1984
1985 while (NILP (XWINDOW (w)->buffer))
1986 {
1987 if (! NILP (XWINDOW (w)->hchild))
1988 w = XWINDOW (w)->hchild;
1989 else if (! NILP (XWINDOW (w)->vchild))
1990 w = XWINDOW (w)->vchild;
1991 else
1992 abort ();
1993 }
1994 return w;
1995 }
1996
1997 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1998 /* Don't confuse make-docfile by having two doc strings for this function.
1999 make-docfile does not pay attention to #if, for good reason! */
2000 0)
2001 (object)
2002 Lisp_Object object;
2003 {
2004 #ifdef MSDOS
2005 if (FRAME_X_P (object))
2006 return intern ("pc");
2007 #endif
2008 return Qnil;
2009 }
2010
2011 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2012 /* Don't confuse make-docfile by having two doc strings for this function.
2013 make-docfile does not pay attention to #if, for good reason! */
2014 0)
2015 (frame, rows, pretend)
2016 Lisp_Object frame, rows, pretend;
2017 {
2018 CHECK_NUMBER (rows, 0);
2019
2020 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
2021 return Qnil;
2022 }
2023
2024 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2025 /* Don't confuse make-docfile by having two doc strings for this function.
2026 make-docfile does not pay attention to #if, for good reason! */
2027 0)
2028 (frame, cols, pretend)
2029 Lisp_Object frame, cols, pretend;
2030 {
2031 CHECK_NUMBER (cols, 0);
2032
2033 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2034 return Qnil;
2035 }
2036
2037 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2038 /* Don't confuse make-docfile by having two doc strings for this function.
2039 make-docfile does not pay attention to #if, for good reason! */
2040 0)
2041 (frame, cols, rows)
2042 Lisp_Object frame, cols, rows;
2043 {
2044 CHECK_NUMBER (cols, 2);
2045 CHECK_NUMBER (rows, 1);
2046
2047 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
2048
2049 return Qnil;
2050 }
2051 \f
2052 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
2053 "Return number of lines available for display on FRAME.\n\
2054 If FRAME is omitted, describe the currently selected frame.")
2055 (frame)
2056 Lisp_Object frame;
2057 {
2058 return make_number (FRAME_HEIGHT (selected_frame));
2059 }
2060
2061 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
2062 "Return number of columns available for display on FRAME.\n\
2063 If FRAME is omitted, describe the currently selected frame.")
2064 (frame)
2065 Lisp_Object frame;
2066 {
2067 return make_number (FRAME_WIDTH (selected_frame));
2068 }
2069
2070 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2071 0, 1, 0,
2072 /* Don't confuse make-docfile by having two doc strings for this function.
2073 make-docfile does not pay attention to #if, for good reason! */
2074 0)
2075 (frame)
2076 Lisp_Object frame;
2077 {
2078 return make_number (1);
2079 }
2080
2081
2082 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2083 0, 1, 0,
2084 /* Don't confuse make-docfile by having two doc strings for this function.
2085 make-docfile does not pay attention to #if, for good reason! */
2086 0)
2087 (frame)
2088 Lisp_Object frame;
2089 {
2090 return make_number (1);
2091 }
2092
2093 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2094 Sframe_pixel_height, 0, 1, 0,
2095 /* Don't confuse make-docfile by having two doc strings for this function.
2096 make-docfile does not pay attention to #if, for good reason! */
2097 0)
2098 (frame)
2099 Lisp_Object frame;
2100 {
2101 return make_number (FRAME_HEIGHT (f));
2102 }
2103
2104 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2105 Sframe_pixel_width, 0, 1, 0,
2106 /* Don't confuse make-docfile by having two doc strings for this function.
2107 make-docfile does not pay attention to #if, for good reason! */
2108 0)
2109 (frame)
2110 Lisp_Object frame;
2111 {
2112 return make_number (FRAME_WIDTH (f));
2113 }
2114
2115 /* These are for backward compatibility with Emacs 18. */
2116
2117 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
2118 "Tell redisplay that the screen has LINES lines.\n\
2119 Optional second arg non-nil means that redisplay should use LINES lines\n\
2120 but that the idea of the actual height of the screen should not be changed.")
2121 (lines, pretend)
2122 Lisp_Object lines, pretend;
2123 {
2124 CHECK_NUMBER (lines, 0);
2125
2126 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
2127 return Qnil;
2128 }
2129
2130 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
2131 "Tell redisplay that the screen has COLS columns.\n\
2132 Optional second arg non-nil means that redisplay should use COLS columns\n\
2133 but that the idea of the actual width of the screen should not be changed.")
2134 (cols, pretend)
2135 Lisp_Object cols, pretend;
2136 {
2137 CHECK_NUMBER (cols, 0);
2138
2139 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2140 return Qnil;
2141 }
2142
2143 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
2144 /* Don't confuse make-docfile by having two doc strings for this function.
2145 make-docfile does not pay attention to #if, for good reason! */
2146 0)
2147 ()
2148 {
2149 #ifdef HAVE_MOUSE
2150 if (mouse_position_hook)
2151 {
2152 FRAME_PTR f;
2153 Lisp_Object lispy_dummy;
2154 enum scroll_bar_part party_dummy;
2155 Lisp_Object x, y;
2156 unsigned long long_dummy;
2157
2158 (*mouse_position_hook) (&f, 0,
2159 &lispy_dummy, &party_dummy,
2160 &x, &y,
2161 &long_dummy);
2162 return Fcons (Fselected_frame (), Fcons (x, y));
2163 }
2164 #endif
2165 return Fcons (Qnil, Fcons (Qnil, Qnil));
2166 }
2167 \f
2168 void
2169 store_in_alist (alistptr, prop, val)
2170 Lisp_Object *alistptr, val;
2171 Lisp_Object prop;
2172 {
2173 register Lisp_Object tem;
2174
2175 tem = Fassq (prop, *alistptr);
2176 if (EQ (tem, Qnil))
2177 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2178 else
2179 Fsetcdr (tem, val);
2180 }
2181
2182 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2183 /* Don't confuse make-docfile by having two doc strings for this function.
2184 make-docfile does not pay attention to #if, for good reason! */
2185 0)
2186 (frame)
2187 Lisp_Object frame;
2188 {
2189 Lisp_Object alist;
2190 FRAME_PTR f;
2191
2192 if (EQ (frame, Qnil))
2193 f = selected_frame;
2194 else
2195 {
2196 CHECK_FRAME (frame, 0);
2197 f = XFRAME (frame);
2198 }
2199
2200 if (!FRAME_LIVE_P (f))
2201 return Qnil;
2202
2203 alist = Qnil;
2204 #ifdef MSDOS
2205 if (FRAME_X_P (f))
2206 {
2207 static char *colornames[16] =
2208 {
2209 "black", "blue", "green", "cyan", "red", "magenta", "brown",
2210 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
2211 "lightred", "lightmagenta", "yellow", "white"
2212 };
2213 store_in_alist (&alist, intern ("foreground-color"),
2214 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
2215 store_in_alist (&alist, intern ("background-color"),
2216 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
2217 }
2218 #endif
2219 store_in_alist (&alist, intern ("font"), build_string ("default"));
2220 store_in_alist (&alist, Qname, build_string ("emacs"));
2221 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
2222 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
2223 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2224 store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
2225 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2226 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
2227
2228 return alist;
2229 }
2230
2231 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2232 Smodify_frame_parameters, 2, 2, 0,
2233 /* Don't confuse make-docfile by having two doc strings for this function.
2234 make-docfile does not pay attention to #if, for good reason! */
2235 0)
2236 (frame, alist)
2237 Lisp_Object frame, alist;
2238 {
2239 #ifdef MSDOS
2240 if (FRAME_X_P (frame))
2241 IT_set_frame_parameters (XFRAME (frame), alist);
2242 #endif
2243 return Qnil;
2244 }
2245
2246 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
2247 /* Don't confuse make-docfile by having two doc strings for this function.
2248 make-docfile does not pay attention to #if, for good reason! */
2249 0)
2250 (frame)
2251 Lisp_Object frame;
2252 {
2253 return Qt;
2254 }
2255
2256 DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0,
2257 /* Don't confuse make-docfile by having two doc strings for this function.
2258 make-docfile does not pay attention to #if, for good reason! */
2259 0)
2260 ()
2261 {
2262 return Fcons (Fselected_frame (), Qnil);
2263 }
2264
2265 syms_of_frame ()
2266 {
2267 Qheight = intern ("height");
2268 staticpro (&Qheight);
2269 Qminibuffer = intern ("minibuffer");
2270 staticpro (&Qminibuffer);
2271 Qmodeline = intern ("modeline");
2272 staticpro (&Qmodeline);
2273 Qname = intern ("name");
2274 staticpro (&Qname);
2275 Qunsplittable = intern ("unsplittable");
2276 staticpro (&Qunsplittable);
2277 Qmenu_bar_lines = intern ("menu-bar-lines");
2278 staticpro (&Qmenu_bar_lines);
2279 Qwidth = intern ("width");
2280 staticpro (&Qwidth);
2281
2282 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2283 "The initial frame-object, which represents Emacs's stdout.");
2284 XSETFASTINT (Vterminal_frame, 0);
2285
2286 defsubr (&Sselected_frame);
2287 defsubr (&Swindow_frame);
2288 defsubr (&Sframe_first_window);
2289 defsubr (&Sframep);
2290 defsubr (&Sframe_char_height);
2291 defsubr (&Sframe_char_width);
2292 defsubr (&Sframe_pixel_height);
2293 defsubr (&Sframe_pixel_width);
2294 defsubr (&Sset_frame_height);
2295 defsubr (&Sset_frame_width);
2296 defsubr (&Sset_frame_size);
2297 defsubr (&Sset_screen_height);
2298 defsubr (&Sset_screen_width);
2299 defsubr (&Sframe_height);
2300 Ffset (intern ("screen-height"), intern ("frame-height"));
2301 defsubr (&Sframe_width);
2302 Ffset (intern ("screen-width"), intern ("frame-width"));
2303 defsubr (&Smouse_position);
2304 defsubr (&Sframe_parameters);
2305 defsubr (&Smodify_frame_parameters);
2306 defsubr (&Sframe_live_p);
2307 defsubr (&Sframe_list);
2308
2309 #ifdef MSDOS
2310 /* A comment in dispnew.c says the_only_frame is not protected. */
2311 the_only_frame.face_alist = Qnil;
2312 staticpro (&the_only_frame.face_alist);
2313 the_only_frame.menu_bar_items = Qnil;
2314 staticpro (&the_only_frame.menu_bar_items);
2315 the_only_frame.menu_bar_vector = Qnil;
2316 staticpro (&the_only_frame.menu_bar_vector);
2317 the_only_frame.menu_bar_items = menu_bar_items (Qnil);
2318 #endif
2319 }
2320
2321 keys_of_frame ()
2322 {
2323 }
2324
2325 #endif /* not MULTI_FRAME */