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