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