Include <config.h> instead of "config.h".
[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
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
574 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
575 "Return the next frame in the frame list after FRAME.\n\
576 By default, skip minibuffer-only frames.\n\
577 If omitted, FRAME defaults to the selected frame.\n\
578 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
579 If MINIFRAME is a window, include only frames using that window for their\n\
580 minibuffer.\n\
581 If MINIFRAME is non-nil and not a window, include all frames.")
582 (frame, miniframe)
583 Lisp_Object frame, miniframe;
584 {
585 Lisp_Object tail;
586
587 if (NILP (frame))
588 XSET (frame, Lisp_Frame, selected_frame);
589 else
590 CHECK_LIVE_FRAME (frame, 0);
591
592 return next_frame (frame, miniframe);
593 }
594
595 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
596 "Return the previous frame in the frame list before FRAME.\n\
597 By default, skip minibuffer-only frames.\n\
598 If omitted, FRAME defaults to the selected frame.\n\
599 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
600 If MINIFRAME is a window, include only frames using that window for their\n\
601 minibuffer.\n\
602 If MINIFRAME is non-nil and not a window, include all frames.")
603 (frame, miniframe)
604 Lisp_Object frame, miniframe;
605 {
606 Lisp_Object tail;
607
608 if (NILP (frame))
609 XSET (frame, Lisp_Frame, selected_frame);
610 else
611 CHECK_LIVE_FRAME (frame, 0);
612
613 return prev_frame (frame, miniframe);
614 }
615
616 \f
617 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
618 "Delete FRAME, permanently eliminating it from use.\n\
619 If omitted, FRAME defaults to the selected frame.\n\
620 A frame may not be deleted if its minibuffer is used by other frames.\n\
621 Normally, you may not delete a frame if all other frames are invisible,\n\
622 but if the second optional argument FORCE is non-nil, you may do so.")
623 (frame, force)
624 Lisp_Object frame, force;
625 {
626 struct frame *f;
627
628 if (EQ (frame, Qnil))
629 {
630 f = selected_frame;
631 XSET (frame, Lisp_Frame, f);
632 }
633 else
634 {
635 CHECK_FRAME (frame, 0);
636 f = XFRAME (frame);
637 }
638
639 if (! FRAME_LIVE_P (f))
640 return Qnil;
641
642 /* If all other frames are invisible, refuse to delete.
643 (Exception: allow deleting the terminal frame when using X.) */
644 if (f == selected_frame && NILP (force))
645 {
646 Lisp_Object frames;
647 int count = 0;
648
649 for (frames = Vframe_list;
650 CONSP (frames);
651 frames = XCONS (frames)->cdr)
652 {
653 Lisp_Object this = XCONS (frames)->car;
654
655 if (FRAME_VISIBLE_P (XFRAME (this))
656 || FRAME_ICONIFIED_P (XFRAME (this))
657 /* Allow deleting the terminal frame when at least
658 one X frame exists! */
659 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
660 count++;
661 }
662 if (count == 1)
663 error ("Attempt to delete the only frame");
664 }
665
666 /* Does this frame have a minibuffer, and is it the surrogate
667 minibuffer for any other frame? */
668 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
669 {
670 Lisp_Object frames;
671
672 for (frames = Vframe_list;
673 CONSP (frames);
674 frames = XCONS (frames)->cdr)
675 {
676 Lisp_Object this = XCONS (frames)->car;
677
678 if (! EQ (this, frame)
679 && EQ (frame,
680 (WINDOW_FRAME
681 (XWINDOW
682 (FRAME_MINIBUF_WINDOW
683 (XFRAME (this)))))))
684 error ("Attempt to delete a surrogate minibuffer frame");
685 }
686 }
687
688 /* Don't let the frame remain selected. */
689 if (f == selected_frame)
690 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
691
692 /* Don't allow minibuf_window to remain on a deleted frame. */
693 if (EQ (f->minibuffer_window, minibuf_window))
694 {
695 Fset_window_buffer (selected_frame->minibuffer_window,
696 XWINDOW (minibuf_window)->buffer);
697 minibuf_window = selected_frame->minibuffer_window;
698 }
699
700 /* Mark all the windows that used to be on FRAME as deleted, and then
701 remove the reference to them. */
702 delete_all_subwindows (XWINDOW (f->root_window));
703 f->root_window = Qnil;
704
705 Vframe_list = Fdelq (frame, Vframe_list);
706 FRAME_SET_VISIBLE (f, 0);
707
708 /* Since some events are handled at the interrupt level, we may get
709 an event for f at any time; if we zero out the frame's display
710 now, then we may trip up the event-handling code. Instead, we'll
711 promise that the display of the frame must be valid until we have
712 called the window-system-dependent frame destruction routine. */
713
714 /* I think this should be done with a hook. */
715 #ifdef HAVE_X_WINDOWS
716 if (FRAME_X_P (f))
717 x_destroy_window (f);
718 #endif
719
720 f->display.nothing = 0;
721
722 /* If we've deleted the last_nonminibuf_frame, then try to find
723 another one. */
724 if (f == last_nonminibuf_frame)
725 {
726 Lisp_Object frames;
727
728 last_nonminibuf_frame = 0;
729
730 for (frames = Vframe_list;
731 CONSP (frames);
732 frames = XCONS (frames)->cdr)
733 {
734 f = XFRAME (XCONS (frames)->car);
735 if (!FRAME_MINIBUF_ONLY_P (f))
736 {
737 last_nonminibuf_frame = f;
738 break;
739 }
740 }
741 }
742
743 /* If we've deleted Vdefault_minibuffer_frame, try to find another
744 one. Prefer minibuffer-only frames, but also notice frames
745 with other windows. */
746 if (EQ (frame, Vdefault_minibuffer_frame))
747 {
748 Lisp_Object frames;
749
750 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
751 Lisp_Object frame_with_minibuf = Qnil;
752
753 for (frames = Vframe_list;
754 CONSP (frames);
755 frames = XCONS (frames)->cdr)
756 {
757 Lisp_Object this = XCONS (frames)->car;
758
759 if (XTYPE (this) != Lisp_Frame)
760 abort ();
761 f = XFRAME (this);
762
763 if (FRAME_HAS_MINIBUF_P (f))
764 {
765 frame_with_minibuf = this;
766 if (FRAME_MINIBUF_ONLY_P (f))
767 break;
768 }
769 }
770
771 /* We know that there must be some frame with a minibuffer out
772 there. If this were not true, all of the frames present
773 would have to be minibufferless, which implies that at some
774 point their minibuffer frames must have been deleted, but
775 that is prohibited at the top; you can't delete surrogate
776 minibuffer frames. */
777 if (NILP (frame_with_minibuf))
778 abort ();
779
780 Vdefault_minibuffer_frame = frame_with_minibuf;
781 }
782
783 return Qnil;
784 }
785 \f
786 /* Return mouse position in character cell units. */
787
788 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
789 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
790 The position is given in character cells, where (0, 0) is the\n\
791 upper-left corner.\n\
792 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
793 to read the mouse position, it returns the selected frame for FRAME\n\
794 and nil for X and Y.")
795 ()
796 {
797 FRAME_PTR f;
798 Lisp_Object lispy_dummy;
799 enum scroll_bar_part party_dummy;
800 Lisp_Object x, y;
801 unsigned long long_dummy;
802
803 f = selected_frame;
804 x = y = Qnil;
805
806 /* It's okay for the hook to refrain from storing anything. */
807 if (mouse_position_hook)
808 (*mouse_position_hook) (&f,
809 &lispy_dummy, &party_dummy,
810 &x, &y,
811 &long_dummy);
812
813 XSET (lispy_dummy, Lisp_Frame, f);
814 return Fcons (lispy_dummy, Fcons (x, y));
815 }
816
817 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
818 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
819 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
820 (frame, x, y)
821 Lisp_Object frame, x, y;
822 {
823 CHECK_LIVE_FRAME (frame, 0);
824 CHECK_NUMBER (x, 2);
825 CHECK_NUMBER (y, 1);
826
827 /* I think this should be done with a hook. */
828 #ifdef HAVE_X_WINDOWS
829 if (FRAME_X_P (XFRAME (frame)))
830 /* Warping the mouse will cause enternotify and focus events. */
831 x_set_mouse_position (XFRAME (frame), x, y);
832 #endif
833
834 return Qnil;
835 }
836 \f
837 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
838 0, 1, "",
839 "Make the frame FRAME visible (assuming it is an X-window).\n\
840 Also raises the frame so that nothing obscures it.\n\
841 If omitted, FRAME defaults to the currently selected frame.")
842 (frame)
843 Lisp_Object frame;
844 {
845 if (NILP (frame))
846 XSET (frame, Lisp_Frame, selected_frame);
847
848 CHECK_LIVE_FRAME (frame, 0);
849
850 /* I think this should be done with a hook. */
851 #ifdef HAVE_X_WINDOWS
852 if (FRAME_X_P (XFRAME (frame)))
853 x_make_frame_visible (XFRAME (frame));
854 #endif
855
856 return frame;
857 }
858
859 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
860 0, 1, "",
861 "Make the frame FRAME invisible (assuming it is an X-window).\n\
862 If omitted, FRAME defaults to the currently selected frame.")
863 (frame)
864 Lisp_Object frame;
865 {
866 if (NILP (frame))
867 XSET (frame, Lisp_Frame, selected_frame);
868
869 CHECK_LIVE_FRAME (frame, 0);
870
871 /* Don't let the frame remain selected. */
872 if (XFRAME (frame) == selected_frame)
873 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
874
875 /* Don't allow minibuf_window to remain on a deleted frame. */
876 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
877 {
878 Fset_window_buffer (selected_frame->minibuffer_window,
879 XWINDOW (minibuf_window)->buffer);
880 minibuf_window = selected_frame->minibuffer_window;
881 }
882
883 /* I think this should be done with a hook. */
884 #ifdef HAVE_X_WINDOWS
885 if (FRAME_X_P (XFRAME (frame)))
886 x_make_frame_invisible (XFRAME (frame));
887 #endif
888
889 return Qnil;
890 }
891
892 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
893 0, 1, "",
894 "Make the frame FRAME into an icon.\n\
895 If omitted, FRAME defaults to the currently selected frame.")
896 (frame)
897 Lisp_Object frame;
898 {
899 if (NILP (frame))
900 XSET (frame, Lisp_Frame, selected_frame);
901
902 CHECK_LIVE_FRAME (frame, 0);
903
904 /* Don't let the frame remain selected. */
905 if (XFRAME (frame) == selected_frame)
906 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
907
908 /* Don't allow minibuf_window to remain on a deleted frame. */
909 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
910 {
911 Fset_window_buffer (selected_frame->minibuffer_window,
912 XWINDOW (minibuf_window)->buffer);
913 minibuf_window = selected_frame->minibuffer_window;
914 }
915
916 /* I think this should be done with a hook. */
917 #ifdef HAVE_X_WINDOWS
918 if (FRAME_X_P (XFRAME (frame)))
919 x_iconify_frame (XFRAME (frame));
920 #endif
921
922 return Qnil;
923 }
924
925 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
926 1, 1, 0,
927 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
928 A frame that is not \"visible\" is not updated and, if it works through\n\
929 a window system, it may not show at all.\n\
930 Return the symbol `icon' if frame is visible only as an icon.")
931 (frame)
932 Lisp_Object frame;
933 {
934 CHECK_LIVE_FRAME (frame, 0);
935
936 if (FRAME_VISIBLE_P (XFRAME (frame)))
937 return Qt;
938 if (FRAME_ICONIFIED_P (XFRAME (frame)))
939 return Qicon;
940 return Qnil;
941 }
942
943 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
944 0, 0, 0,
945 "Return a list of all frames now \"visible\" (being updated).")
946 ()
947 {
948 Lisp_Object tail, frame;
949 struct frame *f;
950 Lisp_Object value;
951
952 value = Qnil;
953 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
954 {
955 frame = XCONS (tail)->car;
956 if (XTYPE (frame) != Lisp_Frame)
957 continue;
958 f = XFRAME (frame);
959 if (FRAME_VISIBLE_P (f))
960 value = Fcons (frame, value);
961 }
962 return value;
963 }
964
965
966 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
967 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
968 If FRAME is invisible, make it visible.\n\
969 If Emacs is displaying on an ordinary terminal or some other device which\n\
970 doesn't support multiple overlapping frames, this function does nothing.")
971 (frame)
972 Lisp_Object frame;
973 {
974 CHECK_LIVE_FRAME (frame, 0);
975
976 if (frame_raise_lower_hook)
977 (*frame_raise_lower_hook) (XFRAME (frame), 1);
978
979 return Qnil;
980 }
981
982 /* Should we have a corresponding function called Flower_Power? */
983 DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
984 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
985 If Emacs is displaying on an ordinary terminal or some other device which\n\
986 doesn't support multiple overlapping frames, this function does nothing.")
987 (frame)
988 Lisp_Object frame;
989 {
990 CHECK_LIVE_FRAME (frame, 0);
991
992 if (frame_raise_lower_hook)
993 (*frame_raise_lower_hook) (XFRAME (frame), 0);
994
995 return Qnil;
996 }
997
998 \f
999 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1000 1, 2, 0,
1001 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1002 In other words, switch-frame events caused by events in FRAME will\n\
1003 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1004 FOCUS-FRAME after reading an event typed at FRAME.\n\
1005 \n\
1006 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1007 cancelled, and the frame again receives its own keystrokes.\n\
1008 \n\
1009 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1010 a surrogate minibuffer frame when a frame doesn't have its own\n\
1011 minibuffer window.\n\
1012 \n\
1013 A frame's focus redirection can be changed by select-frame. If frame\n\
1014 FOO is selected, and then a different frame BAR is selected, any\n\
1015 frames redirecting their focus to FOO are shifted to redirect their\n\
1016 focus to BAR. This allows focus redirection to work properly when the\n\
1017 user switches from one frame to another using `select-window'.\n\
1018 \n\
1019 This means that a frame whose focus is redirected to itself is treated\n\
1020 differently from a frame whose focus is redirected to nil; the former\n\
1021 is affected by select-frame, while the latter is not.\n\
1022 \n\
1023 The redirection lasts until `redirect-frame-focus' is called to change it.")
1024 (frame, focus_frame)
1025 Lisp_Object frame, focus_frame;
1026 {
1027 /* Note that we don't check for a live frame here. It's reasonable
1028 to redirect the focus of a frame you're about to delete, if you
1029 know what other frame should receive those keystrokes. */
1030 CHECK_FRAME (frame, 0);
1031
1032 if (! NILP (focus_frame))
1033 CHECK_LIVE_FRAME (focus_frame, 1);
1034
1035 XFRAME (frame)->focus_frame = focus_frame;
1036
1037 /* I think this should be done with a hook. */
1038 #ifdef HAVE_X_WINDOWS
1039 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1040 && FRAME_X_P (XFRAME (focus_frame)))
1041 Ffocus_frame (focus_frame);
1042 #endif
1043
1044 if (frame_rehighlight_hook)
1045 (*frame_rehighlight_hook) ();
1046
1047 return Qnil;
1048 }
1049
1050
1051 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1052 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1053 This returns nil if FRAME's focus is not redirected.\n\
1054 See `redirect-frame-focus'.")
1055 (frame)
1056 Lisp_Object frame;
1057 {
1058 CHECK_LIVE_FRAME (frame, 0);
1059
1060 return FRAME_FOCUS_FRAME (XFRAME (frame));
1061 }
1062
1063
1064 \f
1065 Lisp_Object
1066 get_frame_param (frame, prop)
1067 register struct frame *frame;
1068 Lisp_Object prop;
1069 {
1070 register Lisp_Object tem;
1071
1072 tem = Fassq (prop, frame->param_alist);
1073 if (EQ (tem, Qnil))
1074 return tem;
1075 return Fcdr (tem);
1076 }
1077
1078 void
1079 store_in_alist (alistptr, prop, val)
1080 Lisp_Object *alistptr, val;
1081 Lisp_Object prop;
1082 {
1083 register Lisp_Object tem;
1084
1085 tem = Fassq (prop, *alistptr);
1086 if (EQ (tem, Qnil))
1087 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1088 else
1089 Fsetcdr (tem, val);
1090 }
1091
1092 void
1093 store_frame_param (f, prop, val)
1094 struct frame *f;
1095 Lisp_Object prop, val;
1096 {
1097 register Lisp_Object tem;
1098
1099 tem = Fassq (prop, f->param_alist);
1100 if (EQ (tem, Qnil))
1101 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1102 else
1103 Fsetcdr (tem, val);
1104
1105 if (EQ (prop, Qminibuffer)
1106 && XTYPE (val) == Lisp_Window)
1107 {
1108 if (! MINI_WINDOW_P (XWINDOW (val)))
1109 error ("Surrogate minibuffer windows must be minibuffer windows.");
1110
1111 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1112 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1113
1114 /* Install the chosen minibuffer window, with proper buffer. */
1115 f->minibuffer_window = val;
1116 }
1117 }
1118
1119 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1120 "Return the parameters-alist of frame FRAME.\n\
1121 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1122 The meaningful PARMs depend on the kind of frame.\n\
1123 If FRAME is omitted, return information on the currently selected frame.")
1124 (frame)
1125 Lisp_Object frame;
1126 {
1127 Lisp_Object alist;
1128 struct frame *f;
1129
1130 if (EQ (frame, Qnil))
1131 f = selected_frame;
1132 else
1133 {
1134 CHECK_FRAME (frame, 0);
1135 f = XFRAME (frame);
1136 }
1137
1138 if (f->display.nothing == 0)
1139 return Qnil;
1140
1141 alist = Fcopy_alist (f->param_alist);
1142 store_in_alist (&alist, Qname, f->name);
1143 store_in_alist (&alist, Qheight, make_number (f->height));
1144 store_in_alist (&alist, Qwidth, make_number (f->width));
1145 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1146 store_in_alist (&alist, Qminibuffer,
1147 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1148 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1149 : FRAME_MINIBUF_WINDOW (f))));
1150 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1151 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
1152
1153 /* I think this should be done with a hook. */
1154 #ifdef HAVE_X_WINDOWS
1155 if (FRAME_X_P (f))
1156 x_report_frame_params (f, &alist);
1157 #endif
1158 return alist;
1159 }
1160
1161 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1162 Smodify_frame_parameters, 2, 2, 0,
1163 "Modify the parameters of frame FRAME according to ALIST.\n\
1164 ALIST is an alist of parameters to change and their new values.\n\
1165 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1166 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1167 (frame, alist)
1168 Lisp_Object frame, alist;
1169 {
1170 FRAME_PTR f;
1171 register Lisp_Object tail, elt, prop, val;
1172
1173 if (EQ (frame, Qnil))
1174 f = selected_frame;
1175 else
1176 {
1177 CHECK_LIVE_FRAME (frame, 0);
1178 f = XFRAME (frame);
1179 }
1180
1181 /* I think this should be done with a hook. */
1182 #ifdef HAVE_X_WINDOWS
1183 if (FRAME_X_P (f))
1184 #if 1
1185 x_set_frame_parameters (f, alist);
1186 #else
1187 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1188 {
1189 elt = Fcar (tail);
1190 prop = Fcar (elt);
1191 val = Fcdr (elt);
1192 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1193 store_frame_param (f, prop, val);
1194 }
1195 #endif
1196 #endif
1197
1198 return Qnil;
1199 }
1200 \f
1201 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1202 0, 1, 0,
1203 "Height in pixels of a line in the font in frame FRAME.\n\
1204 If FRAME is omitted, the selected frame is used.\n\
1205 For a terminal frame, the value is always 1.")
1206 (frame)
1207 Lisp_Object frame;
1208 {
1209 struct frame *f;
1210
1211 if (NILP (frame))
1212 f = selected_frame;
1213 else
1214 {
1215 CHECK_FRAME (frame, 0);
1216 f = XFRAME (frame);
1217 }
1218
1219 #ifdef HAVE_X_WINDOWS
1220 if (FRAME_X_P (f))
1221 return make_number (x_char_height (f));
1222 else
1223 #endif
1224 return make_number (1);
1225 }
1226
1227
1228 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1229 0, 1, 0,
1230 "Width in pixels of characters in the font in frame FRAME.\n\
1231 If FRAME is omitted, the selected frame is used.\n\
1232 The width is the same for all characters, because\n\
1233 currently Emacs supports only fixed-width fonts.\n\
1234 For a terminal screen, the value is always 1.")
1235 (frame)
1236 Lisp_Object frame;
1237 {
1238 struct frame *f;
1239
1240 if (NILP (frame))
1241 f = selected_frame;
1242 else
1243 {
1244 CHECK_FRAME (frame, 0);
1245 f = XFRAME (frame);
1246 }
1247
1248 #ifdef HAVE_X_WINDOWS
1249 if (FRAME_X_P (f))
1250 return make_number (x_char_width (f));
1251 else
1252 #endif
1253 return make_number (1);
1254 }
1255
1256 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1257 Sframe_pixel_height, 0, 1, 0,
1258 "Return a FRAME's height in pixels.\n\
1259 For a terminal frame, the result really gives the height in characters.\n\
1260 If FRAME is omitted, the selected frame is used.")
1261 (frame)
1262 Lisp_Object frame;
1263 {
1264 struct frame *f;
1265
1266 if (NILP (frame))
1267 f = selected_frame;
1268 else
1269 {
1270 CHECK_FRAME (frame, 0);
1271 f = XFRAME (frame);
1272 }
1273
1274 #ifdef HAVE_X_WINDOWS
1275 if (FRAME_X_P (f))
1276 return make_number (x_pixel_height (f));
1277 else
1278 #endif
1279 return make_number (FRAME_HEIGHT (f));
1280 }
1281
1282 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1283 Sframe_pixel_width, 0, 1, 0,
1284 "Return FRAME's width in pixels.\n\
1285 For a terminal frame, the result really gives the width in characters.\n\
1286 If FRAME is omitted, the selected frame is used.")
1287 (frame)
1288 Lisp_Object frame;
1289 {
1290 struct frame *f;
1291
1292 if (NILP (frame))
1293 f = selected_frame;
1294 else
1295 {
1296 CHECK_FRAME (frame, 0);
1297 f = XFRAME (frame);
1298 }
1299
1300 #ifdef HAVE_X_WINDOWS
1301 if (FRAME_X_P (f))
1302 return make_number (x_pixel_width (f));
1303 else
1304 #endif
1305 return make_number (FRAME_WIDTH (f));
1306 }
1307 \f
1308 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1309 "Specify that the frame FRAME has LINES lines.\n\
1310 Optional third arg non-nil means that redisplay should use LINES lines\n\
1311 but that the idea of the actual height of the frame should not be changed.")
1312 (frame, rows, pretend)
1313 Lisp_Object frame, rows, pretend;
1314 {
1315 register struct frame *f;
1316
1317 CHECK_NUMBER (rows, 0);
1318 if (NILP (frame))
1319 f = selected_frame;
1320 else
1321 {
1322 CHECK_LIVE_FRAME (frame, 0);
1323 f = XFRAME (frame);
1324 }
1325
1326 /* I think this should be done with a hook. */
1327 #ifdef HAVE_X_WINDOWS
1328 if (FRAME_X_P (f))
1329 {
1330 if (XINT (rows) != f->width)
1331 x_set_window_size (f, f->width, XINT (rows));
1332 }
1333 else
1334 #endif
1335 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1336 return Qnil;
1337 }
1338
1339 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1340 "Specify that the frame FRAME has COLS columns.\n\
1341 Optional third arg non-nil means that redisplay should use COLS columns\n\
1342 but that the idea of the actual width of the frame should not be changed.")
1343 (frame, cols, pretend)
1344 Lisp_Object frame, cols, pretend;
1345 {
1346 register struct frame *f;
1347 CHECK_NUMBER (cols, 0);
1348 if (NILP (frame))
1349 f = selected_frame;
1350 else
1351 {
1352 CHECK_LIVE_FRAME (frame, 0);
1353 f = XFRAME (frame);
1354 }
1355
1356 /* I think this should be done with a hook. */
1357 #ifdef HAVE_X_WINDOWS
1358 if (FRAME_X_P (f))
1359 {
1360 if (XINT (cols) != f->width)
1361 x_set_window_size (f, XINT (cols), f->height);
1362 }
1363 else
1364 #endif
1365 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1366 return Qnil;
1367 }
1368
1369 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1370 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1371 (frame, cols, rows)
1372 Lisp_Object frame, cols, rows;
1373 {
1374 register struct frame *f;
1375 int mask;
1376
1377 CHECK_LIVE_FRAME (frame, 0);
1378 CHECK_NUMBER (cols, 2);
1379 CHECK_NUMBER (rows, 1);
1380 f = XFRAME (frame);
1381
1382 /* I think this should be done with a hook. */
1383 #ifdef HAVE_X_WINDOWS
1384 if (FRAME_X_P (f))
1385 {
1386 if (XINT (rows) != f->height || XINT (cols) != f->width)
1387 x_set_window_size (f, XINT (cols), XINT (rows));
1388 }
1389 else
1390 #endif
1391 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1392
1393 return Qnil;
1394 }
1395
1396 DEFUN ("set-frame-position", Fset_frame_position,
1397 Sset_frame_position, 3, 3, 0,
1398 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1399 This is actually the position of the upper left corner of the frame.\n\
1400 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1401 the rightmost or bottommost possible position (that stays within the screen).")
1402 (frame, xoffset, yoffset)
1403 Lisp_Object frame, xoffset, yoffset;
1404 {
1405 register struct frame *f;
1406 int mask;
1407
1408 CHECK_LIVE_FRAME (frame, 0);
1409 CHECK_NUMBER (xoffset, 1);
1410 CHECK_NUMBER (yoffset, 2);
1411 f = XFRAME (frame);
1412
1413 /* I think this should be done with a hook. */
1414 #ifdef HAVE_X_WINDOWS
1415 if (FRAME_X_P (f))
1416 x_set_offset (f, XINT (xoffset), XINT (yoffset));
1417 #endif
1418
1419 return Qt;
1420 }
1421
1422 \f
1423 choose_minibuf_frame ()
1424 {
1425 /* For lowest-level minibuf, put it on currently selected frame
1426 if frame has a minibuffer. */
1427
1428 if (minibuf_level == 0
1429 && selected_frame != 0
1430 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1431 {
1432 /* I don't think that any frames may validly have a null minibuffer
1433 window anymore. */
1434 if (NILP (selected_frame->minibuffer_window))
1435 abort ();
1436
1437 Fset_window_buffer (selected_frame->minibuffer_window,
1438 XWINDOW (minibuf_window)->buffer);
1439 minibuf_window = selected_frame->minibuffer_window;
1440 }
1441 }
1442 \f
1443 syms_of_frame ()
1444 {
1445 /*&&& init symbols here &&&*/
1446 Qframep = intern ("framep");
1447 staticpro (&Qframep);
1448 Qframe_live_p = intern ("frame-live-p");
1449 staticpro (&Qframe_live_p);
1450 Qheight = intern ("height");
1451 staticpro (&Qheight);
1452 Qicon = intern ("icon");
1453 staticpro (&Qicon);
1454 Qminibuffer = intern ("minibuffer");
1455 staticpro (&Qminibuffer);
1456 Qmodeline = intern ("modeline");
1457 staticpro (&Qmodeline);
1458 Qname = intern ("name");
1459 staticpro (&Qname);
1460 Qonly = intern ("only");
1461 staticpro (&Qonly);
1462 Qunsplittable = intern ("unsplittable");
1463 staticpro (&Qunsplittable);
1464 Qwidth = intern ("width");
1465 staticpro (&Qwidth);
1466 Qx = intern ("x");
1467 staticpro (&Qx);
1468 Qmenu_bar_lines = intern ("menu-bar-lines");
1469 staticpro (&Qmenu_bar_lines);
1470
1471 staticpro (&Vframe_list);
1472
1473 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1474 "The initial frame-object, which represents Emacs's stdout.");
1475
1476 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1477 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1478 Vemacs_iconified = Qnil;
1479
1480 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1481 "Minibufferless frames use this frame's minibuffer.\n\
1482 \n\
1483 Emacs cannot create minibufferless frames unless this is set to an\n\
1484 appropriate surrogate.\n\
1485 \n\
1486 Emacs consults this variable only when creating minibufferless\n\
1487 frames; once the frame is created, it sticks with its assigned\n\
1488 minibuffer, no matter what this variable is set to. This means that\n\
1489 this variable doesn't necessarily say anything meaningful about the\n\
1490 current set of frames, or where the minibuffer is currently being\n\
1491 displayed.");
1492 Vdefault_minibuffer_frame = Qnil;
1493
1494 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1495 "Alist of default values for frame creation.\n\
1496 These may be set in your init file, like this:\n\
1497 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1498 These override values given in window system configuration data, like\n\
1499 X Windows' defaults database.\n\
1500 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1501 For values specific to the separate minibuffer frame, see\n\
1502 `minibuffer-frame-alist'.");
1503 Vdefault_frame_alist = Qnil;
1504
1505 defsubr (&Sframep);
1506 defsubr (&Sframe_live_p);
1507 defsubr (&Shandle_switch_frame);
1508 defsubr (&Sselect_frame);
1509 defsubr (&Sselected_frame);
1510 defsubr (&Swindow_frame);
1511 defsubr (&Sframe_root_window);
1512 defsubr (&Sframe_selected_window);
1513 defsubr (&Sframe_list);
1514 defsubr (&Snext_frame);
1515 defsubr (&Sprevious_frame);
1516 defsubr (&Sdelete_frame);
1517 defsubr (&Smouse_position);
1518 defsubr (&Sset_mouse_position);
1519 #if 0
1520 defsubr (&Sframe_configuration);
1521 defsubr (&Srestore_frame_configuration);
1522 #endif
1523 defsubr (&Smake_frame_visible);
1524 defsubr (&Smake_frame_invisible);
1525 defsubr (&Siconify_frame);
1526 defsubr (&Sframe_visible_p);
1527 defsubr (&Svisible_frame_list);
1528 defsubr (&Sraise_frame);
1529 defsubr (&Slower_frame);
1530 defsubr (&Sredirect_frame_focus);
1531 defsubr (&Sframe_focus);
1532 defsubr (&Sframe_parameters);
1533 defsubr (&Smodify_frame_parameters);
1534 defsubr (&Sframe_char_height);
1535 defsubr (&Sframe_char_width);
1536 defsubr (&Sframe_pixel_height);
1537 defsubr (&Sframe_pixel_width);
1538 defsubr (&Sset_frame_height);
1539 defsubr (&Sset_frame_width);
1540 defsubr (&Sset_frame_size);
1541 defsubr (&Sset_frame_position);
1542 }
1543
1544 keys_of_frame ()
1545 {
1546 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
1547 }
1548 \f
1549 #else /* not MULTI_FRAME */
1550
1551 /* If we're not using multi-frame stuff, we still need to provide some
1552 support functions. */
1553
1554 /* Unless this function is defined, providing set-frame-height and
1555 set-frame-width doesn't help compatibility any, since they both
1556 want this as their first argument. */
1557 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1558 "Return the frame that is now selected.")
1559 ()
1560 {
1561 Lisp_Object tem;
1562 XFASTINT (tem) = 0;
1563 return tem;
1564 }
1565 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1566 "Return non-nil if OBJECT is a frame.\n\
1567 Value is t for a termcap frame (a character-only terminal),\n\
1568 `x' for an Emacs frame that is really an X window.\n\
1569 Also see `live-frame-p'.")
1570 (object)
1571 Lisp_Object object;
1572 {
1573 return Qnil;
1574 }
1575
1576 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1577 "Specify that the frame FRAME has LINES lines.\n\
1578 Optional third arg non-nil means that redisplay should use LINES lines\n\
1579 but that the idea of the actual height of the frame should not be changed.")
1580 (frame, rows, pretend)
1581 Lisp_Object frame, rows, pretend;
1582 {
1583 CHECK_NUMBER (rows, 0);
1584
1585 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1586 return Qnil;
1587 }
1588
1589 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1590 "Specify that the frame FRAME has COLS columns.\n\
1591 Optional third arg non-nil means that redisplay should use COLS columns\n\
1592 but that the idea of the actual width of the frame should not be changed.")
1593 (frame, cols, pretend)
1594 Lisp_Object frame, cols, pretend;
1595 {
1596 CHECK_NUMBER (cols, 0);
1597
1598 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1599 return Qnil;
1600 }
1601
1602 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1603 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1604 (frame, cols, rows)
1605 Lisp_Object frame, cols, rows;
1606 {
1607 CHECK_NUMBER (cols, 2);
1608 CHECK_NUMBER (rows, 1);
1609
1610 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1611
1612 return Qnil;
1613 }
1614
1615 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1616 "Return number of lines available for display on FRAME.\n\
1617 If FRAME is omitted, describe the currently selected frame.")
1618 (frame)
1619 Lisp_Object frame;
1620 {
1621 return make_number (FRAME_HEIGHT (selected_frame));
1622 }
1623
1624 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1625 "Return number of columns available for display on FRAME.\n\
1626 If FRAME is omitted, describe the currently selected frame.")
1627 (frame)
1628 Lisp_Object frame;
1629 {
1630 return make_number (FRAME_WIDTH (selected_frame));
1631 }
1632
1633 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1634 0, 1, 0,
1635 "Height in pixels of a line in the font in frame FRAME.\n\
1636 If FRAME is omitted, the selected frame is used.\n\
1637 For a terminal frame, the value is always 1.")
1638 (frame)
1639 Lisp_Object frame;
1640 {
1641 return make_number (1);
1642 }
1643
1644
1645 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1646 0, 1, 0,
1647 "Width in pixels of characters in the font in frame FRAME.\n\
1648 If FRAME is omitted, the selected frame is used.\n\
1649 The width is the same for all characters, because\n\
1650 currently Emacs supports only fixed-width fonts.\n\
1651 For a terminal screen, the value is always 1.")
1652 (frame)
1653 Lisp_Object frame;
1654 {
1655 return make_number (1);
1656 }
1657
1658 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1659 Sframe_pixel_height, 0, 1, 0,
1660 "Return FRAME's height in pixels.\n\
1661 For a terminal frame, the result really gives the height in characters.\n\
1662 If FRAME is omitted, the selected frame is used.")
1663 (frame)
1664 Lisp_Object frame;
1665 {
1666 return make_number (FRAME_HEIGHT (f));
1667 }
1668
1669 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1670 Sframe_pixel_width, 0, 1, 0,
1671 "Return FRAME's width in pixels.\n\
1672 For a terminal frame, the result really gives the width in characters.\n\
1673 If FRAME is omitted, the selected frame is used.")
1674 (frame)
1675 Lisp_Object frame;
1676 {
1677 return make_number (FRAME_WIDTH (f));
1678 }
1679
1680 /* These are for backward compatibility with Emacs 18. */
1681
1682 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1683 "Tell redisplay that the screen has LINES lines.\n\
1684 Optional second arg non-nil means that redisplay should use LINES lines\n\
1685 but that the idea of the actual height of the screen should not be changed.")
1686 (lines, pretend)
1687 Lisp_Object lines, pretend;
1688 {
1689 CHECK_NUMBER (lines, 0);
1690
1691 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1692 return Qnil;
1693 }
1694
1695 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1696 "Tell redisplay that the screen has COLS columns.\n\
1697 Optional second arg non-nil means that redisplay should use COLS columns\n\
1698 but that the idea of the actual width of the screen should not be changed.")
1699 (cols, pretend)
1700 Lisp_Object cols, pretend;
1701 {
1702 CHECK_NUMBER (cols, 0);
1703
1704 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1705 return Qnil;
1706 }
1707
1708 syms_of_frame ()
1709 {
1710 defsubr (&Sselected_frame);
1711 defsubr (&Sframep);
1712 defsubr (&Sframe_char_height);
1713 defsubr (&Sframe_char_width);
1714 defsubr (&Sframe_pixel_height);
1715 defsubr (&Sframe_pixel_width);
1716 defsubr (&Sset_frame_height);
1717 defsubr (&Sset_frame_width);
1718 defsubr (&Sset_frame_size);
1719 defsubr (&Sset_screen_height);
1720 defsubr (&Sset_screen_width);
1721 defsubr (&Sframe_height);
1722 Ffset (intern ("screen-height"), intern ("frame-height"));
1723 defsubr (&Sframe_width);
1724 Ffset (intern ("screen-width"), intern ("frame-width"));
1725 }
1726
1727 keys_of_frame ()
1728 {
1729 }
1730
1731 #endif /* not MULTI_FRAME */
1732
1733
1734
1735