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