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