* keyboard.c (Qscrollbar_movement, Qvertical_scrollbar,
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1989, 1992 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 Qlive_frame_p;
78 Lisp_Object Qheight;
79 Lisp_Object Qicon;
80 Lisp_Object Qminibuffer;
81 Lisp_Object Qmodeline;
82 Lisp_Object Qname;
83 Lisp_Object Qnone;
84 Lisp_Object Qonly;
85 Lisp_Object Qunsplittable;
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 ("live-frame-p", Flive_frame_p, Slive_frame_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_scrollbars = 0;
162 f->has_vertical_scrollbars = 0;
163
164 f->param_alist = Qnil;
165
166 root_window = make_window ();
167 if (mini_p)
168 {
169 mini_window = make_window ();
170 XWINDOW (root_window)->next = mini_window;
171 XWINDOW (mini_window)->prev = root_window;
172 XWINDOW (mini_window)->mini_p = Qt;
173 XWINDOW (mini_window)->frame = frame;
174 f->minibuffer_window = mini_window;
175 }
176 else
177 {
178 mini_window = Qnil;
179 XWINDOW (root_window)->next = Qnil;
180 f->minibuffer_window = Qnil;
181 }
182
183 XWINDOW (root_window)->frame = frame;
184
185 /* 10 is arbitrary,
186 just so that there is "something there."
187 Correct size will be set up later with change_frame_size. */
188
189 f->width = 10;
190 f->height = 10;
191
192 XFASTINT (XWINDOW (root_window)->width) = 10;
193 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
194
195 if (mini_p)
196 {
197 XFASTINT (XWINDOW (mini_window)->width) = 10;
198 XFASTINT (XWINDOW (mini_window)->top) = 9;
199 XFASTINT (XWINDOW (mini_window)->height) = 1;
200 }
201
202 /* Choose a buffer for the frame's root window. */
203 {
204 Lisp_Object buf;
205
206 XWINDOW (root_window)->buffer = Qt;
207 buf = Fcurrent_buffer ();
208 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
209 a space), try to find another one. */
210 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
211 buf = Fother_buffer (buf, Qnil);
212 Fset_window_buffer (root_window, buf);
213 }
214
215 if (mini_p)
216 {
217 XWINDOW (mini_window)->buffer = Qt;
218 Fset_window_buffer (mini_window,
219 (NILP (Vminibuffer_list)
220 ? get_minibuffer (0)
221 : Fcar (Vminibuffer_list)));
222 }
223
224 f->root_window = root_window;
225 f->selected_window = root_window;
226 /* Make sure this window seems more recently used than
227 a newly-created, never-selected window. */
228 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
229
230 Vframe_list = Fcons (frame, Vframe_list);
231
232 return f;
233 }
234 \f
235 /* Make a frame using a separate minibuffer window on another frame.
236 MINI_WINDOW is the minibuffer window to use. nil means use the
237 default (the global minibuffer). */
238
239 struct frame *
240 make_frame_without_minibuffer (mini_window)
241 register Lisp_Object mini_window;
242 {
243 register struct frame *f;
244
245 /* Choose the minibuffer window to use. */
246 if (NILP (mini_window))
247 {
248 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
249 error ("default-minibuffer-frame must be set when creating minibufferless frames");
250 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
251 error ("default-minibuffer-frame must be a live frame");
252 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
253 }
254 else
255 {
256 CHECK_LIVE_WINDOW (mini_window, 0);
257 }
258
259 /* Make a frame containing just a root window. */
260 f = make_frame (0);
261
262 /* Install the chosen minibuffer window, with proper buffer. */
263 f->minibuffer_window = mini_window;
264 Fset_window_buffer (mini_window,
265 (NILP (Vminibuffer_list)
266 ? get_minibuffer (0)
267 : Fcar (Vminibuffer_list)));
268 return f;
269 }
270
271 /* Make a frame containing only a minibuffer window. */
272
273 struct frame *
274 make_minibuffer_frame ()
275 {
276 /* First make a frame containing just a root window, no minibuffer. */
277
278 register struct frame *f = make_frame (0);
279 register Lisp_Object mini_window;
280 register Lisp_Object frame;
281
282 XSET (frame, Lisp_Frame, f);
283
284 f->auto_raise = 0;
285 f->auto_lower = 0;
286 f->no_split = 1;
287 f->wants_modeline = 0;
288 f->has_minibuffer = 1;
289
290 /* Now label the root window as also being the minibuffer.
291 Avoid infinite looping on the window chain by marking next pointer
292 as nil. */
293
294 mini_window = f->minibuffer_window = f->root_window;
295 XWINDOW (mini_window)->mini_p = Qt;
296 XWINDOW (mini_window)->next = Qnil;
297 XWINDOW (mini_window)->prev = Qnil;
298 XWINDOW (mini_window)->frame = frame;
299
300 /* Put the proper buffer in that window. */
301
302 Fset_window_buffer (mini_window,
303 (NILP (Vminibuffer_list)
304 ? get_minibuffer (0)
305 : Fcar (Vminibuffer_list)));
306 return f;
307 }
308 \f
309 /* Construct a frame that refers to the terminal (stdin and stdout). */
310
311 struct frame *
312 make_terminal_frame ()
313 {
314 register struct frame *f;
315
316 Vframe_list = Qnil;
317 f = make_frame (1);
318 f->name = build_string ("terminal");
319 FRAME_SET_VISIBLE (f, 1);
320 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
321 XSET (Vterminal_frame, Lisp_Frame, f);
322 return f;
323 }
324 \f
325 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
326 "Select the frame FRAME. FRAME's selected window becomes \"the\"\n\
327 selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
328 focus on that frame.\n\
329 \n\
330 This function is interactive, and may be bound to the ``switch-frame''\n\
331 event; when invoked this way, it switches to the frame named in the\n\
332 event. When called from lisp, FRAME may be a ``switch-frame'' event;\n\
333 if it is, select the frame named in the event.\n\
334 \n\
335 Changing the selected frame can change focus redirections. See\n\
336 `redirect-frame-focus' for details.")
337 (frame, no_enter)
338 Lisp_Object frame, no_enter;
339 {
340 /* If FRAME is a switch-frame event, extract the frame we should
341 switch to. */
342 if (CONSP (frame)
343 && EQ (XCONS (frame)->car, Qswitch_frame)
344 && CONSP (XCONS (frame)->cdr))
345 frame = XCONS (XCONS (frame)->cdr)->car;
346
347 CHECK_LIVE_FRAME (frame, 0);
348
349 if (selected_frame == XFRAME (frame))
350 return frame;
351
352 /* If a frame's focus has been redirected toward the currently
353 selected frame, we should change the redirection to point to the
354 newly selected frame. This means that if the focus is redirected
355 from a minibufferless frame to a surrogate minibuffer frame, we
356 can use `other-window' to switch between all the frames using
357 that minibuffer frame, and the focus redirection will follow us
358 around. */
359 {
360 Lisp_Object tail;
361
362 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
363 {
364 Lisp_Object focus;
365
366 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
367 abort ();
368
369 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
370
371 if (XTYPE (focus) == Lisp_Frame
372 && XFRAME (focus) == selected_frame)
373 Fredirect_frame_focus (XCONS (tail)->car, frame);
374 }
375 }
376
377 selected_frame = XFRAME (frame);
378 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
379 last_nonminibuf_frame = selected_frame;
380
381 Fselect_window (XFRAME (frame)->selected_window);
382
383 #ifdef HAVE_X_WINDOWS
384 #ifdef MULTI_FRAME
385 if (FRAME_X_P (XFRAME (frame))
386 && NILP (no_enter))
387 {
388 Ffocus_frame (frame);
389 }
390 #endif
391 #endif
392 choose_minibuf_frame ();
393
394 return frame;
395 }
396
397 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
398 "Return the frame that is now selected.")
399 ()
400 {
401 Lisp_Object tem;
402 XSET (tem, Lisp_Frame, selected_frame);
403 return tem;
404 }
405
406 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
407 "Return the frame object that window WINDOW is on.")
408 (window)
409 Lisp_Object window;
410 {
411 CHECK_LIVE_WINDOW (window, 0);
412 return XWINDOW (window)->frame;
413 }
414
415 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
416 "Returns the root-window of FRAME.\n\
417 If omitted, FRAME defaults to the currently selected frame.")
418 (frame)
419 Lisp_Object frame;
420 {
421 if (NILP (frame))
422 XSET (frame, Lisp_Frame, selected_frame);
423 else
424 CHECK_LIVE_FRAME (frame, 0);
425
426 return XFRAME (frame)->root_window;
427 }
428
429 DEFUN ("frame-selected-window", Fframe_selected_window,
430 Sframe_selected_window, 0, 1, 0,
431 "Return the selected window of frame object 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)->selected_window;
442 }
443
444 DEFUN ("frame-list", Fframe_list, Sframe_list,
445 0, 0, 0,
446 "Return a list of all frames.")
447 ()
448 {
449 return Fcopy_sequence (Vframe_list);
450 }
451
452 #ifdef MULTI_FRAME
453
454 /* Return the next frame in the frame list after FRAME.
455 If MINIBUF is nil, exclude minibuffer-only frames.
456 If MINIBUF is a window, include only frames using that window for
457 their minibuffer.
458 If MINIBUF is non-nil, and not a window, include all frames. */
459 Lisp_Object
460 next_frame (frame, minibuf)
461 Lisp_Object frame;
462 Lisp_Object minibuf;
463 {
464 Lisp_Object tail;
465 int passed = 0;
466
467 /* There must always be at least one frame in Vframe_list. */
468 if (! CONSP (Vframe_list))
469 abort ();
470
471 while (1)
472 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
473 {
474 Lisp_Object f = XCONS (tail)->car;
475
476 if (passed)
477 {
478 /* Decide whether this frame is eligible to be returned. */
479
480 /* If we've looped all the way around without finding any
481 eligible frames, return the original frame. */
482 if (EQ (f, frame))
483 return f;
484
485 /* Let minibuf decide if this frame is acceptable. */
486 if (NILP (minibuf))
487 {
488 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
489 return f;
490 }
491 else if (XTYPE (minibuf) == Lisp_Window)
492 {
493 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
494 return f;
495 }
496 else
497 return f;
498 }
499
500 if (EQ (frame, f))
501 passed++;
502 }
503 }
504
505 #if 0
506 /* Nobody seems to be using this code right now. */
507
508 /* Return the previous frame in the frame list before FRAME.
509 If MINIBUF is nil, exclude minibuffer-only frames.
510 If MINIBUF is a window, include only frames using that window for
511 their minibuffer.
512 If MINIBUF is non-nil and not a window, include all frames. */
513 Lisp_Object
514 prev_frame (frame, minibuf)
515 Lisp_Object frame;
516 Lisp_Object minibuf;
517 {
518 Lisp_Object tail;
519 Lisp_Object prev;
520
521 /* There must always be at least one frame in Vframe_list. */
522 if (! CONSP (Vframe_list))
523 abort ();
524
525 prev = Qnil;
526 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
527 {
528 Lisp_Object f = XCONS (tail)->car;
529
530 if (XTYPE (f) != Lisp_Frame)
531 abort ();
532
533 if (EQ (frame, f) && !NILP (prev))
534 return prev;
535
536 /* Decide whether this frame is eligible to be returned,
537 according to minibuf. */
538 if (NILP (minibuf))
539 {
540 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
541 prev = f;
542 }
543 else if (XTYPE (minibuf) == Lisp_Window)
544 {
545 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
546 prev = f;
547 }
548 else
549 prev = f;
550 }
551
552 /* We've scanned the entire list. */
553 if (NILP (prev))
554 /* We went through the whole frame list without finding a single
555 acceptable frame. Return the original frame. */
556 return frame;
557 else
558 /* There were no acceptable frames in the list before FRAME; otherwise,
559 we would have returned directly from the loop. Since PREV is the last
560 acceptable frame in the list, return it. */
561 return prev;
562 }
563 #endif
564
565 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
566 "Return the next frame in the frame list after FRAME.\n\
567 By default, skip minibuffer-only frames.\n\
568 If omitted, FRAME defaults to the selected frame.\n\
569 If optional argument MINIFRAME is non-nil, include minibuffer-only frames.\n\
570 If MINIFRAME is a window, include only frames using that window for their\n\
571 minibuffer.\n\
572 If MINIFRAME is non-nil and not a window, include all frames.")
573 (frame, miniframe)
574 Lisp_Object frame, miniframe;
575 {
576 Lisp_Object tail;
577
578 if (NILP (frame))
579 XSET (frame, Lisp_Frame, selected_frame);
580 else
581 CHECK_LIVE_FRAME (frame, 0);
582
583 return next_frame (frame, miniframe);
584 }
585 #endif /* MULTI_FRAME */
586 \f
587 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
588 "Delete FRAME, permanently eliminating it from use.\n\
589 If omitted, FRAME defaults to the selected frame.\n\
590 A frame may not be deleted if its minibuffer is used by other frames.")
591 (frame)
592 Lisp_Object frame;
593 {
594 struct frame *f;
595 union display displ;
596
597 if (EQ (frame, Qnil))
598 {
599 f = selected_frame;
600 XSET (frame, Lisp_Frame, f);
601 }
602 else
603 {
604 CHECK_FRAME (frame, 0);
605 f = XFRAME (frame);
606 }
607
608 if (! FRAME_LIVE_P (f))
609 return;
610
611 /* Are there any other frames besides this one? */
612 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
613 error ("Attempt to delete the only frame");
614
615 /* Does this frame have a minibuffer, and is it the surrogate
616 minibuffer for any other frame? */
617 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
618 {
619 Lisp_Object frames;
620
621 for (frames = Vframe_list;
622 CONSP (frames);
623 frames = XCONS (frames)->cdr)
624 {
625 Lisp_Object this = XCONS (frames)->car;
626
627 if (! EQ (this, frame)
628 && EQ (frame,
629 (WINDOW_FRAME
630 (XWINDOW
631 (FRAME_MINIBUF_WINDOW
632 (XFRAME (this)))))))
633 error ("Attempt to delete a surrogate minibuffer frame");
634 }
635 }
636
637 /* Don't let the frame remain selected. */
638 if (f == selected_frame)
639 Fselect_frame (next_frame (frame, Qt), Qnil);
640
641 /* Don't allow minibuf_window to remain on a deleted frame. */
642 if (EQ (f->minibuffer_window, minibuf_window))
643 {
644 Fset_window_buffer (selected_frame->minibuffer_window,
645 XWINDOW (minibuf_window)->buffer);
646 minibuf_window = selected_frame->minibuffer_window;
647 }
648
649 /* Mark all the windows that used to be on FRAME as deleted, and then
650 remove the reference to them. */
651 delete_all_subwindows (XWINDOW (f->root_window));
652 f->root_window = Qnil;
653
654 Vframe_list = Fdelq (frame, Vframe_list);
655 FRAME_SET_VISIBLE (f, 0);
656 displ = f->display;
657 f->display.nothing = 0;
658
659 #ifdef HAVE_X_WINDOWS
660 if (FRAME_X_P (f))
661 x_destroy_window (f, displ);
662 #endif
663
664 /* If we've deleted the last_nonminibuf_frame, then try to find
665 another one. */
666 if (f == last_nonminibuf_frame)
667 {
668 Lisp_Object frames;
669
670 last_nonminibuf_frame = 0;
671
672 for (frames = Vframe_list;
673 CONSP (frames);
674 frames = XCONS (frames)->cdr)
675 {
676 f = XFRAME (XCONS (frames)->car);
677 if (!FRAME_MINIBUF_ONLY_P (f))
678 {
679 last_nonminibuf_frame = f;
680 break;
681 }
682 }
683 }
684
685 /* If we've deleted Vdefault_minibuffer_frame, try to find another
686 one. Prefer minibuffer-only frames, but also notice frames
687 with other windows. */
688 if (EQ (frame, Vdefault_minibuffer_frame))
689 {
690 Lisp_Object frames;
691
692 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
693 Lisp_Object frame_with_minibuf = Qnil;
694
695 for (frames = Vframe_list;
696 CONSP (frames);
697 frames = XCONS (frames)->cdr)
698 {
699 Lisp_Object this = XCONS (frames)->car;
700
701 if (XTYPE (this) != Lisp_Frame)
702 abort ();
703 f = XFRAME (this);
704
705 if (FRAME_HAS_MINIBUF_P (f))
706 {
707 frame_with_minibuf = this;
708 if (FRAME_MINIBUF_ONLY_P (f))
709 break;
710 }
711 }
712
713 /* We know that there must be some frame with a minibuffer out
714 there. If this were not true, all of the frames present
715 would have to be minibufferless, which implies that at some
716 point their minibuffer frames must have been deleted, but
717 that is prohibited at the top; you can't delete surrogate
718 minibuffer frames. */
719 if (NILP (frame_with_minibuf))
720 abort ();
721
722 Vdefault_minibuffer_frame = frame_with_minibuf;
723 }
724
725 return Qnil;
726 }
727 \f
728 /* Return mouse position in character cell units. */
729
730 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
731 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
732 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
733 to read the mouse position, it returns the selected frame for FRAME\n\
734 and nil for X and Y.")
735 ()
736 {
737 Lisp_Object x, y, dummy;
738 FRAME_PTR f;
739
740 if (mouse_position_hook)
741 (*mouse_position_hook) (&f, &x, &y, &dummy);
742 else
743 {
744 f = selected_frame;
745 x = y = Qnil;
746 }
747
748 XSET (dummy, Lisp_Frame, f);
749 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
750 }
751
752 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
753 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
754 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
755 (frame, x, y)
756 Lisp_Object frame, x, y;
757 {
758 CHECK_LIVE_FRAME (frame, 0);
759 CHECK_NUMBER (x, 2);
760 CHECK_NUMBER (y, 1);
761
762 #ifdef HAVE_X_WINDOWS
763 if (FRAME_X_P (XFRAME (frame)))
764 /* Warping the mouse will cause enternotify and focus events. */
765 x_set_mouse_position (XFRAME (frame), x, y);
766 #endif
767
768 return Qnil;
769 }
770 \f
771 #if 0
772 /* ??? Can this be replaced with a Lisp function?
773 It is used in minibuf.c. Can we get rid of that?
774 Yes. All uses in minibuf.c are gone, and parallels to these
775 functions have been defined in frame.el. */
776
777 DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
778 0, 0, 0,
779 "Return object describing current frame configuration.\n\
780 The frame configuration is the current mouse position and selected frame.\n\
781 This object can be given to `restore-frame-configuration'\n\
782 to restore this frame configuration.")
783 ()
784 {
785 Lisp_Object c, time;
786
787 c = Fmake_vector (make_number(4), Qnil);
788 XVECTOR (c)->contents[0] = Fselected_frame();
789 if (mouse_position_hook)
790 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
791 &XVECTOR (c)->contents[2],
792 &XVECTOR (c)->contents[3],
793 &time);
794 return c;
795 }
796
797 DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
798 Srestore_frame_configuration,
799 1, 1, 0,
800 "Restores frame configuration CONFIGURATION.")
801 (config)
802 Lisp_Object config;
803 {
804 Lisp_Object x_pos, y_pos, frame;
805
806 CHECK_VECTOR (config, 0);
807 if (XVECTOR (config)->size != 3)
808 {
809 error ("Wrong size vector passed to restore-frame-configuration");
810 }
811 frame = XVECTOR (config)->contents[0];
812 CHECK_LIVE_FRAME (frame, 0);
813
814 Fselect_frame (frame, Qnil);
815
816 #if 0
817 /* This seems to interfere with the frame selection mechanism. jla */
818 x_pos = XVECTOR (config)->contents[2];
819 y_pos = XVECTOR (config)->contents[3];
820 set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
821 #endif
822
823 return frame;
824 }
825 #endif
826 \f
827 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
828 0, 1, 0,
829 "Make the frame FRAME visible (assuming it is an X-window).\n\
830 Also raises the frame so that nothing obscures it.\n\
831 If omitted, FRAME defaults to the currently selected frame.")
832 (frame)
833 Lisp_Object frame;
834 {
835 if (NILP (frame))
836 XSET (frame, Lisp_Frame, selected_frame);
837
838 CHECK_LIVE_FRAME (frame, 0);
839
840 #ifdef HAVE_X_WINDOWS
841 if (FRAME_X_P (XFRAME (frame)))
842 x_make_frame_visible (XFRAME (frame));
843 #endif
844
845 return frame;
846 }
847
848 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
849 0, 1, "",
850 "Make the frame FRAME invisible (assuming it is an X-window).\n\
851 If omitted, FRAME defaults to the currently selected frame.")
852 (frame)
853 Lisp_Object frame;
854 {
855 if (NILP (frame))
856 XSET (frame, Lisp_Frame, selected_frame);
857
858 CHECK_LIVE_FRAME (frame, 0);
859
860 #ifdef HAVE_X_WINDOWS
861 if (FRAME_X_P (XFRAME (frame)))
862 x_make_frame_invisible (XFRAME (frame));
863 #endif
864
865 return Qnil;
866 }
867
868 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
869 0, 1, "",
870 "Make the frame FRAME into an icon.\n\
871 If omitted, FRAME defaults to the currently selected frame.")
872 (frame)
873 Lisp_Object frame;
874 {
875 if (NILP (frame))
876 XSET (frame, Lisp_Frame, selected_frame);
877
878 CHECK_LIVE_FRAME (frame, 0);
879
880 #ifdef HAVE_X_WINDOWS
881 if (FRAME_X_P (XFRAME (frame)))
882 x_iconify_frame (XFRAME (frame));
883 #endif
884
885 return Qnil;
886 }
887
888 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
889 1, 1, 0,
890 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
891 A frame that is not \"visible\" is not updated and, if it works through\n\
892 a window system, it may not show at all.\n\
893 Return the symbol `icon' if frame is visible only as an icon.")
894 (frame)
895 Lisp_Object frame;
896 {
897 CHECK_LIVE_FRAME (frame, 0);
898
899 if (FRAME_VISIBLE_P (XFRAME (frame)))
900 return Qt;
901 if (FRAME_ICONIFIED_P (XFRAME (frame)))
902 return Qicon;
903 return Qnil;
904 }
905
906 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
907 0, 0, 0,
908 "Return a list of all frames now \"visible\" (being updated).")
909 ()
910 {
911 Lisp_Object tail, frame;
912 struct frame *f;
913 Lisp_Object value;
914
915 value = Qnil;
916 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
917 {
918 frame = XCONS (tail)->car;
919 if (XTYPE (frame) != Lisp_Frame)
920 continue;
921 f = XFRAME (frame);
922 if (FRAME_VISIBLE_P (f))
923 value = Fcons (frame, value);
924 }
925 return value;
926 }
927
928
929 \f
930 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
931 1, 2, 0,
932 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
933 In other words, switch-frame events caused by events in FRAME will\n\
934 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
935 FOCUS-FRAME after reading an event typed at FRAME.\n\
936 \n\
937 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
938 cancelled, and the frame again receives its own keystrokes.\n\
939 \n\
940 Focus redirection is useful for temporarily redirecting keystrokes to\n\
941 a surrogate minibuffer frame when a frame doesn't have its own\n\
942 minibuffer window.\n\
943 \n\
944 A frame's focus redirection can be changed by select-frame. If frame\n\
945 FOO is selected, and then a different frame BAR is selected, any\n\
946 frames redirecting their focus to FOO are shifted to redirect their\n\
947 focus to BAR. This allows focus redirection to work properly when the\n\
948 user switches from one frame to another using `select-window'.\n\
949 \n\
950 This means that a frame whose focus is redirected to itself is treated\n\
951 differently from a frame whose focus is redirected to nil; the former\n\
952 is affected by select-frame, while the latter is not.\n\
953 \n\
954 The redirection lasts until `redirect-frame-focus' is called to change it.")
955 (frame, focus_frame)
956 Lisp_Object frame, focus_frame;
957 {
958 CHECK_LIVE_FRAME (frame, 0);
959
960 if (! NILP (focus_frame))
961 CHECK_LIVE_FRAME (focus_frame, 1);
962
963 XFRAME (frame)->focus_frame = focus_frame;
964
965 if (frame_rehighlight_hook)
966 (*frame_rehighlight_hook) ();
967
968 return Qnil;
969 }
970
971
972 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
973 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
974 This returns nil if FRAME's focus is not redirected.\n\
975 See `redirect-frame-focus'.")
976 (frame)
977 Lisp_Object frame;
978 {
979 CHECK_LIVE_FRAME (frame, 0);
980
981 return FRAME_FOCUS_FRAME (XFRAME (frame));
982 }
983
984
985 \f
986 Lisp_Object
987 get_frame_param (frame, prop)
988 register struct frame *frame;
989 Lisp_Object prop;
990 {
991 register Lisp_Object tem;
992
993 tem = Fassq (prop, frame->param_alist);
994 if (EQ (tem, Qnil))
995 return tem;
996 return Fcdr (tem);
997 }
998
999 void
1000 store_in_alist (alistptr, prop, val)
1001 Lisp_Object *alistptr, val;
1002 Lisp_Object prop;
1003 {
1004 register Lisp_Object tem;
1005
1006 tem = Fassq (prop, *alistptr);
1007 if (EQ (tem, Qnil))
1008 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1009 else
1010 Fsetcdr (tem, val);
1011 }
1012
1013 void
1014 store_frame_param (f, prop, val)
1015 struct frame *f;
1016 Lisp_Object prop, val;
1017 {
1018 register Lisp_Object tem;
1019
1020 tem = Fassq (prop, f->param_alist);
1021 if (EQ (tem, Qnil))
1022 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1023 else
1024 Fsetcdr (tem, val);
1025
1026 if (EQ (prop, Qminibuffer)
1027 && XTYPE (val) == Lisp_Window)
1028 {
1029 if (! MINI_WINDOW_P (XWINDOW (val)))
1030 error ("Surrogate minibuffer windows must be minibuffer windows.");
1031
1032 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1033 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
1034
1035 /* Install the chosen minibuffer window, with proper buffer. */
1036 f->minibuffer_window = val;
1037 }
1038 }
1039
1040 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1041 "Return the parameters-alist of frame FRAME.\n\
1042 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1043 The meaningful PARMs depend on the kind of frame.\n\
1044 If FRAME is omitted, return information on the currently selected frame.")
1045 (frame)
1046 Lisp_Object frame;
1047 {
1048 Lisp_Object alist;
1049 struct frame *f;
1050
1051 if (EQ (frame, Qnil))
1052 f = selected_frame;
1053 else
1054 {
1055 CHECK_FRAME (frame, 0);
1056 f = XFRAME (frame);
1057 }
1058
1059 if (f->display.nothing == 0)
1060 return Qnil;
1061
1062 alist = Fcopy_alist (f->param_alist);
1063 store_in_alist (&alist, Qname, f->name);
1064 store_in_alist (&alist, Qheight, make_number (f->height));
1065 store_in_alist (&alist, Qwidth, make_number (f->width));
1066 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1067 store_in_alist (&alist, Qminibuffer,
1068 (! FRAME_HAS_MINIBUF_P (f) ? Qnone
1069 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1070 : FRAME_MINIBUF_WINDOW (f))));
1071 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1072
1073 #ifdef HAVE_X_WINDOWS
1074 if (FRAME_X_P (f))
1075 x_report_frame_params (f, &alist);
1076 #endif
1077 return alist;
1078 }
1079
1080 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1081 Smodify_frame_parameters, 2, 2, 0,
1082 "Modify the parameters of frame FRAME according to ALIST.\n\
1083 ALIST is an alist of parameters to change and their new values.\n\
1084 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1085 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1086 (frame, alist)
1087 Lisp_Object frame, alist;
1088 {
1089 FRAME_PTR f;
1090 register Lisp_Object tail, elt, prop, val;
1091
1092 if (EQ (frame, Qnil))
1093 f = selected_frame;
1094 else
1095 {
1096 CHECK_LIVE_FRAME (frame, 0);
1097 f = XFRAME (frame);
1098 }
1099
1100 #ifdef HAVE_X_WINDOWS
1101 if (FRAME_X_P (f))
1102 #if 1
1103 x_set_frame_parameters (f, alist);
1104 #else
1105 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1106 {
1107 elt = Fcar (tail);
1108 prop = Fcar (elt);
1109 val = Fcdr (elt);
1110 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1111 store_frame_param (f, prop, val);
1112 }
1113 #endif
1114 #endif
1115
1116 return Qnil;
1117 }
1118 \f
1119
1120 #if 0
1121 /* This function isn't useful enough by itself to include; we need to
1122 add functions to allow the user to find the size of a font before
1123 this is actually useful. */
1124
1125 DEFUN ("frame-pixel-size", Fframe_pixel_size,
1126 Sframe_pixel_size, 1, 1, 0,
1127 "Return a cons (width . height) of FRAME's size in pixels.")
1128 (frame)
1129 Lisp_Object frame;
1130 {
1131 register struct frame *f;
1132 int width, height;
1133
1134 CHECK_LIVE_FRAME (frame, 0);
1135 f = XFRAME (frame);
1136
1137 return Fcons (make_number (x_pixel_width (f)),
1138 make_number (x_pixel_height (f)));
1139 }
1140 #endif
1141
1142 #if 0
1143 /* These functions have no C callers, and can be written nicely in lisp. */
1144
1145 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1146 "Return number of lines available for display on selected frame.")
1147 ()
1148 {
1149 return make_number (FRAME_HEIGHT (selected_frame));
1150 }
1151
1152 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1153 "Return number of columns available for display on selected frame.")
1154 ()
1155 {
1156 return make_number (FRAME_WIDTH (selected_frame));
1157 }
1158 #endif
1159
1160 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1161 "Specify that the frame FRAME has LINES lines.\n\
1162 Optional third arg non-nil means that redisplay should use LINES lines\n\
1163 but that the idea of the actual height of the frame should not be changed.")
1164 (frame, rows, pretend)
1165 Lisp_Object frame, rows, pretend;
1166 {
1167 register struct frame *f;
1168
1169 CHECK_NUMBER (rows, 0);
1170 if (NILP (frame))
1171 f = selected_frame;
1172 else
1173 {
1174 CHECK_LIVE_FRAME (frame, 0);
1175 f = XFRAME (frame);
1176 }
1177
1178 #ifdef HAVE_X_WINDOWS
1179 if (FRAME_X_P (f))
1180 {
1181 if (XINT (rows) != f->width)
1182 x_set_window_size (f, f->width, XINT (rows));
1183 }
1184 else
1185 #endif
1186 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1187 return Qnil;
1188 }
1189
1190 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1191 "Specify that the frame FRAME has COLS columns.\n\
1192 Optional third arg non-nil means that redisplay should use COLS columns\n\
1193 but that the idea of the actual width of the frame should not be changed.")
1194 (frame, cols, pretend)
1195 Lisp_Object frame, cols, pretend;
1196 {
1197 register struct frame *f;
1198 CHECK_NUMBER (cols, 0);
1199 if (NILP (frame))
1200 f = selected_frame;
1201 else
1202 {
1203 CHECK_LIVE_FRAME (frame, 0);
1204 f = XFRAME (frame);
1205 }
1206
1207 #ifdef HAVE_X_WINDOWS
1208 if (FRAME_X_P (f))
1209 {
1210 if (XINT (cols) != f->width)
1211 x_set_window_size (f, XINT (cols), f->height);
1212 }
1213 else
1214 #endif
1215 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1216 return Qnil;
1217 }
1218
1219 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1220 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1221 (frame, cols, rows)
1222 Lisp_Object frame, cols, rows;
1223 {
1224 register struct frame *f;
1225 int mask;
1226
1227 CHECK_LIVE_FRAME (frame, 0);
1228 CHECK_NUMBER (cols, 2);
1229 CHECK_NUMBER (rows, 1);
1230 f = XFRAME (frame);
1231
1232 #ifdef HAVE_X_WINDOWS
1233 if (FRAME_X_P (f))
1234 {
1235 if (XINT (rows) != f->height || XINT (cols) != f->width)
1236 x_set_window_size (f, XINT (cols), XINT (rows));
1237 }
1238 else
1239 #endif
1240 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1241
1242 return Qnil;
1243 }
1244
1245 DEFUN ("set-frame-position", Fset_frame_position,
1246 Sset_frame_position, 3, 3, 0,
1247 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1248 If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1249 the leftmost or bottommost position FRAME could occupy without going\n\
1250 off the screen.")
1251 (frame, xoffset, yoffset)
1252 Lisp_Object frame, xoffset, yoffset;
1253 {
1254 register struct frame *f;
1255 int mask;
1256
1257 CHECK_LIVE_FRAME (frame, 0);
1258 CHECK_NUMBER (xoffset, 1);
1259 CHECK_NUMBER (yoffset, 2);
1260 f = XFRAME (frame);
1261
1262 #ifdef HAVE_X_WINDOWS
1263 if (FRAME_X_P (f))
1264 x_set_offset (f, XINT (xoffset), XINT (yoffset));
1265 #endif
1266
1267 return Qt;
1268 }
1269
1270 \f
1271 #ifndef HAVE_X11
1272 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1273 3, 3, "",
1274 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1275 Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
1276 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1277 specify defaults for some sizes/positions. If GEO specifies everything,\n\
1278 the mouse is not used.\n\
1279 Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1280 (frame, name, geo)
1281 Lisp_Object frame;
1282 Lisp_Object name;
1283 Lisp_Object geo;
1284 {
1285 int vals[4];
1286 Lisp_Object nums[4];
1287 int i;
1288
1289 CHECK_FRAME (frame, 0);
1290 CHECK_STRING (name, 1);
1291 CHECK_STRING (geo, 2);
1292
1293 switch (XFRAME (frame)->output_method)
1294 {
1295 case output_x_window:
1296 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
1297 XSTRING (geo)->data, XSTRING (name)->data);
1298 break;
1299
1300 default:
1301 return Qnil;
1302 }
1303
1304 for (i = 0; i < 4; i++)
1305 XFASTINT (nums[i]) = vals[i];
1306 return Fcons (frame, Flist (4, nums));
1307 return Qnil;
1308 }
1309 #endif /* not HAVE_X11 */
1310 \f
1311 choose_minibuf_frame ()
1312 {
1313 /* For lowest-level minibuf, put it on currently selected frame
1314 if frame has a minibuffer. */
1315
1316 if (minibuf_level == 0
1317 && selected_frame != 0
1318 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1319 {
1320 /* I don't think that any frames may validly have a null minibuffer
1321 window anymore. */
1322 if (NILP (selected_frame->minibuffer_window))
1323 abort ();
1324
1325 Fset_window_buffer (selected_frame->minibuffer_window,
1326 XWINDOW (minibuf_window)->buffer);
1327 minibuf_window = selected_frame->minibuffer_window;
1328 }
1329 }
1330 \f
1331 syms_of_frame ()
1332 {
1333 /*&&& init symbols here &&&*/
1334 Qframep = intern ("framep");
1335 staticpro (&Qframep);
1336 Qlive_frame_p = intern ("live-frame-p");
1337 staticpro (&Qlive_frame_p);
1338 Qheight = intern ("height");
1339 staticpro (&Qheight);
1340 Qicon = intern ("icon");
1341 staticpro (&Qicon);
1342 Qminibuffer = intern ("minibuffer");
1343 staticpro (&Qminibuffer);
1344 Qmodeline = intern ("modeline");
1345 staticpro (&Qmodeline);
1346 Qname = intern ("name");
1347 staticpro (&Qname);
1348 Qnone = intern ("none");
1349 staticpro (&Qnone);
1350 Qonly = intern ("only");
1351 staticpro (&Qonly);
1352 Qunsplittable = intern ("unsplittable");
1353 staticpro (&Qunsplittable);
1354 Qwidth = intern ("width");
1355 staticpro (&Qwidth);
1356 Qx = intern ("x");
1357 staticpro (&Qx);
1358
1359 staticpro (&Vframe_list);
1360
1361 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1362 "The initial frame-object, which represents Emacs's stdout.");
1363
1364 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1365 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1366 Vemacs_iconified = Qnil;
1367
1368 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1369 "Minibufferless frames use this frame's minibuffer.\n\
1370 \n\
1371 Emacs cannot create minibufferless frames unless this is set to an\n\
1372 appropriate surrogate.\n\
1373 \n\
1374 Emacs consults this variable only when creating minibufferless\n\
1375 frames; once the frame is created, it sticks with its assigned\n\
1376 minibuffer, no matter what this variable is set to. This means that\n\
1377 this variable doesn't necessarily say anything meaningful about the\n\
1378 current set of frames, or where the minibuffer is currently being\n\
1379 displayed.");
1380 Vdefault_minibuffer_frame = Qnil;
1381
1382 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1383 "Alist of default values for frame creation.\n\
1384 These may be set in your init file, like this:\n\
1385 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1386 These override values given in window system configuration data, like\n\
1387 X Windows' defaults database.\n\
1388 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1389 For values specific to the separate minibuffer frame, see\n\
1390 `minibuffer-frame-alist'.");
1391 Vdefault_frame_alist = Qnil;
1392
1393 defsubr (&Sframep);
1394 defsubr (&Slive_frame_p);
1395 defsubr (&Sselect_frame);
1396 defsubr (&Sselected_frame);
1397 defsubr (&Swindow_frame);
1398 defsubr (&Sframe_root_window);
1399 defsubr (&Sframe_selected_window);
1400 defsubr (&Sframe_list);
1401 defsubr (&Snext_frame);
1402 defsubr (&Sdelete_frame);
1403 defsubr (&Smouse_position);
1404 defsubr (&Sset_mouse_position);
1405 #if 0
1406 defsubr (&Sframe_configuration);
1407 defsubr (&Srestore_frame_configuration);
1408 #endif
1409 defsubr (&Smake_frame_visible);
1410 defsubr (&Smake_frame_invisible);
1411 defsubr (&Siconify_frame);
1412 defsubr (&Sframe_visible_p);
1413 defsubr (&Svisible_frame_list);
1414 defsubr (&Sredirect_frame_focus);
1415 defsubr (&Sframe_focus);
1416 defsubr (&Sframe_parameters);
1417 defsubr (&Smodify_frame_parameters);
1418 #if 0
1419 defsubr (&Sframe_pixel_size);
1420 defsubr (&Sframe_height);
1421 defsubr (&Sframe_width);
1422 #endif
1423 defsubr (&Sset_frame_height);
1424 defsubr (&Sset_frame_width);
1425 defsubr (&Sset_frame_size);
1426 defsubr (&Sset_frame_position);
1427 #ifndef HAVE_X11
1428 defsubr (&Srubber_band_rectangle);
1429 #endif /* HAVE_X11 */
1430 }
1431
1432 keys_of_frame ()
1433 {
1434 initial_define_lispy_key (global_map, "switch-frame", "select-frame");
1435 }
1436
1437 #else /* not MULTI_FRAME */
1438
1439 /* If we're not using multi-frame stuff, we still need to provide some
1440 support functions. */
1441
1442 /* Unless this function is defined, providing set-frame-height and
1443 set-frame-width doesn't help compatibility any, since they both
1444 want this as their first argument. */
1445 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1446 "Return the frame that is now selected.")
1447 ()
1448 {
1449 Lisp_Object tem;
1450 XFASTINT (tem) = 0;
1451 return tem;
1452 }
1453
1454 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1455 "Specify that the frame FRAME has LINES lines.\n\
1456 Optional third arg non-nil means that redisplay should use LINES lines\n\
1457 but that the idea of the actual height of the frame should not be changed.")
1458 (frame, rows, pretend)
1459 Lisp_Object frame, rows, pretend;
1460 {
1461 CHECK_NUMBER (rows, 0);
1462
1463 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1464 return Qnil;
1465 }
1466
1467 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1468 "Specify that the frame FRAME has COLS columns.\n\
1469 Optional third arg non-nil means that redisplay should use COLS columns\n\
1470 but that the idea of the actual width of the frame should not be changed.")
1471 (frame, cols, pretend)
1472 Lisp_Object frame, cols, pretend;
1473 {
1474 CHECK_NUMBER (cols, 0);
1475
1476 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1477 return Qnil;
1478 }
1479
1480 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1481 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1482 (frame, cols, rows)
1483 Lisp_Object frame, cols, rows;
1484 {
1485 CHECK_NUMBER (cols, 2);
1486 CHECK_NUMBER (rows, 1);
1487
1488 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1489
1490 return Qnil;
1491 }
1492
1493 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1494 "Return number of lines available for display on selected frame.")
1495 ()
1496 {
1497 return make_number (FRAME_HEIGHT (selected_frame));
1498 }
1499
1500 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1501 "Return number of columns available for display on selected frame.")
1502 ()
1503 {
1504 return make_number (FRAME_WIDTH (selected_frame));
1505 }
1506
1507 /* These are for backward compatibility with Emacs 18. */
1508
1509 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1510 "Tell redisplay that the screen has LINES lines.\n\
1511 Optional second arg non-nil means that redisplay should use LINES lines\n\
1512 but that the idea of the actual height of the screen should not be changed.")
1513 (lines, pretend)
1514 Lisp_Object lines, pretend;
1515 {
1516 CHECK_NUMBER (lines, 0);
1517
1518 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1519 return Qnil;
1520 }
1521
1522 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1523 "Tell redisplay that the screen has COLS columns.\n\
1524 Optional second arg non-nil means that redisplay should use COLS columns\n\
1525 but that the idea of the actual width of the screen should not be changed.")
1526 (cols, pretend)
1527 Lisp_Object cols, pretend;
1528 {
1529 CHECK_NUMBER (cols, 0);
1530
1531 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1532 return Qnil;
1533 }
1534
1535 syms_of_frame ()
1536 {
1537 defsubr (&Sset_frame_height);
1538 defsubr (&Sset_frame_width);
1539 defsubr (&Sset_frame_size);
1540 defsubr (&Sset_screen_height);
1541 defsubr (&Sset_screen_width);
1542 defsubr (&Sframe_height);
1543 Ffset (intern ("screen-height"), intern ("frame-height"));
1544 defsubr (&Sframe_width);
1545 Ffset (intern ("screen-width"), intern ("frame-width"));
1546 }
1547
1548 keys_of_frame ()
1549 {
1550 }
1551
1552 #endif /* not MULTI_FRAME */
1553
1554
1555
1556