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