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