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