]> code.delx.au - gnu-emacs/blob - src/frame.c
* xdisp.c (display_menu_bar): Redisplay all lines occupied by the
[gnu-emacs] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1993 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 <stdio.h>
21
22 #include "config.h"
23 #include "lisp.h"
24 #include "frame.h"
25
26 #ifdef MULTI_FRAME
27
28 #include "buffer.h"
29 #include "window.h"
30 #include "termhooks.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
89 extern Lisp_Object Vminibuffer_list;
90 extern Lisp_Object get_minibuffer ();
91 \f
92 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
93 "Return non-nil if OBJECT is a frame.\n\
94 Value is t for a termcap frame (a character-only terminal),\n\
95 `x' for an Emacs frame that is really an X window.\n\
96 Also see `live-frame-p'.")
97 (object)
98 Lisp_Object object;
99 {
100 if (XTYPE (object) != Lisp_Frame)
101 return Qnil;
102 switch (XFRAME (object)->output_method)
103 {
104 case output_termcap:
105 return Qt;
106 case output_x_window:
107 return Qx;
108 default:
109 abort ();
110 }
111 }
112
113 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
114 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
115 Value is nil if OBJECT is not a live frame. If object is a live\n\
116 frame, the return value indicates what sort of output device it is\n\
117 displayed on. Value is t for a termcap frame (a character-only\n\
118 terminal), `x' for an Emacs frame being displayed in an X window.")
119 (object)
120 Lisp_Object object;
121 {
122 return ((FRAMEP (object)
123 && FRAME_LIVE_P (XFRAME (object)))
124 ? Fframep (object)
125 : Qnil);
126 }
127
128 struct frame *
129 make_frame (mini_p)
130 int mini_p;
131 {
132 Lisp_Object frame;
133 register struct frame *f;
134 register Lisp_Object root_window;
135 register Lisp_Object mini_window;
136
137 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
138 - sizeof (Lisp_Object)))
139 / sizeof (Lisp_Object)),
140 make_number (0));
141 XSETTYPE (frame, Lisp_Frame);
142 f = XFRAME (frame);
143
144 f->cursor_x = 0;
145 f->cursor_y = 0;
146 f->current_glyphs = 0;
147 f->desired_glyphs = 0;
148 f->visible = 0;
149 f->async_visible = 0;
150 f->display.nothing = 0;
151 f->iconified = 0;
152 f->async_iconified = 0;
153 f->wants_modeline = 1;
154 f->auto_raise = 0;
155 f->auto_lower = 0;
156 f->no_split = 0;
157 f->garbaged = 0;
158 f->has_minibuffer = mini_p;
159 f->focus_frame = Qnil;
160 f->explicit_name = 0;
161 f->can_have_scroll_bars = 0;
162 f->has_vertical_scroll_bars = 0;
163 f->param_alist = Qnil;
164 f->scroll_bars = Qnil;
165 f->condemned_scroll_bars = Qnil;
166 f->face_alist = Qnil;
167
168 root_window = make_window ();
169 if (mini_p)
170 {
171 mini_window = make_window ();
172 XWINDOW (root_window)->next = mini_window;
173 XWINDOW (mini_window)->prev = root_window;
174 XWINDOW (mini_window)->mini_p = Qt;
175 XWINDOW (mini_window)->frame = frame;
176 f->minibuffer_window = mini_window;
177 }
178 else
179 {
180 mini_window = Qnil;
181 XWINDOW (root_window)->next = Qnil;
182 f->minibuffer_window = Qnil;
183 }
184
185 XWINDOW (root_window)->frame = frame;
186
187 /* 10 is arbitrary,
188 just so that there is "something there."
189 Correct size will be set up later with change_frame_size. */
190
191 f->width = 10;
192 f->height = 10;
193
194 XFASTINT (XWINDOW (root_window)->width) = 10;
195 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
196
197 if (mini_p)
198 {
199 XFASTINT (XWINDOW (mini_window)->width) = 10;
200 XFASTINT (XWINDOW (mini_window)->top) = 9;
201 XFASTINT (XWINDOW (mini_window)->height) = 1;
202 }
203
204 /* Choose a buffer for the frame's root window. */
205 {
206 Lisp_Object buf;
207
208 XWINDOW (root_window)->buffer = Qt;
209 buf = Fcurrent_buffer ();
210 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
211 a space), try to find another one. */
212 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
213 buf = Fother_buffer (buf, Qnil);
214 Fset_window_buffer (root_window, buf);
215 }
216
217 if (mini_p)
218 {
219 XWINDOW (mini_window)->buffer = Qt;
220 Fset_window_buffer (mini_window,
221 (NILP (Vminibuffer_list)
222 ? get_minibuffer (0)
223 : Fcar (Vminibuffer_list)));
224 }
225
226 f->root_window = root_window;
227 f->selected_window = root_window;
228 /* Make sure this window seems more recently used than
229 a newly-created, never-selected window. */
230 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
231
232 Vframe_list = Fcons (frame, Vframe_list);
233
234 return f;
235 }
236 \f
237 /* Make a frame using a separate minibuffer window on another frame.
238 MINI_WINDOW is the minibuffer window to use. nil means use the
239 default (the global minibuffer). */
240
241 struct frame *
242 make_frame_without_minibuffer (mini_window)
243 register Lisp_Object mini_window;
244 {
245 register struct frame *f;
246
247 /* Choose the minibuffer window to use. */
248 if (NILP (mini_window))
249 {
250 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
251 error ("default-minibuffer-frame must be set when creating minibufferless frames");
252 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
253 error ("default-minibuffer-frame must be a live frame");
254 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
255 }
256 else
257 {
258 CHECK_LIVE_WINDOW (mini_window, 0);
259 }
260
261 /* Make a frame containing just a root window. */
262 f = make_frame (0);
263
264 /* Install the chosen minibuffer window, with proper buffer. */
265 f->minibuffer_window = mini_window;
266 Fset_window_buffer (mini_window,
267 (NILP (Vminibuffer_list)
268 ? get_minibuffer (0)
269 : Fcar (Vminibuffer_list)));
270 return f;
271 }
272
273 /* Make a frame containing only a minibuffer window. */
274
275 struct frame *
276 make_minibuffer_frame ()
277 {
278 /* First make a frame containing just a root window, no minibuffer. */
279
280 register struct frame *f = make_frame (0);
281 register Lisp_Object mini_window;
282 register Lisp_Object frame;
283
284 XSET (frame, Lisp_Frame, f);
285
286 f->auto_raise = 0;
287 f->auto_lower = 0;
288 f->no_split = 1;
289 f->wants_modeline = 0;
290 f->has_minibuffer = 1;
291
292 /* Now label the root window as also being the minibuffer.
293 Avoid infinite looping on the window chain by marking next pointer
294 as nil. */
295
296 mini_window = f->minibuffer_window = f->root_window;
297 XWINDOW (mini_window)->mini_p = Qt;
298 XWINDOW (mini_window)->next = Qnil;
299 XWINDOW (mini_window)->prev = Qnil;
300 XWINDOW (mini_window)->frame = frame;
301
302 /* Put the proper buffer in that window. */
303
304 Fset_window_buffer (mini_window,
305 (NILP (Vminibuffer_list)
306 ? get_minibuffer (0)
307 : Fcar (Vminibuffer_list)));
308 return f;
309 }
310 \f
311 /* Construct a frame that refers to the terminal (stdin and stdout). */
312
313 struct frame *
314 make_terminal_frame ()
315 {
316 register struct frame *f;
317
318 Vframe_list = Qnil;
319 f = make_frame (1);
320 f->name = build_string ("terminal");
321 FRAME_SET_VISIBLE (f, 1);
322 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
323 XSET (Vterminal_frame, Lisp_Frame, f);
324 return f;
325 }
326 \f
327 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
328 "Select the frame FRAME.\n\
329 Subsequent editing commands apply to its selected window.\n\
330 The selection of FRAME lasts until the next time the user does\n\
331 something to select a different frame, or until the next time this\n\
332 function is called.")
333 (frame, no_enter)
334 Lisp_Object frame, no_enter;
335 {
336 return Fhandle_switch_frame (frame, no_enter);
337 }
338
339
340 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
341 "Handle a switch-frame event EVENT.\n\
342 Switch-frame events is usually bound to this function.\n\
343 A switch-frame event tells Emacs that the window manager has requested\n\
344 that the user's events be directed to the frame mentioned in the event.\n\
345 This function selects the selected window of the frame of EVENT.\n\
346 \n\
347 If EVENT is frame object, handle it as if it were a switch-frame event\n\
348 to that frame.")
349 (frame, no_enter)
350 Lisp_Object frame, no_enter;
351 {
352 /* If FRAME is a switch-frame event, extract the frame we should
353 switch to. */
354 if (CONSP (frame)
355 && EQ (XCONS (frame)->car, Qswitch_frame)
356 && CONSP (XCONS (frame)->cdr))
357 frame = XCONS (XCONS (frame)->cdr)->car;
358
359 CHECK_LIVE_FRAME (frame, 0);
360
361 if (selected_frame == XFRAME (frame))
362 return frame;
363
364 /* If a frame's focus has been redirected toward the currently
365 selected frame, we should change the redirection to point to the
366 newly selected frame. This means that if the focus is redirected
367 from a minibufferless frame to a surrogate minibuffer frame, we
368 can use `other-window' to switch between all the frames using
369 that minibuffer frame, and the focus redirection will follow us
370 around. */
371 {
372 Lisp_Object tail;
373
374 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
375 {
376 Lisp_Object focus;
377
378 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
379 abort ();
380
381 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
382
383 if (XTYPE (focus) == Lisp_Frame
384 && XFRAME (focus) == selected_frame)
385 Fredirect_frame_focus (XCONS (tail)->car, frame);
386 }
387 }
388
389 selected_frame = XFRAME (frame);
390 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
391 last_nonminibuf_frame = selected_frame;
392
393 Fselect_window (XFRAME (frame)->selected_window);
394 choose_minibuf_frame ();
395
396 /* We want to make sure that the next event generates a frame-switch
397 event to the appropriate frame. This seems kludgy to me, but
398 before you take it out, make sure that evaluating something like
399 (select-window (frame-root-window (new-frame))) doesn't end up
400 with your typing being interpreted in the new frame instead of
401 the one you're actually typing in. */
402 internal_last_event_frame = Qnil;
403
404 return frame;
405 }
406
407 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
408 "Return the frame that is now selected.")
409 ()
410 {
411 Lisp_Object tem;
412 XSET (tem, Lisp_Frame, selected_frame);
413 return tem;
414 }
415
416 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
417 "Return the frame object that window WINDOW is on.")
418 (window)
419 Lisp_Object window;
420 {
421 CHECK_LIVE_WINDOW (window, 0);
422 return XWINDOW (window)->frame;
423 }
424
425 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
426 "Returns the root-window of FRAME.\n\
427 If omitted, FRAME defaults to the currently selected frame.")
428 (frame)
429 Lisp_Object frame;
430 {
431 if (NILP (frame))
432 XSET (frame, Lisp_Frame, selected_frame);
433 else
434 CHECK_LIVE_FRAME (frame, 0);
435
436 return XFRAME (frame)->root_window;
437 }
438
439 DEFUN ("frame-selected-window", Fframe_selected_window,
440 Sframe_selected_window, 0, 1, 0,
441 "Return the selected window of frame object FRAME.\n\
442 If omitted, FRAME defaults to the currently selected frame.")
443 (frame)
444 Lisp_Object frame;
445 {
446 if (NILP (frame))
447 XSET (frame, Lisp_Frame, selected_frame);
448 else
449 CHECK_LIVE_FRAME (frame, 0);
450
451 return XFRAME (frame)->selected_window;
452 }
453
454 DEFUN ("frame-list", Fframe_list, Sframe_list,
455 0, 0, 0,
456 "Return a list of all frames.")
457 ()
458 {
459 return Fcopy_sequence (Vframe_list);
460 }
461
462 /* Return the next frame in the frame list after FRAME.
463 If MINIBUF is nil, exclude minibuffer-only frames.
464 If MINIBUF is a window, include only frames using that window for
465 their minibuffer.
466 If MINIBUF is non-nil, and not a window, include all frames. */
467 Lisp_Object
468 next_frame (frame, minibuf)
469 Lisp_Object frame;
470 Lisp_Object minibuf;
471 {
472 Lisp_Object tail;
473 int passed = 0;
474
475 /* There must always be at least one frame in Vframe_list. */
476 if (! CONSP (Vframe_list))
477 abort ();
478
479 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
480 forever. Forestall that. */
481 CHECK_LIVE_FRAME (frame, 0);
482
483 while (1)
484 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
485 {
486 Lisp_Object f = XCONS (tail)->car;
487
488 if (passed)
489 {
490 /* Decide whether this frame is eligible to be returned. */
491
492 /* If we've looped all the way around without finding any
493 eligible frames, return the original frame. */
494 if (EQ (f, frame))
495 return f;
496
497 /* Let minibuf decide if this frame is acceptable. */
498 if (NILP (minibuf))
499 {
500 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
501 return f;
502 }
503 else if (XTYPE (minibuf) == Lisp_Window)
504 {
505 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
506 return f;
507 }
508 else
509 return f;
510 }
511
512 if (EQ (frame, f))
513 passed++;
514 }
515 }
516
517 /* Return the previous frame in the frame list before FRAME.
518 If MINIBUF is nil, exclude minibuffer-only frames.
519 If MINIBUF is a window, include only frames using that window for
520 their minibuffer.
521 If MINIBUF is non-nil and not a window, include all frames. */
522 Lisp_Object
523 prev_frame (frame, minibuf)
524 Lisp_Object frame;
525 Lisp_Object minibuf;
526 {
527 Lisp_Object tail;
528 Lisp_Object prev;
529
530 /* There must always be at least one frame in Vframe_list. */
531 if (! CONSP (Vframe_list))
532 abort ();
533
534 prev = Qnil;
535 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
536 {
537 Lisp_Object f = XCONS (tail)->car;
538
539 if (XTYPE (f) != Lisp_Frame)
540 abort ();
541
542 if (EQ (frame, f) && !NILP (prev))
543 return prev;
544
545 /* Decide whether this frame is eligible to be returned,
546 according to minibuf. */
547 if (NILP (minibuf))
548 {
549 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
550 prev = f;
551 }
552 else if (XTYPE (minibuf) == Lisp_Window)
553 {
554 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
555 prev = f;
556 }
557 else
558 prev = f;
559 }
560
561 /* We've scanned the entire list. */
562 if (NILP (prev))
563 /* We went through the whole frame list without finding a single
564 acceptable frame. Return the original frame. */
565 return frame;
566 else
567 /* There were no acceptable frames in the list before FRAME; otherwise,
568 we would have returned directly from the loop. Since PREV is the last
569 acceptable frame in the list, return it. */
570 return prev;
571 }
572
573 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
574 "Return the next frame in the frame list after FRAME.\n\
575 By default, skip minibuffer-only frames.\n\
576 If omitted, FRAME defaults to the selected frame.\n\
577 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
578 If MINIFRAME is a window, include only frames using that window for their\n\
579 minibuffer.\n\
580 If MINIFRAME is non-nil and not a window, include all frames.")
581 (frame, miniframe)
582 Lisp_Object frame, miniframe;
583 {
584 Lisp_Object tail;
585
586 if (NILP (frame))
587 XSET (frame, Lisp_Frame, selected_frame);
588 else
589 CHECK_LIVE_FRAME (frame, 0);
590
591 return next_frame (frame, miniframe);
592 }
593
594 \f
595 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
596 "Delete FRAME, permanently eliminating it from use.\n\
597 If omitted, FRAME defaults to the selected frame.\n\
598 A frame may not be deleted if its minibuffer is used by other frames.\n\
599 Normally, you may not delete a frame if all other frames are invisible,\n\
600 but if the second optional argument FORCE is non-nil, you may do so.")
601 (frame, force)
602 Lisp_Object frame, force;
603 {
604 struct frame *f;
605
606 if (EQ (frame, Qnil))
607 {
608 f = selected_frame;
609 XSET (frame, Lisp_Frame, f);
610 }
611 else
612 {
613 CHECK_FRAME (frame, 0);
614 f = XFRAME (frame);
615 }
616
617 if (! FRAME_LIVE_P (f))
618 return Qnil;
619
620 /* If all other frames are invisible, refuse to delete.
621 (Exception: allow deleting the terminal frame when using X.) */
622 if (f == selected_frame && NILP (force))
623 {
624 Lisp_Object frames;
625 int count = 0;
626
627 for (frames = Vframe_list;
628 CONSP (frames);
629 frames = XCONS (frames)->cdr)
630 {
631 Lisp_Object this = XCONS (frames)->car;
632
633 if (FRAME_VISIBLE_P (XFRAME (this))
634 || FRAME_ICONIFIED_P (XFRAME (this))
635 /* Allow deleting the terminal frame when at least
636 one X frame exists! */
637 || FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f))
638 count++;
639 }
640 if (count == 1)
641 error ("Attempt to delete the only frame");
642 }
643
644 /* Does this frame have a minibuffer, and is it the surrogate
645 minibuffer for any other frame? */
646 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
647 {
648 Lisp_Object frames;
649
650 for (frames = Vframe_list;
651 CONSP (frames);
652 frames = XCONS (frames)->cdr)
653 {
654 Lisp_Object this = XCONS (frames)->car;
655
656 if (! EQ (this, frame)
657 && EQ (frame,
658 (WINDOW_FRAME
659 (XWINDOW
660 (FRAME_MINIBUF_WINDOW
661 (XFRAME (this)))))))
662 error ("Attempt to delete a surrogate minibuffer frame");
663 }
664 }
665
666 /* Don't let the frame remain selected. */
667 if (f == selected_frame)
668 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
669
670 /* Don't allow minibuf_window to remain on a deleted frame. */
671 if (EQ (f->minibuffer_window, minibuf_window))
672 {
673 Fset_window_buffer (selected_frame->minibuffer_window,
674 XWINDOW (minibuf_window)->buffer);
675 minibuf_window = selected_frame->minibuffer_window;
676 }
677
678 /* Mark all the windows that used to be on FRAME as deleted, and then
679 remove the reference to them. */
680 delete_all_subwindows (XWINDOW (f->root_window));
681 f->root_window = Qnil;
682
683 Vframe_list = Fdelq (frame, Vframe_list);
684 FRAME_SET_VISIBLE (f, 0);
685
686 /* Since some events are handled at the interrupt level, we may get
687 an event for f at any time; if we zero out the frame's display
688 now, then we may trip up the event-handling code. Instead, we'll
689 promise that the display of the frame must be valid until we have
690 called the window-system-dependent frame destruction routine. */
691
692 /* I think this should be done with a hook. */
693 #ifdef HAVE_X_WINDOWS
694 if (FRAME_X_P (f))
695 x_destroy_window (f);
696 #endif
697
698 f->display.nothing = 0;
699
700 /* If we've deleted the last_nonminibuf_frame, then try to find
701 another one. */
702 if (f == last_nonminibuf_frame)
703 {
704 Lisp_Object frames;
705
706 last_nonminibuf_frame = 0;
707
708 for (frames = Vframe_list;
709 CONSP (frames);
710 frames = XCONS (frames)->cdr)
711 {
712 f = XFRAME (XCONS (frames)->car);
713 if (!FRAME_MINIBUF_ONLY_P (f))
714 {
715 last_nonminibuf_frame = f;
716 break;
717 }
718 }
719 }
720
721 /* If we've deleted Vdefault_minibuffer_frame, try to find another
722 one. Prefer minibuffer-only frames, but also notice frames
723 with other windows. */
724 if (EQ (frame, Vdefault_minibuffer_frame))
725 {
726 Lisp_Object frames;
727
728 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
729 Lisp_Object frame_with_minibuf = Qnil;
730
731 for (frames = Vframe_list;
732 CONSP (frames);
733 frames = XCONS (frames)->cdr)
734 {
735 Lisp_Object this = XCONS (frames)->car;
736
737 if (XTYPE (this) != Lisp_Frame)
738 abort ();
739 f = XFRAME (this);
740
741 if (FRAME_HAS_MINIBUF_P (f))
742 {
743 frame_with_minibuf = this;
744 if (FRAME_MINIBUF_ONLY_P (f))
745 break;
746 }
747 }
748
749 /* We know that there must be some frame with a minibuffer out
750 there. If this were not true, all of the frames present
751 would have to be minibufferless, which implies that at some
752 point their minibuffer frames must have been deleted, but
753 that is prohibited at the top; you can't delete surrogate
754 minibuffer frames. */
755 if (NILP (frame_with_minibuf))
756 abort ();
757
758 Vdefault_minibuffer_frame = frame_with_minibuf;
759 }
760
761 return Qnil;
762 }
763 \f
764 /* Return mouse position in character cell units. */
765
766 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
767 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
768 The position is given in character cells, where (0, 0) is the\n\
769 upper-left corner.\n\
770 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
771 to read the mouse position, it returns the selected frame for FRAME\n\
772 and nil for X and Y.")
773 ()
774 {
775 FRAME_PTR f;
776 Lisp_Object lispy_dummy;
777 enum scroll_bar_part party_dummy;
778 Lisp_Object x, y;
779 unsigned long long_dummy;
780
781 f = selected_frame;
782 x = y = Qnil;
783
784 /* It's okay for the hook to refrain from storing anything. */
785 if (mouse_position_hook)
786 (*mouse_position_hook) (&f,
787 &lispy_dummy, &party_dummy,
788 &x, &y,
789 &long_dummy);
790
791 XSET (lispy_dummy, Lisp_Frame, f);
792 return Fcons (lispy_dummy, Fcons (x, y));
793 }
794
795 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
796 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
797 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
798 (frame, x, y)
799 Lisp_Object frame, x, y;
800 {
801 CHECK_LIVE_FRAME (frame, 0);
802 CHECK_NUMBER (x, 2);
803 CHECK_NUMBER (y, 1);
804
805 /* I think this should be done with a hook. */
806 #ifdef HAVE_X_WINDOWS
807 if (FRAME_X_P (XFRAME (frame)))
808 /* Warping the mouse will cause enternotify and focus events. */
809 x_set_mouse_position (XFRAME (frame), x, y);
810 #endif
811
812 return Qnil;
813 }
814 \f
815 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
816 0, 1, "",
817 "Make the frame FRAME visible (assuming it is an X-window).\n\
818 Also raises the frame so that nothing obscures it.\n\
819 If omitted, FRAME defaults to the currently selected frame.")
820 (frame)
821 Lisp_Object frame;
822 {
823 if (NILP (frame))
824 XSET (frame, Lisp_Frame, selected_frame);
825
826 CHECK_LIVE_FRAME (frame, 0);
827
828 /* I think this should be done with a hook. */
829 #ifdef HAVE_X_WINDOWS
830 if (FRAME_X_P (XFRAME (frame)))
831 x_make_frame_visible (XFRAME (frame));
832 #endif
833
834 return frame;
835 }
836
837 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
838 0, 1, "",
839 "Make the frame FRAME invisible (assuming it is an X-window).\n\
840 If omitted, FRAME defaults to the currently selected frame.")
841 (frame)
842 Lisp_Object frame;
843 {
844 if (NILP (frame))
845 XSET (frame, Lisp_Frame, selected_frame);
846
847 CHECK_LIVE_FRAME (frame, 0);
848
849 /* Don't let the frame remain selected. */
850 if (XFRAME (frame) == selected_frame)
851 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
852
853 /* Don't allow minibuf_window to remain on a deleted frame. */
854 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
855 {
856 Fset_window_buffer (selected_frame->minibuffer_window,
857 XWINDOW (minibuf_window)->buffer);
858 minibuf_window = selected_frame->minibuffer_window;
859 }
860
861 /* I think this should be done with a hook. */
862 #ifdef HAVE_X_WINDOWS
863 if (FRAME_X_P (XFRAME (frame)))
864 x_make_frame_invisible (XFRAME (frame));
865 #endif
866
867 return Qnil;
868 }
869
870 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
871 0, 1, "",
872 "Make the frame FRAME into an icon.\n\
873 If omitted, FRAME defaults to the currently selected frame.")
874 (frame)
875 Lisp_Object frame;
876 {
877 if (NILP (frame))
878 XSET (frame, Lisp_Frame, selected_frame);
879
880 CHECK_LIVE_FRAME (frame, 0);
881
882 /* Don't let the frame remain selected. */
883 if (XFRAME (frame) == selected_frame)
884 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
885
886 /* Don't allow minibuf_window to remain on a deleted frame. */
887 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
888 {
889 Fset_window_buffer (selected_frame->minibuffer_window,
890 XWINDOW (minibuf_window)->buffer);
891 minibuf_window = selected_frame->minibuffer_window;
892 }
893
894 /* I think this should be done with a hook. */
895 #ifdef HAVE_X_WINDOWS
896 if (FRAME_X_P (XFRAME (frame)))
897 x_iconify_frame (XFRAME (frame));
898 #endif
899
900 return Qnil;
901 }
902
903 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
904 1, 1, 0,
905 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
906 A frame that is not \"visible\" is not updated and, if it works through\n\
907 a window system, it may not show at all.\n\
908 Return the symbol `icon' if frame is visible only as an icon.")
909 (frame)
910 Lisp_Object frame;
911 {
912 CHECK_LIVE_FRAME (frame, 0);
913
914 if (FRAME_VISIBLE_P (XFRAME (frame)))
915 return Qt;
916 if (FRAME_ICONIFIED_P (XFRAME (frame)))
917 return Qicon;
918 return Qnil;
919 }
920
921 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
922 0, 0, 0,
923 "Return a list of all frames now \"visible\" (being updated).")
924 ()
925 {
926 Lisp_Object tail, frame;
927 struct frame *f;
928 Lisp_Object value;
929
930 value = Qnil;
931 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
932 {
933 frame = XCONS (tail)->car;
934 if (XTYPE (frame) != Lisp_Frame)
935 continue;
936 f = XFRAME (frame);
937 if (FRAME_VISIBLE_P (f))
938 value = Fcons (frame, value);
939 }
940 return value;
941 }
942
943
944 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
945 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
946 If FRAME is invisible, make it visible.\n\
947 If Emacs is displaying on an ordinary terminal or some other device which\n\
948 doesn't support multiple overlapping frames, this function does nothing.")
949 (frame)
950 Lisp_Object frame;
951 {
952 CHECK_LIVE_FRAME (frame, 0);
953
954 if (frame_raise_lower_hook)
955 (*frame_raise_lower_hook) (XFRAME (frame), 1);
956
957 return Qnil;
958 }
959
960 /* Should we have a corresponding function called Flower_Power? */
961 DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
962 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
963 If Emacs is displaying on an ordinary terminal or some other device which\n\
964 doesn't support multiple overlapping frames, this function does nothing.")
965 (frame)
966 Lisp_Object frame;
967 {
968 CHECK_LIVE_FRAME (frame, 0);
969
970 if (frame_raise_lower_hook)
971 (*frame_raise_lower_hook) (XFRAME (frame), 0);
972
973 return Qnil;
974 }
975
976 \f
977 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
978 1, 2, 0,
979 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
980 In other words, switch-frame events caused by events in FRAME will\n\
981 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
982 FOCUS-FRAME after reading an event typed at FRAME.\n\
983 \n\
984 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
985 cancelled, and the frame again receives its own keystrokes.\n\
986 \n\
987 Focus redirection is useful for temporarily redirecting keystrokes to\n\
988 a surrogate minibuffer frame when a frame doesn't have its own\n\
989 minibuffer window.\n\
990 \n\
991 A frame's focus redirection can be changed by select-frame. If frame\n\
992 FOO is selected, and then a different frame BAR is selected, any\n\
993 frames redirecting their focus to FOO are shifted to redirect their\n\
994 focus to BAR. This allows focus redirection to work properly when the\n\
995 user switches from one frame to another using `select-window'.\n\
996 \n\
997 This means that a frame whose focus is redirected to itself is treated\n\
998 differently from a frame whose focus is redirected to nil; the former\n\
999 is affected by select-frame, while the latter is not.\n\
1000 \n\
1001 The redirection lasts until `redirect-frame-focus' is called to change it.")
1002 (frame, focus_frame)
1003 Lisp_Object frame, focus_frame;
1004 {
1005 /* Note that we don't check for a live frame here. It's reasonable
1006 to redirect the focus of a frame you're about to delete, if you
1007 know what other frame should receive those keystrokes. */
1008 CHECK_FRAME (frame, 0);
1009
1010 if (! NILP (focus_frame))
1011 CHECK_LIVE_FRAME (focus_frame, 1);
1012
1013 XFRAME (frame)->focus_frame = focus_frame;
1014
1015 /* I think this should be done with a hook. */
1016 #ifdef HAVE_X_WINDOWS
1017 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1018 && FRAME_X_P (XFRAME (focus_frame)))
1019 Ffocus_frame (focus_frame);
1020 #endif
1021
1022 if (frame_rehighlight_hook)
1023 (*frame_rehighlight_hook) ();
1024
1025 return Qnil;
1026 }
1027
1028
1029 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1030 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1031 This returns nil if FRAME's focus is not redirected.\n\
1032 See `redirect-frame-focus'.")
1033 (frame)
1034 Lisp_Object frame;
1035 {
1036 CHECK_LIVE_FRAME (frame, 0);
1037
1038 return FRAME_FOCUS_FRAME (XFRAME (frame));
1039 }
1040
1041
1042 \f
1043 Lisp_Object
1044 get_frame_param (frame, prop)
1045 register struct frame *frame;
1046 Lisp_Object prop;
1047 {
1048 register Lisp_Object tem;
1049
1050 tem = Fassq (prop, frame->param_alist);
1051 if (EQ (tem, Qnil))
1052 return tem;
1053 return Fcdr (tem);
1054 }
1055
1056 void
1057 store_in_alist (alistptr, prop, val)
1058 Lisp_Object *alistptr, val;
1059 Lisp_Object prop;
1060 {
1061 register Lisp_Object tem;
1062
1063 tem = Fassq (prop, *alistptr);
1064 if (EQ (tem, Qnil))
1065 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1066 else
1067 Fsetcdr (tem, val);
1068 }
1069
1070 void
1071 store_frame_param (f, prop, val)
1072 struct frame *f;
1073 Lisp_Object prop, val;
1074 {
1075 register Lisp_Object tem;
1076
1077 tem = Fassq (prop, f->param_alist);
1078 if (EQ (tem, Qnil))
1079 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1080 else
1081 Fsetcdr (tem, val);
1082
1083 if (EQ (prop, Qminibuffer)
1084 && XTYPE (val) == Lisp_Window)
1085 {
1086 if (! MINI_WINDOW_P (XWINDOW (val)))
1087 error ("Surrogate minibuffer windows must be minibuffer windows.");
1088
1089 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1090 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1091
1092 /* Install the chosen minibuffer window, with proper buffer. */
1093 f->minibuffer_window = val;
1094 }
1095 }
1096
1097 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1098 "Return the parameters-alist of frame FRAME.\n\
1099 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1100 The meaningful PARMs depend on the kind of frame.\n\
1101 If FRAME is omitted, return information on the currently selected frame.")
1102 (frame)
1103 Lisp_Object frame;
1104 {
1105 Lisp_Object alist;
1106 struct frame *f;
1107
1108 if (EQ (frame, Qnil))
1109 f = selected_frame;
1110 else
1111 {
1112 CHECK_FRAME (frame, 0);
1113 f = XFRAME (frame);
1114 }
1115
1116 if (f->display.nothing == 0)
1117 return Qnil;
1118
1119 alist = Fcopy_alist (f->param_alist);
1120 store_in_alist (&alist, Qname, f->name);
1121 store_in_alist (&alist, Qheight, make_number (f->height));
1122 store_in_alist (&alist, Qwidth, make_number (f->width));
1123 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1124 store_in_alist (&alist, Qminibuffer,
1125 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1126 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1127 : FRAME_MINIBUF_WINDOW (f))));
1128 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1129 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
1130
1131 /* I think this should be done with a hook. */
1132 #ifdef HAVE_X_WINDOWS
1133 if (FRAME_X_P (f))
1134 x_report_frame_params (f, &alist);
1135 #endif
1136 return alist;
1137 }
1138
1139 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1140 Smodify_frame_parameters, 2, 2, 0,
1141 "Modify the parameters of frame FRAME according to ALIST.\n\
1142 ALIST is an alist of parameters to change and their new values.\n\
1143 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1144 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1145 (frame, alist)
1146 Lisp_Object frame, alist;
1147 {
1148 FRAME_PTR f;
1149 register Lisp_Object tail, elt, prop, val;
1150
1151 if (EQ (frame, Qnil))
1152 f = selected_frame;
1153 else
1154 {
1155 CHECK_LIVE_FRAME (frame, 0);
1156 f = XFRAME (frame);
1157 }
1158
1159 /* I think this should be done with a hook. */
1160 #ifdef HAVE_X_WINDOWS
1161 if (FRAME_X_P (f))
1162 #if 1
1163 x_set_frame_parameters (f, alist);
1164 #else
1165 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1166 {
1167 elt = Fcar (tail);
1168 prop = Fcar (elt);
1169 val = Fcdr (elt);
1170 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1171 store_frame_param (f, prop, val);
1172 }
1173 #endif
1174 #endif
1175
1176 return Qnil;
1177 }
1178 \f
1179 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1180 0, 1, 0,
1181 "Height in pixels of a line in the font in frame FRAME.\n\
1182 If FRAME is omitted, the selected frame is used.\n\
1183 For a terminal frame, the value is always 1.")
1184 (frame)
1185 Lisp_Object frame;
1186 {
1187 struct frame *f;
1188
1189 if (NILP (frame))
1190 f = selected_frame;
1191 else
1192 {
1193 CHECK_FRAME (frame, 0);
1194 f = XFRAME (frame);
1195 }
1196
1197 #ifdef HAVE_X_WINDOWS
1198 if (FRAME_X_P (f))
1199 return make_number (x_char_height (f));
1200 else
1201 #endif
1202 return make_number (1);
1203 }
1204
1205
1206 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1207 0, 1, 0,
1208 "Width in pixels of characters in the font in frame FRAME.\n\
1209 If FRAME is omitted, the selected frame is used.\n\
1210 The width is the same for all characters, because\n\
1211 currently Emacs supports only fixed-width fonts.\n\
1212 For a terminal screen, the value is always 1.")
1213 (frame)
1214 Lisp_Object frame;
1215 {
1216 struct frame *f;
1217
1218 if (NILP (frame))
1219 f = selected_frame;
1220 else
1221 {
1222 CHECK_FRAME (frame, 0);
1223 f = XFRAME (frame);
1224 }
1225
1226 #ifdef HAVE_X_WINDOWS
1227 if (FRAME_X_P (f))
1228 return make_number (x_char_width (f));
1229 else
1230 #endif
1231 return make_number (1);
1232 }
1233
1234 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1235 Sframe_pixel_height, 0, 1, 0,
1236 "Return a FRAME's height in pixels.\n\
1237 For a terminal frame, the result really gives the height in characters.\n\
1238 If FRAME is omitted, the selected frame is used.")
1239 (frame)
1240 Lisp_Object frame;
1241 {
1242 struct frame *f;
1243
1244 if (NILP (frame))
1245 f = selected_frame;
1246 else
1247 {
1248 CHECK_FRAME (frame, 0);
1249 f = XFRAME (frame);
1250 }
1251
1252 #ifdef HAVE_X_WINDOWS
1253 if (FRAME_X_P (f))
1254 return make_number (x_pixel_height (f));
1255 else
1256 #endif
1257 return make_number (FRAME_HEIGHT (f));
1258 }
1259
1260 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1261 Sframe_pixel_width, 0, 1, 0,
1262 "Return FRAME's width in pixels.\n\
1263 For a terminal frame, the result really gives the width in characters.\n\
1264 If FRAME is omitted, the selected frame is used.")
1265 (frame)
1266 Lisp_Object frame;
1267 {
1268 struct frame *f;
1269
1270 if (NILP (frame))
1271 f = selected_frame;
1272 else
1273 {
1274 CHECK_FRAME (frame, 0);
1275 f = XFRAME (frame);
1276 }
1277
1278 #ifdef HAVE_X_WINDOWS
1279 if (FRAME_X_P (f))
1280 return make_number (x_pixel_width (f));
1281 else
1282 #endif
1283 return make_number (FRAME_WIDTH (f));
1284 }
1285 \f
1286 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1287 "Specify that the frame FRAME has LINES lines.\n\
1288 Optional third arg non-nil means that redisplay should use LINES lines\n\
1289 but that the idea of the actual height of the frame should not be changed.")
1290 (frame, rows, pretend)
1291 Lisp_Object frame, rows, pretend;
1292 {
1293 register struct frame *f;
1294
1295 CHECK_NUMBER (rows, 0);
1296 if (NILP (frame))
1297 f = selected_frame;
1298 else
1299 {
1300 CHECK_LIVE_FRAME (frame, 0);
1301 f = XFRAME (frame);
1302 }
1303
1304 /* I think this should be done with a hook. */
1305 #ifdef HAVE_X_WINDOWS
1306 if (FRAME_X_P (f))
1307 {
1308 if (XINT (rows) != f->width)
1309 x_set_window_size (f, f->width, XINT (rows));
1310 }
1311 else
1312 #endif
1313 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1314 return Qnil;
1315 }
1316
1317 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1318 "Specify that the frame FRAME has COLS columns.\n\
1319 Optional third arg non-nil means that redisplay should use COLS columns\n\
1320 but that the idea of the actual width of the frame should not be changed.")
1321 (frame, cols, pretend)
1322 Lisp_Object frame, cols, pretend;
1323 {
1324 register struct frame *f;
1325 CHECK_NUMBER (cols, 0);
1326 if (NILP (frame))
1327 f = selected_frame;
1328 else
1329 {
1330 CHECK_LIVE_FRAME (frame, 0);
1331 f = XFRAME (frame);
1332 }
1333
1334 /* I think this should be done with a hook. */
1335 #ifdef HAVE_X_WINDOWS
1336 if (FRAME_X_P (f))
1337 {
1338 if (XINT (cols) != f->width)
1339 x_set_window_size (f, XINT (cols), f->height);
1340 }
1341 else
1342 #endif
1343 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1344 return Qnil;
1345 }
1346
1347 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1348 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1349 (frame, cols, rows)
1350 Lisp_Object frame, cols, rows;
1351 {
1352 register struct frame *f;
1353 int mask;
1354
1355 CHECK_LIVE_FRAME (frame, 0);
1356 CHECK_NUMBER (cols, 2);
1357 CHECK_NUMBER (rows, 1);
1358 f = XFRAME (frame);
1359
1360 /* I think this should be done with a hook. */
1361 #ifdef HAVE_X_WINDOWS
1362 if (FRAME_X_P (f))
1363 {
1364 if (XINT (rows) != f->height || XINT (cols) != f->width)
1365 x_set_window_size (f, XINT (cols), XINT (rows));
1366 }
1367 else
1368 #endif
1369 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1370
1371 return Qnil;
1372 }
1373
1374 DEFUN ("set-frame-position", Fset_frame_position,
1375 Sset_frame_position, 3, 3, 0,
1376 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1377 This is actually the position of the upper left corner of the frame.\n\
1378 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1379 the rightmost or bottommost possible position (that stays within the screen).")
1380 (frame, xoffset, yoffset)
1381 Lisp_Object frame, xoffset, yoffset;
1382 {
1383 register struct frame *f;
1384 int mask;
1385
1386 CHECK_LIVE_FRAME (frame, 0);
1387 CHECK_NUMBER (xoffset, 1);
1388 CHECK_NUMBER (yoffset, 2);
1389 f = XFRAME (frame);
1390
1391 /* I think this should be done with a hook. */
1392 #ifdef HAVE_X_WINDOWS
1393 if (FRAME_X_P (f))
1394 x_set_offset (f, XINT (xoffset), XINT (yoffset));
1395 #endif
1396
1397 return Qt;
1398 }
1399
1400 \f
1401 choose_minibuf_frame ()
1402 {
1403 /* For lowest-level minibuf, put it on currently selected frame
1404 if frame has a minibuffer. */
1405
1406 if (minibuf_level == 0
1407 && selected_frame != 0
1408 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1409 {
1410 /* I don't think that any frames may validly have a null minibuffer
1411 window anymore. */
1412 if (NILP (selected_frame->minibuffer_window))
1413 abort ();
1414
1415 Fset_window_buffer (selected_frame->minibuffer_window,
1416 XWINDOW (minibuf_window)->buffer);
1417 minibuf_window = selected_frame->minibuffer_window;
1418 }
1419 }
1420 \f
1421 syms_of_frame ()
1422 {
1423 /*&&& init symbols here &&&*/
1424 Qframep = intern ("framep");
1425 staticpro (&Qframep);
1426 Qframe_live_p = intern ("frame-live-p");
1427 staticpro (&Qframe_live_p);
1428 Qheight = intern ("height");
1429 staticpro (&Qheight);
1430 Qicon = intern ("icon");
1431 staticpro (&Qicon);
1432 Qminibuffer = intern ("minibuffer");
1433 staticpro (&Qminibuffer);
1434 Qmodeline = intern ("modeline");
1435 staticpro (&Qmodeline);
1436 Qname = intern ("name");
1437 staticpro (&Qname);
1438 Qonly = intern ("only");
1439 staticpro (&Qonly);
1440 Qunsplittable = intern ("unsplittable");
1441 staticpro (&Qunsplittable);
1442 Qwidth = intern ("width");
1443 staticpro (&Qwidth);
1444 Qx = intern ("x");
1445 staticpro (&Qx);
1446 Qmenu_bar_lines = intern ("menu-bar-lines");
1447 staticpro (&Qmenu_bar_lines);
1448
1449 staticpro (&Vframe_list);
1450
1451 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1452 "The initial frame-object, which represents Emacs's stdout.");
1453
1454 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1455 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1456 Vemacs_iconified = Qnil;
1457
1458 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1459 "Minibufferless frames use this frame's minibuffer.\n\
1460 \n\
1461 Emacs cannot create minibufferless frames unless this is set to an\n\
1462 appropriate surrogate.\n\
1463 \n\
1464 Emacs consults this variable only when creating minibufferless\n\
1465 frames; once the frame is created, it sticks with its assigned\n\
1466 minibuffer, no matter what this variable is set to. This means that\n\
1467 this variable doesn't necessarily say anything meaningful about the\n\
1468 current set of frames, or where the minibuffer is currently being\n\
1469 displayed.");
1470 Vdefault_minibuffer_frame = Qnil;
1471
1472 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1473 "Alist of default values for frame creation.\n\
1474 These may be set in your init file, like this:\n\
1475 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1476 These override values given in window system configuration data, like\n\
1477 X Windows' defaults database.\n\
1478 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1479 For values specific to the separate minibuffer frame, see\n\
1480 `minibuffer-frame-alist'.");
1481 Vdefault_frame_alist = Qnil;
1482
1483 defsubr (&Sframep);
1484 defsubr (&Sframe_live_p);
1485 defsubr (&Shandle_switch_frame);
1486 defsubr (&Sselect_frame);
1487 defsubr (&Sselected_frame);
1488 defsubr (&Swindow_frame);
1489 defsubr (&Sframe_root_window);
1490 defsubr (&Sframe_selected_window);
1491 defsubr (&Sframe_list);
1492 defsubr (&Snext_frame);
1493 defsubr (&Sdelete_frame);
1494 defsubr (&Smouse_position);
1495 defsubr (&Sset_mouse_position);
1496 #if 0
1497 defsubr (&Sframe_configuration);
1498 defsubr (&Srestore_frame_configuration);
1499 #endif
1500 defsubr (&Smake_frame_visible);
1501 defsubr (&Smake_frame_invisible);
1502 defsubr (&Siconify_frame);
1503 defsubr (&Sframe_visible_p);
1504 defsubr (&Svisible_frame_list);
1505 defsubr (&Sraise_frame);
1506 defsubr (&Slower_frame);
1507 defsubr (&Sredirect_frame_focus);
1508 defsubr (&Sframe_focus);
1509 defsubr (&Sframe_parameters);
1510 defsubr (&Smodify_frame_parameters);
1511 defsubr (&Sframe_char_height);
1512 defsubr (&Sframe_char_width);
1513 defsubr (&Sframe_pixel_height);
1514 defsubr (&Sframe_pixel_width);
1515 defsubr (&Sset_frame_height);
1516 defsubr (&Sset_frame_width);
1517 defsubr (&Sset_frame_size);
1518 defsubr (&Sset_frame_position);
1519 }
1520
1521 keys_of_frame ()
1522 {
1523 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
1524 }
1525 \f
1526 #else /* not MULTI_FRAME */
1527
1528 /* If we're not using multi-frame stuff, we still need to provide some
1529 support functions. */
1530
1531 /* Unless this function is defined, providing set-frame-height and
1532 set-frame-width doesn't help compatibility any, since they both
1533 want this as their first argument. */
1534 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1535 "Return the frame that is now selected.")
1536 ()
1537 {
1538 Lisp_Object tem;
1539 XFASTINT (tem) = 0;
1540 return tem;
1541 }
1542 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1543 "Return non-nil if OBJECT is a frame.\n\
1544 Value is t for a termcap frame (a character-only terminal),\n\
1545 `x' for an Emacs frame that is really an X window.\n\
1546 Also see `live-frame-p'.")
1547 (object)
1548 Lisp_Object object;
1549 {
1550 return Qnil;
1551 }
1552
1553 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1554 "Specify that the frame FRAME has LINES lines.\n\
1555 Optional third arg non-nil means that redisplay should use LINES lines\n\
1556 but that the idea of the actual height of the frame should not be changed.")
1557 (frame, rows, pretend)
1558 Lisp_Object frame, rows, pretend;
1559 {
1560 CHECK_NUMBER (rows, 0);
1561
1562 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1563 return Qnil;
1564 }
1565
1566 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1567 "Specify that the frame FRAME has COLS columns.\n\
1568 Optional third arg non-nil means that redisplay should use COLS columns\n\
1569 but that the idea of the actual width of the frame should not be changed.")
1570 (frame, cols, pretend)
1571 Lisp_Object frame, cols, pretend;
1572 {
1573 CHECK_NUMBER (cols, 0);
1574
1575 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1576 return Qnil;
1577 }
1578
1579 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1580 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1581 (frame, cols, rows)
1582 Lisp_Object frame, cols, rows;
1583 {
1584 CHECK_NUMBER (cols, 2);
1585 CHECK_NUMBER (rows, 1);
1586
1587 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1588
1589 return Qnil;
1590 }
1591
1592 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1593 "Return number of lines available for display on FRAME.\n\
1594 If FRAME is omitted, describe the currently selected frame.")
1595 (frame)
1596 Lisp_Object frame;
1597 {
1598 return make_number (FRAME_HEIGHT (selected_frame));
1599 }
1600
1601 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1602 "Return number of columns available for display on FRAME.\n\
1603 If FRAME is omitted, describe the currently selected frame.")
1604 (frame)
1605 Lisp_Object frame;
1606 {
1607 return make_number (FRAME_WIDTH (selected_frame));
1608 }
1609
1610 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1611 0, 1, 0,
1612 "Height in pixels of a line in the font in frame FRAME.\n\
1613 If FRAME is omitted, the selected frame is used.\n\
1614 For a terminal frame, the value is always 1.")
1615 (frame)
1616 Lisp_Object frame;
1617 {
1618 return make_number (1);
1619 }
1620
1621
1622 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1623 0, 1, 0,
1624 "Width in pixels of characters in the font in frame FRAME.\n\
1625 If FRAME is omitted, the selected frame is used.\n\
1626 The width is the same for all characters, because\n\
1627 currently Emacs supports only fixed-width fonts.\n\
1628 For a terminal screen, the value is always 1.")
1629 (frame)
1630 Lisp_Object frame;
1631 {
1632 return make_number (1);
1633 }
1634
1635 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1636 Sframe_pixel_height, 0, 1, 0,
1637 "Return FRAME's height in pixels.\n\
1638 For a terminal frame, the result really gives the height in characters.\n\
1639 If FRAME is omitted, the selected frame is used.")
1640 (frame)
1641 Lisp_Object frame;
1642 {
1643 return make_number (FRAME_HEIGHT (f));
1644 }
1645
1646 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1647 Sframe_pixel_width, 0, 1, 0,
1648 "Return FRAME's width in pixels.\n\
1649 For a terminal frame, the result really gives the width in characters.\n\
1650 If FRAME is omitted, the selected frame is used.")
1651 (frame)
1652 Lisp_Object frame;
1653 {
1654 return make_number (FRAME_WIDTH (f));
1655 }
1656
1657 /* These are for backward compatibility with Emacs 18. */
1658
1659 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1660 "Tell redisplay that the screen has LINES lines.\n\
1661 Optional second arg non-nil means that redisplay should use LINES lines\n\
1662 but that the idea of the actual height of the screen should not be changed.")
1663 (lines, pretend)
1664 Lisp_Object lines, pretend;
1665 {
1666 CHECK_NUMBER (lines, 0);
1667
1668 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1669 return Qnil;
1670 }
1671
1672 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1673 "Tell redisplay that the screen has COLS columns.\n\
1674 Optional second arg non-nil means that redisplay should use COLS columns\n\
1675 but that the idea of the actual width of the screen should not be changed.")
1676 (cols, pretend)
1677 Lisp_Object cols, pretend;
1678 {
1679 CHECK_NUMBER (cols, 0);
1680
1681 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1682 return Qnil;
1683 }
1684
1685 syms_of_frame ()
1686 {
1687 defsubr (&Sselected_frame);
1688 defsubr (&Sframep);
1689 defsubr (&Sframe_char_height);
1690 defsubr (&Sframe_char_width);
1691 defsubr (&Sframe_pixel_height);
1692 defsubr (&Sframe_pixel_width);
1693 defsubr (&Sset_frame_height);
1694 defsubr (&Sset_frame_width);
1695 defsubr (&Sset_frame_size);
1696 defsubr (&Sset_screen_height);
1697 defsubr (&Sset_screen_width);
1698 defsubr (&Sframe_height);
1699 Ffset (intern ("screen-height"), intern ("frame-height"));
1700 defsubr (&Sframe_width);
1701 Ffset (intern ("screen-width"), intern ("frame-width"));
1702 }
1703
1704 keys_of_frame ()
1705 {
1706 }
1707
1708 #endif /* not MULTI_FRAME */
1709
1710
1711
1712