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