(Fset_frame_height): Compare against height, not width.
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994 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 <config.h>
21
22 #include <stdio.h>
23 #include "lisp.h"
24 #include "frame.h"
25 #include "termhooks.h"
26 #include "window.h"
27 #ifdef MSDOS
28 #include "msdos.h"
29 #endif
30
31 #ifdef MULTI_FRAME
32
33 #include "buffer.h"
34
35 /* These help us bind and responding to switch-frame events. */
36 #include "commands.h"
37 #include "keyboard.h"
38
39 Lisp_Object Vemacs_iconified;
40 Lisp_Object Vframe_list;
41 Lisp_Object Vterminal_frame;
42 Lisp_Object Vdefault_minibuffer_frame;
43 Lisp_Object Vdefault_frame_alist;
44
45 /* Evaluate this expression to rebuild the section of syms_of_frame
46 that initializes and staticpros the symbols declared below. Note
47 that Emacs 18 has a bug that keeps C-x C-e from being able to
48 evaluate this expression.
49
50 (progn
51 ;; Accumulate a list of the symbols we want to initialize from the
52 ;; declarations at the top of the file.
53 (goto-char (point-min))
54 (search-forward "/\*&&& symbols declared here &&&*\/\n")
55 (let (symbol-list)
56 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
57 (setq symbol-list
58 (cons (buffer-substring (match-beginning 1) (match-end 1))
59 symbol-list))
60 (forward-line 1))
61 (setq symbol-list (nreverse symbol-list))
62 ;; Delete the section of syms_of_... where we initialize the symbols.
63 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
64 (let ((start (point)))
65 (while (looking-at "^ Q")
66 (forward-line 2))
67 (kill-region start (point)))
68 ;; Write a new symbol initialization section.
69 (while symbol-list
70 (insert (format " %s = intern (\"" (car symbol-list)))
71 (let ((start (point)))
72 (insert (substring (car symbol-list) 1))
73 (subst-char-in-region start (point) ?_ ?-))
74 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
75 (setq symbol-list (cdr symbol-list)))))
76 */
77
78 /*&&& symbols declared here &&&*/
79 Lisp_Object Qframep;
80 Lisp_Object Qframe_live_p;
81 Lisp_Object Qheight;
82 Lisp_Object Qicon;
83 Lisp_Object Qminibuffer;
84 Lisp_Object Qmodeline;
85 Lisp_Object Qname;
86 Lisp_Object Qonly;
87 Lisp_Object Qunsplittable;
88 Lisp_Object Qmenu_bar_lines;
89 Lisp_Object Qwidth;
90 Lisp_Object Qx;
91 Lisp_Object Qvisible;
92
93 extern Lisp_Object Vminibuffer_list;
94 extern Lisp_Object get_minibuffer ();
95 extern Lisp_Object Fhandle_switch_frame ();
96 extern Lisp_Object Fredirect_frame_focus ();
97 \f
98 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
99 "Return non-nil if OBJECT is a frame.\n\
100 Value is t for a termcap frame (a character-only terminal),\n\
101 `x' for an Emacs frame that is really an X window,\n\
102 `pc' for a direct-write MS-DOS frame.\n\
103 Also see `live-frame-p'.")
104 (object)
105 Lisp_Object object;
106 {
107 if (!FRAMEP (object))
108 return Qnil;
109 switch (XFRAME (object)->output_method)
110 {
111 case output_termcap:
112 return Qt;
113 case output_x_window:
114 return Qx;
115 /* The `pc' case is in the Fframep below. */
116 default:
117 abort ();
118 }
119 }
120
121 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
122 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
123 Value is nil if OBJECT is not a live frame. If object is a live\n\
124 frame, the return value indicates what sort of output device it is\n\
125 displayed on. Value is t for a termcap frame (a character-only\n\
126 terminal), `x' for an Emacs frame being displayed in an X window.")
127 (object)
128 Lisp_Object object;
129 {
130 return ((FRAMEP (object)
131 && FRAME_LIVE_P (XFRAME (object)))
132 ? Fframep (object)
133 : Qnil);
134 }
135
136 struct frame *
137 make_frame (mini_p)
138 int mini_p;
139 {
140 Lisp_Object frame;
141 register struct frame *f;
142 register Lisp_Object root_window;
143 register Lisp_Object mini_window;
144
145 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
146 - sizeof (Lisp_Object)))
147 / sizeof (Lisp_Object)),
148 make_number (0));
149 XSETTYPE (frame, Lisp_Frame);
150 f = XFRAME (frame);
151
152 f->cursor_x = 0;
153 f->cursor_y = 0;
154 f->current_glyphs = 0;
155 f->desired_glyphs = 0;
156 f->visible = 0;
157 f->async_visible = 0;
158 f->display.nothing = 0;
159 f->iconified = 0;
160 f->async_iconified = 0;
161 f->wants_modeline = 1;
162 f->auto_raise = 0;
163 f->auto_lower = 0;
164 f->no_split = 0;
165 f->garbaged = 0;
166 f->has_minibuffer = mini_p;
167 f->focus_frame = Qnil;
168 f->explicit_name = 0;
169 f->can_have_scroll_bars = 0;
170 f->has_vertical_scroll_bars = 0;
171 f->param_alist = Qnil;
172 f->scroll_bars = Qnil;
173 f->condemned_scroll_bars = Qnil;
174 f->face_alist = Qnil;
175 f->menu_bar_items = Qnil;
176 f->menu_bar_vector = Qnil;
177 f->menu_bar_items_used = 0;
178
179 root_window = make_window ();
180 if (mini_p)
181 {
182 mini_window = make_window ();
183 XWINDOW (root_window)->next = mini_window;
184 XWINDOW (mini_window)->prev = root_window;
185 XWINDOW (mini_window)->mini_p = Qt;
186 XWINDOW (mini_window)->frame = frame;
187 f->minibuffer_window = mini_window;
188 }
189 else
190 {
191 mini_window = Qnil;
192 XWINDOW (root_window)->next = Qnil;
193 f->minibuffer_window = Qnil;
194 }
195
196 XWINDOW (root_window)->frame = frame;
197
198 /* 10 is arbitrary,
199 just so that there is "something there."
200 Correct size will be set up later with change_frame_size. */
201
202 f->width = 10;
203 f->height = 10;
204
205 XSETFASTINT (XWINDOW (root_window)->width, 10);
206 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
207
208 if (mini_p)
209 {
210 XSETFASTINT (XWINDOW (mini_window)->width, 10);
211 XSETFASTINT (XWINDOW (mini_window)->top, 9);
212 XSETFASTINT (XWINDOW (mini_window)->height, 1);
213 }
214
215 /* Choose a buffer for the frame's root window. */
216 {
217 Lisp_Object buf;
218
219 XWINDOW (root_window)->buffer = Qt;
220 buf = Fcurrent_buffer ();
221 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
222 a space), try to find another one. */
223 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
224 buf = Fother_buffer (buf, Qnil);
225 Fset_window_buffer (root_window, buf);
226 }
227
228 if (mini_p)
229 {
230 XWINDOW (mini_window)->buffer = Qt;
231 Fset_window_buffer (mini_window,
232 (NILP (Vminibuffer_list)
233 ? get_minibuffer (0)
234 : Fcar (Vminibuffer_list)));
235 }
236
237 f->root_window = root_window;
238 f->selected_window = root_window;
239 /* Make sure this window seems more recently used than
240 a newly-created, never-selected window. */
241 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
242
243 return f;
244 }
245 \f
246 /* Make a frame using a separate minibuffer window on another frame.
247 MINI_WINDOW is the minibuffer window to use. nil means use the
248 default (the global minibuffer). */
249
250 struct frame *
251 make_frame_without_minibuffer (mini_window)
252 register Lisp_Object mini_window;
253 {
254 register struct frame *f;
255
256 /* Choose the minibuffer window to use. */
257 if (NILP (mini_window))
258 {
259 if (!FRAMEP (Vdefault_minibuffer_frame))
260 error ("default-minibuffer-frame must be set when creating minibufferless frames");
261 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
262 error ("default-minibuffer-frame must be a live frame");
263 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
264 }
265 else
266 {
267 CHECK_LIVE_WINDOW (mini_window, 0);
268 }
269
270 /* Make a frame containing just a root window. */
271 f = make_frame (0);
272
273 /* Install the chosen minibuffer window, with proper buffer. */
274 f->minibuffer_window = mini_window;
275 Fset_window_buffer (mini_window,
276 (NILP (Vminibuffer_list)
277 ? get_minibuffer (0)
278 : Fcar (Vminibuffer_list)));
279 return f;
280 }
281
282 /* Make a frame containing only a minibuffer window. */
283
284 struct frame *
285 make_minibuffer_frame ()
286 {
287 /* First make a frame containing just a root window, no minibuffer. */
288
289 register struct frame *f = make_frame (0);
290 register Lisp_Object mini_window;
291 register Lisp_Object frame;
292
293 XSETFRAME (frame, f);
294
295 f->auto_raise = 0;
296 f->auto_lower = 0;
297 f->no_split = 1;
298 f->wants_modeline = 0;
299 f->has_minibuffer = 1;
300
301 /* Now label the root window as also being the minibuffer.
302 Avoid infinite looping on the window chain by marking next pointer
303 as nil. */
304
305 mini_window = f->minibuffer_window = f->root_window;
306 XWINDOW (mini_window)->mini_p = Qt;
307 XWINDOW (mini_window)->next = Qnil;
308 XWINDOW (mini_window)->prev = Qnil;
309 XWINDOW (mini_window)->frame = frame;
310
311 /* Put the proper buffer in that window. */
312
313 Fset_window_buffer (mini_window,
314 (NILP (Vminibuffer_list)
315 ? get_minibuffer (0)
316 : Fcar (Vminibuffer_list)));
317 return f;
318 }
319 \f
320 /* Construct a frame that refers to the terminal (stdin and stdout). */
321
322 struct frame *
323 make_terminal_frame ()
324 {
325 register struct frame *f;
326 Lisp_Object frame;
327
328 Vframe_list = Qnil;
329 f = make_frame (1);
330
331 XSETFRAME (frame, f);
332 Vframe_list = Fcons (frame, Vframe_list);
333
334 f->name = build_string ("terminal");
335 FRAME_SET_VISIBLE (f, 1);
336 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
337 XSETFRAME (Vterminal_frame, f);
338 return f;
339 }
340 \f
341 static Lisp_Object
342 do_switch_frame (frame, no_enter, track)
343 Lisp_Object frame, no_enter;
344 int track;
345 {
346 /* If FRAME is a switch-frame event, extract the frame we should
347 switch to. */
348 if (CONSP (frame)
349 && EQ (XCONS (frame)->car, Qswitch_frame)
350 && CONSP (XCONS (frame)->cdr))
351 frame = XCONS (XCONS (frame)->cdr)->car;
352
353 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
354 a switch-frame event to arrive after a frame is no longer live,
355 especially when deleting the initial frame during startup. */
356 CHECK_FRAME (frame, 0);
357 if (! FRAME_LIVE_P (XFRAME (frame)))
358 return Qnil;
359
360 if (selected_frame == XFRAME (frame))
361 return frame;
362
363 /* This is too greedy; it causes inappropriate focus redirection
364 that's hard to get rid of. */
365 #if 0
366 /* If a frame's focus has been redirected toward the currently
367 selected frame, we should change the redirection to point to the
368 newly selected frame. This means that if the focus is redirected
369 from a minibufferless frame to a surrogate minibuffer frame, we
370 can use `other-window' to switch between all the frames using
371 that minibuffer frame, and the focus redirection will follow us
372 around. */
373 if (track)
374 {
375 Lisp_Object tail;
376
377 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
378 {
379 Lisp_Object focus;
380
381 if (!FRAMEP (XCONS (tail)->car))
382 abort ();
383
384 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
385
386 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
387 Fredirect_frame_focus (XCONS (tail)->car, frame);
388 }
389 }
390 #else /* ! 0 */
391 /* Instead, apply it only to the frame we're pointing to. */
392 #ifdef HAVE_X_WINDOWS
393 if (track)
394 {
395 Lisp_Object focus, xfocus;
396
397 xfocus = x_get_focus_frame ();
398 if (FRAMEP (xfocus))
399 {
400 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
401 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
402 Fredirect_frame_focus (xfocus, frame);
403 }
404 }
405 #endif /* HAVE_X_WINDOWS */
406 #endif /* ! 0 */
407
408 selected_frame = XFRAME (frame);
409 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
410 last_nonminibuf_frame = selected_frame;
411
412 Fselect_window (XFRAME (frame)->selected_window);
413 choose_minibuf_frame ();
414
415 /* We want to make sure that the next event generates a frame-switch
416 event to the appropriate frame. This seems kludgy to me, but
417 before you take it out, make sure that evaluating something like
418 (select-window (frame-root-window (new-frame))) doesn't end up
419 with your typing being interpreted in the new frame instead of
420 the one you're actually typing in. */
421 internal_last_event_frame = Qnil;
422
423 return frame;
424 }
425
426 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
427 "Select the frame FRAME.\n\
428 Subsequent editing commands apply to its selected window.\n\
429 The selection of FRAME lasts until the next time the user does\n\
430 something to select a different frame, or until the next time this\n\
431 function is called.")
432 (frame, no_enter)
433 Lisp_Object frame, no_enter;
434 {
435 return do_switch_frame (frame, no_enter, 1);
436 }
437
438
439 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
440 "Handle a switch-frame event EVENT.\n\
441 Switch-frame events are usually bound to this function.\n\
442 A switch-frame event tells Emacs that the window manager has requested\n\
443 that the user's events be directed to the frame mentioned in the event.\n\
444 This function selects the selected window of the frame of EVENT.\n\
445 \n\
446 If EVENT is frame object, handle it as if it were a switch-frame event\n\
447 to that frame.")
448 (frame, no_enter)
449 Lisp_Object frame, no_enter;
450 {
451 return do_switch_frame (frame, no_enter, 0);
452 }
453
454
455 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
456 "Return the frame that is now selected.")
457 ()
458 {
459 Lisp_Object tem;
460 XSETFRAME (tem, selected_frame);
461 return tem;
462 }
463 \f
464 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
465 "Return the frame object that window WINDOW is on.")
466 (window)
467 Lisp_Object window;
468 {
469 CHECK_LIVE_WINDOW (window, 0);
470 return XWINDOW (window)->frame;
471 }
472
473 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
474 "Returns the topmost, leftmost window of FRAME.\n\
475 If omitted, FRAME defaults to the currently selected frame.")
476 (frame)
477 Lisp_Object frame;
478 {
479 Lisp_Object w;
480
481 if (NILP (frame))
482 w = selected_frame->root_window;
483 else
484 {
485 CHECK_LIVE_FRAME (frame, 0);
486 w = XFRAME (frame)->root_window;
487 }
488 while (NILP (XWINDOW (w)->buffer))
489 {
490 if (! NILP (XWINDOW (w)->hchild))
491 w = XWINDOW (w)->hchild;
492 else if (! NILP (XWINDOW (w)->vchild))
493 w = XWINDOW (w)->vchild;
494 else
495 abort ();
496 }
497 return w;
498 }
499
500 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
501 "Returns the root-window of FRAME.\n\
502 If omitted, FRAME defaults to the currently selected frame.")
503 (frame)
504 Lisp_Object frame;
505 {
506 if (NILP (frame))
507 XSETFRAME (frame, selected_frame);
508 else
509 CHECK_LIVE_FRAME (frame, 0);
510
511 return XFRAME (frame)->root_window;
512 }
513
514 DEFUN ("frame-selected-window", Fframe_selected_window,
515 Sframe_selected_window, 0, 1, 0,
516 "Return the selected window of frame object FRAME.\n\
517 If omitted, FRAME defaults to the currently selected frame.")
518 (frame)
519 Lisp_Object frame;
520 {
521 if (NILP (frame))
522 XSETFRAME (frame, selected_frame);
523 else
524 CHECK_LIVE_FRAME (frame, 0);
525
526 return XFRAME (frame)->selected_window;
527 }
528
529 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
530 Sset_frame_selected_window, 2, 2, 0,
531 "Set the selected window of frame object FRAME to WINDOW.\n\
532 If FRAME is nil, the selected frame is used.\n\
533 If FRAME is the selected frame, this makes WINDOW the selected window.")
534 (frame, window)
535 Lisp_Object frame, window;
536 {
537 if (NILP (frame))
538 XSETFRAME (frame, selected_frame);
539 else
540 CHECK_LIVE_FRAME (frame, 0);
541
542 CHECK_LIVE_WINDOW (window, 1);
543
544 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
545 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
546
547 if (XFRAME (frame) == selected_frame)
548 return Fselect_window (window);
549
550 return XFRAME (frame)->selected_window = window;
551 }
552 \f
553 DEFUN ("frame-list", Fframe_list, Sframe_list,
554 0, 0, 0,
555 "Return a list of all frames.")
556 ()
557 {
558 return Fcopy_sequence (Vframe_list);
559 }
560
561 /* Return the next frame in the frame list after FRAME.
562 If MINIBUF is nil, exclude minibuffer-only frames.
563 If MINIBUF is a window, include only its own frame
564 and any frame now using that window as the minibuffer.
565 If MINIBUF is `visible', include all visible frames.
566 If MINIBUF is 0, include all visible and iconified frames.
567 Otherwise, include all frames. */
568
569 Lisp_Object
570 next_frame (frame, minibuf)
571 Lisp_Object frame;
572 Lisp_Object minibuf;
573 {
574 Lisp_Object tail;
575 int passed = 0;
576
577 /* There must always be at least one frame in Vframe_list. */
578 if (! CONSP (Vframe_list))
579 abort ();
580
581 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
582 forever. Forestall that. */
583 CHECK_LIVE_FRAME (frame, 0);
584
585 while (1)
586 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
587 {
588 Lisp_Object f;
589
590 f = XCONS (tail)->car;
591 if (passed)
592 {
593 /* Decide whether this frame is eligible to be returned. */
594
595 /* If we've looped all the way around without finding any
596 eligible frames, return the original frame. */
597 if (EQ (f, frame))
598 return f;
599
600 /* Let minibuf decide if this frame is acceptable. */
601 if (NILP (minibuf))
602 {
603 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
604 return f;
605 }
606 else if (EQ (minibuf, Qvisible))
607 {
608 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
609 if (FRAME_VISIBLE_P (XFRAME (f)))
610 return f;
611 }
612 else if (XFASTINT (minibuf) == 0)
613 {
614 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
615 if (FRAME_VISIBLE_P (XFRAME (f))
616 || FRAME_ICONIFIED_P (XFRAME (f)))
617 return f;
618 }
619 else if (WINDOWP (minibuf))
620 {
621 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
622 /* Check that F either is, or has forwarded its focus to,
623 MINIBUF's frame. */
624 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
625 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
626 FRAME_FOCUS_FRAME (XFRAME (f)))))
627 return f;
628 }
629 else
630 return f;
631 }
632
633 if (EQ (frame, f))
634 passed++;
635 }
636 }
637
638 /* Return the previous frame in the frame list before FRAME.
639 If MINIBUF is nil, exclude minibuffer-only frames.
640 If MINIBUF is a window, include only its own frame
641 and any frame now using that window as the minibuffer.
642 If MINIBUF is `visible', include all visible frames.
643 If MINIBUF is 0, include all visible and iconified frames.
644 Otherwise, include all frames. */
645
646 Lisp_Object
647 prev_frame (frame, minibuf)
648 Lisp_Object frame;
649 Lisp_Object minibuf;
650 {
651 Lisp_Object tail;
652 Lisp_Object prev;
653
654 /* There must always be at least one frame in Vframe_list. */
655 if (! CONSP (Vframe_list))
656 abort ();
657
658 prev = Qnil;
659 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
660 {
661 Lisp_Object f;
662
663 f = XCONS (tail)->car;
664 if (!FRAMEP (f))
665 abort ();
666
667 if (EQ (frame, f) && !NILP (prev))
668 return prev;
669
670 /* Decide whether this frame is eligible to be returned,
671 according to minibuf. */
672 if (NILP (minibuf))
673 {
674 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
675 prev = f;
676 }
677 else if (WINDOWP (minibuf))
678 {
679 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
680 /* Check that F either is, or has forwarded its focus to,
681 MINIBUF's frame. */
682 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
683 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
684 FRAME_FOCUS_FRAME (XFRAME (f)))))
685 prev = f;
686 }
687 else if (EQ (minibuf, Qvisible))
688 {
689 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
690 if (FRAME_VISIBLE_P (XFRAME (f)))
691 prev = f;
692 }
693 else if (XFASTINT (minibuf) == 0)
694 {
695 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
696 if (FRAME_VISIBLE_P (XFRAME (f))
697 || FRAME_ICONIFIED_P (XFRAME (f)))
698 prev = f;
699 }
700 else
701 prev = f;
702 }
703
704 /* We've scanned the entire list. */
705 if (NILP (prev))
706 /* We went through the whole frame list without finding a single
707 acceptable frame. Return the original frame. */
708 return frame;
709 else
710 /* There were no acceptable frames in the list before FRAME; otherwise,
711 we would have returned directly from the loop. Since PREV is the last
712 acceptable frame in the list, return it. */
713 return prev;
714 }
715
716
717 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
718 "Return the next frame in the frame list after FRAME.\n\
719 By default, skip minibuffer-only frames.\n\
720 If omitted, FRAME defaults to the selected frame.\n\
721 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
722 If MINIBUF is a window, include only its own frame\n\
723 and any frame now using that window as the minibuffer.\n\
724 If MINIFRAME is `visible', include all visible frames.\n\
725 If MINIBUF is 0, include all visible and iconified frames.\n\
726 Otherwise, include all frames.")
727 (frame, miniframe)
728 Lisp_Object frame, miniframe;
729 {
730 Lisp_Object tail;
731
732 if (NILP (frame))
733 XSETFRAME (frame, selected_frame);
734 else
735 CHECK_LIVE_FRAME (frame, 0);
736
737 return next_frame (frame, miniframe);
738 }
739
740 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
741 "Return the previous frame in the frame list before FRAME.\n\
742 By default, skip minibuffer-only frames.\n\
743 If omitted, FRAME defaults to the selected frame.\n\
744 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
745 If MINIBUF is a window, include only its own frame\n\
746 and any frame now using that window as the minibuffer.\n\
747 If MINIFRAME is `visible', include all visible frames.\n\
748 If MINIBUF is 0, include all visible and iconified frames.\n\
749 Otherwise, include all frames.")
750 (frame, miniframe)
751 Lisp_Object frame, miniframe;
752 {
753 Lisp_Object tail;
754
755 if (NILP (frame))
756 XSETFRAME (frame, selected_frame);
757 else
758 CHECK_LIVE_FRAME (frame, 0);
759
760 return prev_frame (frame, miniframe);
761 }
762 \f
763 /* Return 1 if it is ok to delete frame F;
764 0 if all frames aside from F are invisible.
765 (Exception: if F is the terminal frame, and we are using X, return 1.) */
766
767 int
768 other_visible_frames (f)
769 FRAME_PTR f;
770 {
771 /* We know the selected frame is visible,
772 so if F is some other frame, it can't be the sole visible one. */
773 if (f == selected_frame)
774 {
775 Lisp_Object frames;
776 int count = 0;
777
778 for (frames = Vframe_list;
779 CONSP (frames);
780 frames = XCONS (frames)->cdr)
781 {
782 Lisp_Object this;
783
784 this = XCONS (frames)->car;
785 /* Verify that the frame's window still exists
786 and we can still talk to it. And note any recent change
787 in visibility. */
788 #ifdef HAVE_X_WINDOWS
789 if (FRAME_X_P (XFRAME (this)))
790 {
791 x_sync (XFRAME (this));
792 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
793 }
794 #endif
795
796 if (FRAME_VISIBLE_P (XFRAME (this))
797 || FRAME_ICONIFIED_P (XFRAME (this))
798 /* Allow deleting the terminal frame when at least
799 one X frame exists! */
800 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
801 count++;
802 }
803 return count > 1;
804 }
805 return 1;
806 }
807
808 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
809 "Delete FRAME, permanently eliminating it from use.\n\
810 If omitted, FRAME defaults to the selected frame.\n\
811 A frame may not be deleted if its minibuffer is used by other frames.\n\
812 Normally, you may not delete a frame if all other frames are invisible,\n\
813 but if the second optional argument FORCE is non-nil, you may do so.")
814 (frame, force)
815 Lisp_Object frame, force;
816 {
817 struct frame *f;
818
819 if (EQ (frame, Qnil))
820 {
821 f = selected_frame;
822 XSETFRAME (frame, f);
823 }
824 else
825 {
826 CHECK_FRAME (frame, 0);
827 f = XFRAME (frame);
828 }
829
830 if (! FRAME_LIVE_P (f))
831 return Qnil;
832
833 if (NILP (force) && !other_visible_frames (f))
834 error ("Attempt to delete the sole visible or iconified frame");
835
836 /* Does this frame have a minibuffer, and is it the surrogate
837 minibuffer for any other frame? */
838 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
839 {
840 Lisp_Object frames;
841
842 for (frames = Vframe_list;
843 CONSP (frames);
844 frames = XCONS (frames)->cdr)
845 {
846 Lisp_Object this;
847 this = XCONS (frames)->car;
848
849 if (! EQ (this, frame)
850 && EQ (frame,
851 WINDOW_FRAME (XWINDOW
852 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
853 error ("Attempt to delete a surrogate minibuffer frame");
854 }
855 }
856
857 /* Don't let the frame remain selected. */
858 if (f == selected_frame)
859 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
860
861 /* Don't allow minibuf_window to remain on a deleted frame. */
862 if (EQ (f->minibuffer_window, minibuf_window))
863 {
864 Fset_window_buffer (selected_frame->minibuffer_window,
865 XWINDOW (minibuf_window)->buffer);
866 minibuf_window = selected_frame->minibuffer_window;
867 }
868
869 /* Clear any X selections for this frame. */
870 #ifdef HAVE_X_WINDOWS
871 if (FRAME_X_P (f))
872 x_clear_frame_selections (f);
873 #endif
874
875 /* Mark all the windows that used to be on FRAME as deleted, and then
876 remove the reference to them. */
877 delete_all_subwindows (XWINDOW (f->root_window));
878 f->root_window = Qnil;
879
880 Vframe_list = Fdelq (frame, Vframe_list);
881 FRAME_SET_VISIBLE (f, 0);
882
883 if (FRAME_CURRENT_GLYPHS (f))
884 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
885 if (FRAME_DESIRED_GLYPHS (f))
886 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
887 if (FRAME_TEMP_GLYPHS (f))
888 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
889 if (FRAME_INSERT_COST (f))
890 free (FRAME_INSERT_COST (f));
891 if (FRAME_DELETEN_COST (f))
892 free (FRAME_DELETEN_COST (f));
893 if (FRAME_INSERTN_COST (f))
894 free (FRAME_INSERTN_COST (f));
895 if (FRAME_DELETE_COST (f))
896 free (FRAME_DELETE_COST (f));
897
898 /* Since some events are handled at the interrupt level, we may get
899 an event for f at any time; if we zero out the frame's display
900 now, then we may trip up the event-handling code. Instead, we'll
901 promise that the display of the frame must be valid until we have
902 called the window-system-dependent frame destruction routine. */
903
904 /* I think this should be done with a hook. */
905 #ifdef HAVE_X_WINDOWS
906 if (FRAME_X_P (f))
907 x_destroy_window (f);
908 #endif
909
910 f->display.nothing = 0;
911
912 /* If we've deleted the last_nonminibuf_frame, then try to find
913 another one. */
914 if (f == last_nonminibuf_frame)
915 {
916 Lisp_Object frames;
917
918 last_nonminibuf_frame = 0;
919
920 for (frames = Vframe_list;
921 CONSP (frames);
922 frames = XCONS (frames)->cdr)
923 {
924 f = XFRAME (XCONS (frames)->car);
925 if (!FRAME_MINIBUF_ONLY_P (f))
926 {
927 last_nonminibuf_frame = f;
928 break;
929 }
930 }
931 }
932
933 /* If we've deleted Vdefault_minibuffer_frame, try to find another
934 one. Prefer minibuffer-only frames, but also notice frames
935 with other windows. */
936 if (EQ (frame, Vdefault_minibuffer_frame))
937 {
938 Lisp_Object frames;
939
940 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
941 Lisp_Object frame_with_minibuf;
942
943 frame_with_minibuf = Qnil;
944 for (frames = Vframe_list;
945 CONSP (frames);
946 frames = XCONS (frames)->cdr)
947 {
948 Lisp_Object this;
949
950 this = XCONS (frames)->car;
951 if (!FRAMEP (this))
952 abort ();
953 f = XFRAME (this);
954
955 if (FRAME_HAS_MINIBUF_P (f))
956 {
957 frame_with_minibuf = this;
958 if (FRAME_MINIBUF_ONLY_P (f))
959 break;
960 }
961 }
962
963 /* We know that there must be some frame with a minibuffer out
964 there. If this were not true, all of the frames present
965 would have to be minibufferless, which implies that at some
966 point their minibuffer frames must have been deleted, but
967 that is prohibited at the top; you can't delete surrogate
968 minibuffer frames. */
969 if (NILP (frame_with_minibuf))
970 abort ();
971
972 Vdefault_minibuffer_frame = frame_with_minibuf;
973 }
974
975 return Qnil;
976 }
977 \f
978 /* Return mouse position in character cell units. */
979
980 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
981 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
982 The position is given in character cells, where (0, 0) is the\n\
983 upper-left corner.\n\
984 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
985 to read the mouse position, it returns the selected frame for FRAME\n\
986 and nil for X and Y.")
987 ()
988 {
989 FRAME_PTR f;
990 Lisp_Object lispy_dummy;
991 enum scroll_bar_part party_dummy;
992 Lisp_Object x, y;
993 int col, row;
994 unsigned long long_dummy;
995
996 f = selected_frame;
997 x = y = Qnil;
998
999 /* It's okay for the hook to refrain from storing anything. */
1000 if (mouse_position_hook)
1001 (*mouse_position_hook) (&f,
1002 &lispy_dummy, &party_dummy,
1003 &x, &y,
1004 &long_dummy);
1005 if (! NILP (x))
1006 {
1007 col = XINT (x);
1008 row = XINT (y);
1009 pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
1010 XSETINT (x, col);
1011 XSETINT (y, row);
1012 }
1013 XSETFRAME (lispy_dummy, f);
1014 return Fcons (lispy_dummy, Fcons (x, y));
1015 }
1016
1017 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1018 Smouse_pixel_position, 0, 0, 0,
1019 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1020 The position is given in pixel units, where (0, 0) is the\n\
1021 upper-left corner.\n\
1022 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1023 to read the mouse position, it returns the selected frame for FRAME\n\
1024 and nil for X and Y.")
1025 ()
1026 {
1027 FRAME_PTR f;
1028 Lisp_Object lispy_dummy;
1029 enum scroll_bar_part party_dummy;
1030 Lisp_Object x, y;
1031 int col, row;
1032 unsigned long long_dummy;
1033
1034 f = selected_frame;
1035 x = y = Qnil;
1036
1037 /* It's okay for the hook to refrain from storing anything. */
1038 if (mouse_position_hook)
1039 (*mouse_position_hook) (&f,
1040 &lispy_dummy, &party_dummy,
1041 &x, &y,
1042 &long_dummy);
1043 XSETFRAME (lispy_dummy, f);
1044 return Fcons (lispy_dummy, Fcons (x, y));
1045 }
1046
1047 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1048 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1049 WARNING: If you use this under X windows,\n\
1050 you should call `unfocus-frame' afterwards.")
1051 (frame, x, y)
1052 Lisp_Object frame, x, y;
1053 {
1054 CHECK_LIVE_FRAME (frame, 0);
1055 CHECK_NUMBER (x, 2);
1056 CHECK_NUMBER (y, 1);
1057
1058 /* I think this should be done with a hook. */
1059 #ifdef HAVE_X_WINDOWS
1060 if (FRAME_X_P (XFRAME (frame)))
1061 /* Warping the mouse will cause enternotify and focus events. */
1062 x_set_mouse_position (XFRAME (frame), x, y);
1063 #endif
1064
1065 return Qnil;
1066 }
1067
1068 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1069 Sset_mouse_pixel_position, 3, 3, 0,
1070 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1071 WARNING: If you use this under X windows,\n\
1072 you should call `unfocus-frame' afterwards.")
1073 (frame, x, y)
1074 Lisp_Object frame, x, y;
1075 {
1076 CHECK_LIVE_FRAME (frame, 0);
1077 CHECK_NUMBER (x, 2);
1078 CHECK_NUMBER (y, 1);
1079
1080 /* I think this should be done with a hook. */
1081 #ifdef HAVE_X_WINDOWS
1082 if (FRAME_X_P (XFRAME (frame)))
1083 /* Warping the mouse will cause enternotify and focus events. */
1084 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1085 #endif
1086
1087 return Qnil;
1088 }
1089 \f
1090 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1091 0, 1, "",
1092 "Make the frame FRAME visible (assuming it is an X-window).\n\
1093 If omitted, FRAME defaults to the currently selected frame.")
1094 (frame)
1095 Lisp_Object frame;
1096 {
1097 if (NILP (frame))
1098 XSETFRAME (frame, selected_frame);
1099
1100 CHECK_LIVE_FRAME (frame, 0);
1101
1102 /* I think this should be done with a hook. */
1103 #ifdef HAVE_X_WINDOWS
1104 if (FRAME_X_P (XFRAME (frame)))
1105 {
1106 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1107 x_make_frame_visible (XFRAME (frame));
1108 }
1109 #endif
1110
1111 /* Make menu bar update for the Buffers and Frams menus. */
1112 windows_or_buffers_changed++;
1113
1114 return frame;
1115 }
1116
1117 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1118 0, 2, "",
1119 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1120 If omitted, FRAME defaults to the currently selected frame.\n\
1121 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1122 but if the second optional argument FORCE is non-nil, you may do so.")
1123 (frame, force)
1124 Lisp_Object frame, force;
1125 {
1126 if (NILP (frame))
1127 XSETFRAME (frame, selected_frame);
1128
1129 CHECK_LIVE_FRAME (frame, 0);
1130
1131 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1132 error ("Attempt to make invisible the sole visible or iconified frame");
1133
1134 #if 0 /* This isn't logically necessary, and it can do GC. */
1135 /* Don't let the frame remain selected. */
1136 if (XFRAME (frame) == selected_frame)
1137 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1138 #endif
1139
1140 /* Don't allow minibuf_window to remain on a deleted frame. */
1141 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1142 {
1143 Fset_window_buffer (selected_frame->minibuffer_window,
1144 XWINDOW (minibuf_window)->buffer);
1145 minibuf_window = selected_frame->minibuffer_window;
1146 }
1147
1148 /* I think this should be done with a hook. */
1149 #ifdef HAVE_X_WINDOWS
1150 if (FRAME_X_P (XFRAME (frame)))
1151 x_make_frame_invisible (XFRAME (frame));
1152 #endif
1153
1154 /* Make menu bar update for the Buffers and Frams menus. */
1155 windows_or_buffers_changed++;
1156
1157 return Qnil;
1158 }
1159
1160 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1161 0, 1, "",
1162 "Make the frame FRAME into an icon.\n\
1163 If omitted, FRAME defaults to the currently selected frame.")
1164 (frame)
1165 Lisp_Object frame;
1166 {
1167 if (NILP (frame))
1168 XSETFRAME (frame, selected_frame);
1169
1170 CHECK_LIVE_FRAME (frame, 0);
1171
1172 #if 0 /* This isn't logically necessary, and it can do GC. */
1173 /* Don't let the frame remain selected. */
1174 if (XFRAME (frame) == selected_frame)
1175 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1176 #endif
1177
1178 /* Don't allow minibuf_window to remain on a deleted frame. */
1179 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1180 {
1181 Fset_window_buffer (selected_frame->minibuffer_window,
1182 XWINDOW (minibuf_window)->buffer);
1183 minibuf_window = selected_frame->minibuffer_window;
1184 }
1185
1186 /* I think this should be done with a hook. */
1187 #ifdef HAVE_X_WINDOWS
1188 if (FRAME_X_P (XFRAME (frame)))
1189 x_iconify_frame (XFRAME (frame));
1190 #endif
1191
1192 /* Make menu bar update for the Buffers and Frams menus. */
1193 windows_or_buffers_changed++;
1194
1195 return Qnil;
1196 }
1197
1198 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1199 1, 1, 0,
1200 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1201 A frame that is not \"visible\" is not updated and, if it works through\n\
1202 a window system, it may not show at all.\n\
1203 Return the symbol `icon' if frame is visible only as an icon.")
1204 (frame)
1205 Lisp_Object frame;
1206 {
1207 CHECK_LIVE_FRAME (frame, 0);
1208
1209 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1210
1211 if (FRAME_VISIBLE_P (XFRAME (frame)))
1212 return Qt;
1213 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1214 return Qicon;
1215 return Qnil;
1216 }
1217
1218 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1219 0, 0, 0,
1220 "Return a list of all frames now \"visible\" (being updated).")
1221 ()
1222 {
1223 Lisp_Object tail, frame;
1224 struct frame *f;
1225 Lisp_Object value;
1226
1227 value = Qnil;
1228 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1229 {
1230 frame = XCONS (tail)->car;
1231 if (!FRAMEP (frame))
1232 continue;
1233 f = XFRAME (frame);
1234 if (FRAME_VISIBLE_P (f))
1235 value = Fcons (frame, value);
1236 }
1237 return value;
1238 }
1239
1240
1241 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
1242 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1243 If FRAME is invisible, make it visible.\n\
1244 If Emacs is displaying on an ordinary terminal or some other device which\n\
1245 doesn't support multiple overlapping frames, this function does nothing.")
1246 (frame)
1247 Lisp_Object frame;
1248 {
1249 CHECK_LIVE_FRAME (frame, 0);
1250
1251 /* Do like the documentation says. */
1252 Fmake_frame_visible (frame);
1253
1254 if (frame_raise_lower_hook)
1255 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1256
1257 return Qnil;
1258 }
1259
1260 /* Should we have a corresponding function called Flower_Power? */
1261 DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
1262 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1263 If Emacs is displaying on an ordinary terminal or some other device which\n\
1264 doesn't support multiple overlapping frames, this function does nothing.")
1265 (frame)
1266 Lisp_Object frame;
1267 {
1268 CHECK_LIVE_FRAME (frame, 0);
1269
1270 if (frame_raise_lower_hook)
1271 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1272
1273 return Qnil;
1274 }
1275
1276 \f
1277 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1278 1, 2, 0,
1279 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1280 In other words, switch-frame events caused by events in FRAME will\n\
1281 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1282 FOCUS-FRAME after reading an event typed at FRAME.\n\
1283 \n\
1284 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1285 cancelled, and the frame again receives its own keystrokes.\n\
1286 \n\
1287 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1288 a surrogate minibuffer frame when a frame doesn't have its own\n\
1289 minibuffer window.\n\
1290 \n\
1291 A frame's focus redirection can be changed by select-frame. If frame\n\
1292 FOO is selected, and then a different frame BAR is selected, any\n\
1293 frames redirecting their focus to FOO are shifted to redirect their\n\
1294 focus to BAR. This allows focus redirection to work properly when the\n\
1295 user switches from one frame to another using `select-window'.\n\
1296 \n\
1297 This means that a frame whose focus is redirected to itself is treated\n\
1298 differently from a frame whose focus is redirected to nil; the former\n\
1299 is affected by select-frame, while the latter is not.\n\
1300 \n\
1301 The redirection lasts until `redirect-frame-focus' is called to change it.")
1302 (frame, focus_frame)
1303 Lisp_Object frame, focus_frame;
1304 {
1305 /* Note that we don't check for a live frame here. It's reasonable
1306 to redirect the focus of a frame you're about to delete, if you
1307 know what other frame should receive those keystrokes. */
1308 CHECK_FRAME (frame, 0);
1309
1310 if (! NILP (focus_frame))
1311 CHECK_LIVE_FRAME (focus_frame, 1);
1312
1313 XFRAME (frame)->focus_frame = focus_frame;
1314
1315 /* I think this should be done with a hook. */
1316 #ifdef HAVE_X_WINDOWS
1317 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1318 && FRAME_X_P (XFRAME (focus_frame)))
1319 Ffocus_frame (focus_frame);
1320 #endif
1321
1322 if (frame_rehighlight_hook)
1323 (*frame_rehighlight_hook) ();
1324
1325 return Qnil;
1326 }
1327
1328
1329 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1330 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1331 This returns nil if FRAME's focus is not redirected.\n\
1332 See `redirect-frame-focus'.")
1333 (frame)
1334 Lisp_Object frame;
1335 {
1336 CHECK_LIVE_FRAME (frame, 0);
1337
1338 return FRAME_FOCUS_FRAME (XFRAME (frame));
1339 }
1340
1341
1342 \f
1343 Lisp_Object
1344 get_frame_param (frame, prop)
1345 register struct frame *frame;
1346 Lisp_Object prop;
1347 {
1348 register Lisp_Object tem;
1349
1350 tem = Fassq (prop, frame->param_alist);
1351 if (EQ (tem, Qnil))
1352 return tem;
1353 return Fcdr (tem);
1354 }
1355
1356 void
1357 store_in_alist (alistptr, prop, val)
1358 Lisp_Object *alistptr, val;
1359 Lisp_Object prop;
1360 {
1361 register Lisp_Object tem;
1362
1363 tem = Fassq (prop, *alistptr);
1364 if (EQ (tem, Qnil))
1365 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1366 else
1367 Fsetcdr (tem, val);
1368 }
1369
1370 void
1371 store_frame_param (f, prop, val)
1372 struct frame *f;
1373 Lisp_Object prop, val;
1374 {
1375 register Lisp_Object tem;
1376
1377 tem = Fassq (prop, f->param_alist);
1378 if (EQ (tem, Qnil))
1379 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1380 else
1381 Fsetcdr (tem, val);
1382
1383 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1384 {
1385 if (! MINI_WINDOW_P (XWINDOW (val)))
1386 error ("Surrogate minibuffer windows must be minibuffer windows.");
1387
1388 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1389 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1390
1391 /* Install the chosen minibuffer window, with proper buffer. */
1392 f->minibuffer_window = val;
1393 }
1394 }
1395
1396 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1397 "Return the parameters-alist of frame FRAME.\n\
1398 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1399 The meaningful PARMs depend on the kind of frame.\n\
1400 If FRAME is omitted, return information on the currently selected frame.")
1401 (frame)
1402 Lisp_Object frame;
1403 {
1404 Lisp_Object alist;
1405 FRAME_PTR f;
1406
1407 if (EQ (frame, Qnil))
1408 f = selected_frame;
1409 else
1410 {
1411 CHECK_FRAME (frame, 0);
1412 f = XFRAME (frame);
1413 }
1414
1415 if (!FRAME_LIVE_P (f))
1416 return Qnil;
1417
1418 alist = Fcopy_alist (f->param_alist);
1419 store_in_alist (&alist, Qname, f->name);
1420 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
1421 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
1422 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
1423 store_in_alist (&alist, Qminibuffer,
1424 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1425 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1426 : FRAME_MINIBUF_WINDOW (f)));
1427 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
1428
1429 /* I think this should be done with a hook. */
1430 #ifdef HAVE_X_WINDOWS
1431 if (FRAME_X_P (f))
1432 x_report_frame_params (f, &alist);
1433 else
1434 #endif
1435 {
1436 /* This ought to be correct in f->param_alist for an X frame. */
1437 Lisp_Object lines;
1438 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
1439 store_in_alist (&alist, Qmenu_bar_lines, lines);
1440 }
1441 return alist;
1442 }
1443
1444 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1445 Smodify_frame_parameters, 2, 2, 0,
1446 "Modify the parameters of frame FRAME according to ALIST.\n\
1447 ALIST is an alist of parameters to change and their new values.\n\
1448 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1449 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1450 (frame, alist)
1451 Lisp_Object frame, alist;
1452 {
1453 FRAME_PTR f;
1454 register Lisp_Object tail, elt, prop, val;
1455
1456 if (EQ (frame, Qnil))
1457 f = selected_frame;
1458 else
1459 {
1460 CHECK_LIVE_FRAME (frame, 0);
1461 f = XFRAME (frame);
1462 }
1463
1464 /* I think this should be done with a hook. */
1465 #ifdef HAVE_X_WINDOWS
1466 if (FRAME_X_P (f))
1467 #if 1
1468 x_set_frame_parameters (f, alist);
1469 #else
1470 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1471 {
1472 elt = Fcar (tail);
1473 prop = Fcar (elt);
1474 val = Fcdr (elt);
1475 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
1476 store_frame_param (f, prop, val);
1477 }
1478 #endif
1479 #endif
1480
1481 return Qnil;
1482 }
1483 \f
1484 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1485 0, 1, 0,
1486 "Height in pixels of a line in the font in frame FRAME.\n\
1487 If FRAME is omitted, the selected frame is used.\n\
1488 For a terminal frame, the value is always 1.")
1489 (frame)
1490 Lisp_Object frame;
1491 {
1492 struct frame *f;
1493
1494 if (NILP (frame))
1495 f = selected_frame;
1496 else
1497 {
1498 CHECK_FRAME (frame, 0);
1499 f = XFRAME (frame);
1500 }
1501
1502 #ifdef HAVE_X_WINDOWS
1503 if (FRAME_X_P (f))
1504 return make_number (x_char_height (f));
1505 else
1506 #endif
1507 return make_number (1);
1508 }
1509
1510
1511 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1512 0, 1, 0,
1513 "Width in pixels of characters in the font in frame FRAME.\n\
1514 If FRAME is omitted, the selected frame is used.\n\
1515 The width is the same for all characters, because\n\
1516 currently Emacs supports only fixed-width fonts.\n\
1517 For a terminal screen, the value is always 1.")
1518 (frame)
1519 Lisp_Object frame;
1520 {
1521 struct frame *f;
1522
1523 if (NILP (frame))
1524 f = selected_frame;
1525 else
1526 {
1527 CHECK_FRAME (frame, 0);
1528 f = XFRAME (frame);
1529 }
1530
1531 #ifdef HAVE_X_WINDOWS
1532 if (FRAME_X_P (f))
1533 return make_number (x_char_width (f));
1534 else
1535 #endif
1536 return make_number (1);
1537 }
1538
1539 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1540 Sframe_pixel_height, 0, 1, 0,
1541 "Return a FRAME's height in pixels.\n\
1542 For a terminal frame, the result really gives the height in characters.\n\
1543 If FRAME is omitted, the selected frame is used.")
1544 (frame)
1545 Lisp_Object frame;
1546 {
1547 struct frame *f;
1548
1549 if (NILP (frame))
1550 f = selected_frame;
1551 else
1552 {
1553 CHECK_FRAME (frame, 0);
1554 f = XFRAME (frame);
1555 }
1556
1557 #ifdef HAVE_X_WINDOWS
1558 if (FRAME_X_P (f))
1559 return make_number (x_pixel_height (f));
1560 else
1561 #endif
1562 return make_number (FRAME_HEIGHT (f));
1563 }
1564
1565 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1566 Sframe_pixel_width, 0, 1, 0,
1567 "Return FRAME's width in pixels.\n\
1568 For a terminal frame, the result really gives the width in characters.\n\
1569 If FRAME is omitted, the selected frame is used.")
1570 (frame)
1571 Lisp_Object frame;
1572 {
1573 struct frame *f;
1574
1575 if (NILP (frame))
1576 f = selected_frame;
1577 else
1578 {
1579 CHECK_FRAME (frame, 0);
1580 f = XFRAME (frame);
1581 }
1582
1583 #ifdef HAVE_X_WINDOWS
1584 if (FRAME_X_P (f))
1585 return make_number (x_pixel_width (f));
1586 else
1587 #endif
1588 return make_number (FRAME_WIDTH (f));
1589 }
1590 \f
1591 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1592 "Specify that the frame FRAME has LINES lines.\n\
1593 Optional third arg non-nil means that redisplay should use LINES lines\n\
1594 but that the idea of the actual height of the frame should not be changed.")
1595 (frame, rows, pretend)
1596 Lisp_Object frame, rows, pretend;
1597 {
1598 register struct frame *f;
1599
1600 CHECK_NUMBER (rows, 0);
1601 if (NILP (frame))
1602 f = selected_frame;
1603 else
1604 {
1605 CHECK_LIVE_FRAME (frame, 0);
1606 f = XFRAME (frame);
1607 }
1608
1609 /* I think this should be done with a hook. */
1610 #ifdef HAVE_X_WINDOWS
1611 if (FRAME_X_P (f))
1612 {
1613 if (XINT (rows) != f->height)
1614 x_set_window_size (f, 1, f->width, XINT (rows));
1615 }
1616 else
1617 #endif
1618 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
1619 return Qnil;
1620 }
1621
1622 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1623 "Specify that the frame FRAME has COLS columns.\n\
1624 Optional third arg non-nil means that redisplay should use COLS columns\n\
1625 but that the idea of the actual width of the frame should not be changed.")
1626 (frame, cols, pretend)
1627 Lisp_Object frame, cols, pretend;
1628 {
1629 register struct frame *f;
1630 CHECK_NUMBER (cols, 0);
1631 if (NILP (frame))
1632 f = selected_frame;
1633 else
1634 {
1635 CHECK_LIVE_FRAME (frame, 0);
1636 f = XFRAME (frame);
1637 }
1638
1639 /* I think this should be done with a hook. */
1640 #ifdef HAVE_X_WINDOWS
1641 if (FRAME_X_P (f))
1642 {
1643 if (XINT (cols) != f->width)
1644 x_set_window_size (f, 1, XINT (cols), f->height);
1645 }
1646 else
1647 #endif
1648 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1649 return Qnil;
1650 }
1651
1652 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1653 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1654 (frame, cols, rows)
1655 Lisp_Object frame, cols, rows;
1656 {
1657 register struct frame *f;
1658 int mask;
1659
1660 CHECK_LIVE_FRAME (frame, 0);
1661 CHECK_NUMBER (cols, 2);
1662 CHECK_NUMBER (rows, 1);
1663 f = XFRAME (frame);
1664
1665 /* I think this should be done with a hook. */
1666 #ifdef HAVE_X_WINDOWS
1667 if (FRAME_X_P (f))
1668 {
1669 if (XINT (rows) != f->height || XINT (cols) != f->width)
1670 x_set_window_size (f, 1, XINT (cols), XINT (rows));
1671 }
1672 else
1673 #endif
1674 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1675
1676 return Qnil;
1677 }
1678
1679 DEFUN ("set-frame-position", Fset_frame_position,
1680 Sset_frame_position, 3, 3, 0,
1681 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1682 This is actually the position of the upper left corner of the frame.\n\
1683 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1684 the rightmost or bottommost possible position (that stays within the screen).")
1685 (frame, xoffset, yoffset)
1686 Lisp_Object frame, xoffset, yoffset;
1687 {
1688 register struct frame *f;
1689 int mask;
1690
1691 CHECK_LIVE_FRAME (frame, 0);
1692 CHECK_NUMBER (xoffset, 1);
1693 CHECK_NUMBER (yoffset, 2);
1694 f = XFRAME (frame);
1695
1696 /* I think this should be done with a hook. */
1697 #ifdef HAVE_X_WINDOWS
1698 if (FRAME_X_P (f))
1699 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
1700 #endif
1701
1702 return Qt;
1703 }
1704
1705 \f
1706 choose_minibuf_frame ()
1707 {
1708 /* For lowest-level minibuf, put it on currently selected frame
1709 if frame has a minibuffer. */
1710
1711 if (minibuf_level == 0
1712 && selected_frame != 0
1713 && !EQ (minibuf_window, selected_frame->minibuffer_window))
1714 {
1715 /* I don't think that any frames may validly have a null minibuffer
1716 window anymore. */
1717 if (NILP (selected_frame->minibuffer_window))
1718 abort ();
1719
1720 Fset_window_buffer (selected_frame->minibuffer_window,
1721 XWINDOW (minibuf_window)->buffer);
1722 minibuf_window = selected_frame->minibuffer_window;
1723 }
1724 }
1725 \f
1726 syms_of_frame ()
1727 {
1728 /*&&& init symbols here &&&*/
1729 Qframep = intern ("framep");
1730 staticpro (&Qframep);
1731 Qframe_live_p = intern ("frame-live-p");
1732 staticpro (&Qframe_live_p);
1733 Qheight = intern ("height");
1734 staticpro (&Qheight);
1735 Qicon = intern ("icon");
1736 staticpro (&Qicon);
1737 Qminibuffer = intern ("minibuffer");
1738 staticpro (&Qminibuffer);
1739 Qmodeline = intern ("modeline");
1740 staticpro (&Qmodeline);
1741 Qname = intern ("name");
1742 staticpro (&Qname);
1743 Qonly = intern ("only");
1744 staticpro (&Qonly);
1745 Qunsplittable = intern ("unsplittable");
1746 staticpro (&Qunsplittable);
1747 Qmenu_bar_lines = intern ("menu-bar-lines");
1748 staticpro (&Qmenu_bar_lines);
1749 Qwidth = intern ("width");
1750 staticpro (&Qwidth);
1751 Qx = intern ("x");
1752 staticpro (&Qx);
1753 Qvisible = intern ("visible");
1754 staticpro (&Qvisible);
1755
1756 staticpro (&Vframe_list);
1757
1758 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1759 "The initial frame-object, which represents Emacs's stdout.");
1760
1761 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1762 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1763 Vemacs_iconified = Qnil;
1764
1765 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1766 "Minibufferless frames use this frame's minibuffer.\n\
1767 \n\
1768 Emacs cannot create minibufferless frames unless this is set to an\n\
1769 appropriate surrogate.\n\
1770 \n\
1771 Emacs consults this variable only when creating minibufferless\n\
1772 frames; once the frame is created, it sticks with its assigned\n\
1773 minibuffer, no matter what this variable is set to. This means that\n\
1774 this variable doesn't necessarily say anything meaningful about the\n\
1775 current set of frames, or where the minibuffer is currently being\n\
1776 displayed.");
1777 Vdefault_minibuffer_frame = Qnil;
1778
1779 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1780 "Alist of default values for frame creation.\n\
1781 These may be set in your init file, like this:\n\
1782 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1783 These override values given in window system configuration data, like\n\
1784 X Windows' defaults database.\n\
1785 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1786 For values specific to the separate minibuffer frame, see\n\
1787 `minibuffer-frame-alist'.");
1788 Vdefault_frame_alist = Qnil;
1789
1790 defsubr (&Sframep);
1791 defsubr (&Sframe_live_p);
1792 defsubr (&Shandle_switch_frame);
1793 defsubr (&Sselect_frame);
1794 defsubr (&Sselected_frame);
1795 defsubr (&Swindow_frame);
1796 defsubr (&Sframe_root_window);
1797 defsubr (&Sframe_first_window);
1798 defsubr (&Sframe_selected_window);
1799 defsubr (&Sset_frame_selected_window);
1800 defsubr (&Sframe_list);
1801 defsubr (&Snext_frame);
1802 defsubr (&Sprevious_frame);
1803 defsubr (&Sdelete_frame);
1804 defsubr (&Smouse_position);
1805 defsubr (&Smouse_pixel_position);
1806 defsubr (&Sset_mouse_position);
1807 defsubr (&Sset_mouse_pixel_position);
1808 #if 0
1809 defsubr (&Sframe_configuration);
1810 defsubr (&Srestore_frame_configuration);
1811 #endif
1812 defsubr (&Smake_frame_visible);
1813 defsubr (&Smake_frame_invisible);
1814 defsubr (&Siconify_frame);
1815 defsubr (&Sframe_visible_p);
1816 defsubr (&Svisible_frame_list);
1817 defsubr (&Sraise_frame);
1818 defsubr (&Slower_frame);
1819 defsubr (&Sredirect_frame_focus);
1820 defsubr (&Sframe_focus);
1821 defsubr (&Sframe_parameters);
1822 defsubr (&Smodify_frame_parameters);
1823 defsubr (&Sframe_char_height);
1824 defsubr (&Sframe_char_width);
1825 defsubr (&Sframe_pixel_height);
1826 defsubr (&Sframe_pixel_width);
1827 defsubr (&Sset_frame_height);
1828 defsubr (&Sset_frame_width);
1829 defsubr (&Sset_frame_size);
1830 defsubr (&Sset_frame_position);
1831 }
1832
1833 keys_of_frame ()
1834 {
1835 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
1836 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1837 initial_define_lispy_key (global_map, "iconify-frame", "ignore");
1838 initial_define_lispy_key (global_map, "make-frame-visible", "ignore");
1839 }
1840 \f
1841 #else /* not MULTI_FRAME */
1842
1843 /* If we're not using multi-frame stuff, we still need to provide some
1844 support functions. */
1845
1846 Lisp_Object Qheight;
1847 Lisp_Object Qminibuffer;
1848 Lisp_Object Qmodeline;
1849 Lisp_Object Qname;
1850 Lisp_Object Qunsplittable;
1851 Lisp_Object Qmenu_bar_lines;
1852 Lisp_Object Qwidth;
1853
1854 Lisp_Object Vterminal_frame;
1855
1856 /* Unless this function is defined, providing set-frame-height and
1857 set-frame-width doesn't help compatibility any, since they both
1858 want this as their first argument. */
1859 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1860 /* Don't confuse make-docfile by having two doc strings for this function.
1861 make-docfile does not pay attention to #if, for good reason! */
1862 0)
1863 ()
1864 {
1865 /* For your possible information, this code is unfolded into the
1866 second WINDOW_FRAME in frame.h. */
1867 Lisp_Object tem;
1868 XSETFASTINT (tem, 0);
1869 return tem;
1870 }
1871
1872 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
1873 0)
1874 (frame)
1875 Lisp_Object frame;
1876 {
1877 Lisp_Object w;
1878
1879 w = FRAME_ROOT_WINDOW (selected_frame);
1880
1881 while (NILP (XWINDOW (w)->buffer))
1882 {
1883 if (! NILP (XWINDOW (w)->hchild))
1884 w = XWINDOW (w)->hchild;
1885 else if (! NILP (XWINDOW (w)->vchild))
1886 w = XWINDOW (w)->vchild;
1887 else
1888 abort ();
1889 }
1890 return w;
1891 }
1892
1893 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1894 /* Don't confuse make-docfile by having two doc strings for this function.
1895 make-docfile does not pay attention to #if, for good reason! */
1896 0)
1897 (object)
1898 Lisp_Object object;
1899 {
1900 #ifdef MSDOS
1901 if (FRAME_X_P (object))
1902 return intern ("pc");
1903 #endif
1904 return Qnil;
1905 }
1906
1907 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1908 /* Don't confuse make-docfile by having two doc strings for this function.
1909 make-docfile does not pay attention to #if, for good reason! */
1910 0)
1911 (frame, rows, pretend)
1912 Lisp_Object frame, rows, pretend;
1913 {
1914 CHECK_NUMBER (rows, 0);
1915
1916 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1917 return Qnil;
1918 }
1919
1920 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1921 /* Don't confuse make-docfile by having two doc strings for this function.
1922 make-docfile does not pay attention to #if, for good reason! */
1923 0)
1924 (frame, cols, pretend)
1925 Lisp_Object frame, cols, pretend;
1926 {
1927 CHECK_NUMBER (cols, 0);
1928
1929 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1930 return Qnil;
1931 }
1932
1933 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1934 /* Don't confuse make-docfile by having two doc strings for this function.
1935 make-docfile does not pay attention to #if, for good reason! */
1936 0)
1937 (frame, cols, rows)
1938 Lisp_Object frame, cols, rows;
1939 {
1940 CHECK_NUMBER (cols, 2);
1941 CHECK_NUMBER (rows, 1);
1942
1943 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1944
1945 return Qnil;
1946 }
1947 \f
1948 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1949 "Return number of lines available for display on FRAME.\n\
1950 If FRAME is omitted, describe the currently selected frame.")
1951 (frame)
1952 Lisp_Object frame;
1953 {
1954 return make_number (FRAME_HEIGHT (selected_frame));
1955 }
1956
1957 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1958 "Return number of columns available for display on FRAME.\n\
1959 If FRAME is omitted, describe the currently selected frame.")
1960 (frame)
1961 Lisp_Object frame;
1962 {
1963 return make_number (FRAME_WIDTH (selected_frame));
1964 }
1965
1966 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1967 0, 1, 0,
1968 /* Don't confuse make-docfile by having two doc strings for this function.
1969 make-docfile does not pay attention to #if, for good reason! */
1970 0)
1971 (frame)
1972 Lisp_Object frame;
1973 {
1974 return make_number (1);
1975 }
1976
1977
1978 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1979 0, 1, 0,
1980 /* Don't confuse make-docfile by having two doc strings for this function.
1981 make-docfile does not pay attention to #if, for good reason! */
1982 0)
1983 (frame)
1984 Lisp_Object frame;
1985 {
1986 return make_number (1);
1987 }
1988
1989 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1990 Sframe_pixel_height, 0, 1, 0,
1991 /* Don't confuse make-docfile by having two doc strings for this function.
1992 make-docfile does not pay attention to #if, for good reason! */
1993 0)
1994 (frame)
1995 Lisp_Object frame;
1996 {
1997 return make_number (FRAME_HEIGHT (f));
1998 }
1999
2000 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2001 Sframe_pixel_width, 0, 1, 0,
2002 /* Don't confuse make-docfile by having two doc strings for this function.
2003 make-docfile does not pay attention to #if, for good reason! */
2004 0)
2005 (frame)
2006 Lisp_Object frame;
2007 {
2008 return make_number (FRAME_WIDTH (f));
2009 }
2010
2011 /* These are for backward compatibility with Emacs 18. */
2012
2013 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
2014 "Tell redisplay that the screen has LINES lines.\n\
2015 Optional second arg non-nil means that redisplay should use LINES lines\n\
2016 but that the idea of the actual height of the screen should not be changed.")
2017 (lines, pretend)
2018 Lisp_Object lines, pretend;
2019 {
2020 CHECK_NUMBER (lines, 0);
2021
2022 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
2023 return Qnil;
2024 }
2025
2026 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
2027 "Tell redisplay that the screen has COLS columns.\n\
2028 Optional second arg non-nil means that redisplay should use COLS columns\n\
2029 but that the idea of the actual width of the screen should not be changed.")
2030 (cols, pretend)
2031 Lisp_Object cols, pretend;
2032 {
2033 CHECK_NUMBER (cols, 0);
2034
2035 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2036 return Qnil;
2037 }
2038
2039 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
2040 /* Don't confuse make-docfile by having two doc strings for this function.
2041 make-docfile does not pay attention to #if, for good reason! */
2042 0)
2043 ()
2044 {
2045 #ifdef HAVE_MOUSE
2046 if (mouse_position_hook)
2047 {
2048 FRAME_PTR f;
2049 Lisp_Object lispy_dummy;
2050 enum scroll_bar_part party_dummy;
2051 Lisp_Object x, y;
2052 unsigned long long_dummy;
2053
2054 (*mouse_position_hook) (&f,
2055 &lispy_dummy, &party_dummy,
2056 &x, &y,
2057 &long_dummy);
2058 return Fcons (Fselected_frame (), Fcons (x, y));
2059 }
2060 #endif
2061 return Fcons (Qnil, Fcons (Qnil, Qnil));
2062 }
2063 \f
2064 void
2065 store_in_alist (alistptr, prop, val)
2066 Lisp_Object *alistptr, val;
2067 Lisp_Object prop;
2068 {
2069 register Lisp_Object tem;
2070
2071 tem = Fassq (prop, *alistptr);
2072 if (EQ (tem, Qnil))
2073 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2074 else
2075 Fsetcdr (tem, val);
2076 }
2077
2078 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2079 /* Don't confuse make-docfile by having two doc strings for this function.
2080 make-docfile does not pay attention to #if, for good reason! */
2081 0)
2082 (frame)
2083 Lisp_Object frame;
2084 {
2085 Lisp_Object alist;
2086 FRAME_PTR f;
2087
2088 if (EQ (frame, Qnil))
2089 f = selected_frame;
2090 else
2091 {
2092 CHECK_FRAME (frame, 0);
2093 f = XFRAME (frame);
2094 }
2095
2096 if (!FRAME_LIVE_P (f))
2097 return Qnil;
2098
2099 alist = Qnil;
2100 #ifdef MSDOS
2101 if (FRAME_X_P (f))
2102 {
2103 static char *colornames[16] =
2104 {
2105 "black", "blue", "green", "cyan", "red", "magenta", "brown",
2106 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
2107 "lightred", "lightmagenta", "yellow", "white"
2108 };
2109 store_in_alist (&alist, intern ("foreground-color"),
2110 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
2111 store_in_alist (&alist, intern ("background-color"),
2112 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
2113 }
2114 #endif
2115 store_in_alist (&alist, intern ("font"), build_string ("default"));
2116 store_in_alist (&alist, Qname, build_string ("emacs"));
2117 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
2118 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
2119 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2120 store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
2121 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2122 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
2123
2124 return alist;
2125 }
2126
2127 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2128 Smodify_frame_parameters, 2, 2, 0,
2129 /* Don't confuse make-docfile by having two doc strings for this function.
2130 make-docfile does not pay attention to #if, for good reason! */
2131 0)
2132 (frame, alist)
2133 Lisp_Object frame, alist;
2134 {
2135 #ifdef MSDOS
2136 if (FRAME_X_P (frame))
2137 IT_set_frame_parameters (XFRAME (frame), alist);
2138 #endif
2139 return Qnil;
2140 }
2141
2142 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
2143 /* Don't confuse make-docfile by having two doc strings for this function.
2144 make-docfile does not pay attention to #if, for good reason! */
2145 0)
2146 (frame)
2147 Lisp_Object frame;
2148 {
2149 return Qt;
2150 }
2151
2152 DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0,
2153 /* Don't confuse make-docfile by having two doc strings for this function.
2154 make-docfile does not pay attention to #if, for good reason! */
2155 0)
2156 ()
2157 {
2158 return Fcons (Fselected_frame (), Qnil);
2159 }
2160
2161 syms_of_frame ()
2162 {
2163 Qheight = intern ("height");
2164 staticpro (&Qheight);
2165 Qminibuffer = intern ("minibuffer");
2166 staticpro (&Qminibuffer);
2167 Qmodeline = intern ("modeline");
2168 staticpro (&Qmodeline);
2169 Qname = intern ("name");
2170 staticpro (&Qname);
2171 Qunsplittable = intern ("unsplittable");
2172 staticpro (&Qunsplittable);
2173 Qmenu_bar_lines = intern ("menu-bar-lines");
2174 staticpro (&Qmenu_bar_lines);
2175 Qwidth = intern ("width");
2176 staticpro (&Qwidth);
2177
2178 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2179 "The initial frame-object, which represents Emacs's stdout.");
2180 XSETFASTINT (Vterminal_frame, 0);
2181
2182 defsubr (&Sselected_frame);
2183 defsubr (&Sframe_first_window);
2184 defsubr (&Sframep);
2185 defsubr (&Sframe_char_height);
2186 defsubr (&Sframe_char_width);
2187 defsubr (&Sframe_pixel_height);
2188 defsubr (&Sframe_pixel_width);
2189 defsubr (&Sset_frame_height);
2190 defsubr (&Sset_frame_width);
2191 defsubr (&Sset_frame_size);
2192 defsubr (&Sset_screen_height);
2193 defsubr (&Sset_screen_width);
2194 defsubr (&Sframe_height);
2195 Ffset (intern ("screen-height"), intern ("frame-height"));
2196 defsubr (&Sframe_width);
2197 Ffset (intern ("screen-width"), intern ("frame-width"));
2198 defsubr (&Smouse_position);
2199 defsubr (&Sframe_parameters);
2200 defsubr (&Smodify_frame_parameters);
2201 defsubr (&Sframe_live_p);
2202 defsubr (&Sframe_list);
2203
2204 #ifdef MSDOS
2205 /* A comment in dispnew.c says the_only_frame is not protected. */
2206 the_only_frame.face_alist = Qnil;
2207 staticpro (&the_only_frame.face_alist);
2208 the_only_frame.menu_bar_items = Qnil;
2209 staticpro (&the_only_frame.menu_bar_items);
2210 the_only_frame.menu_bar_vector = Qnil;
2211 staticpro (&the_only_frame.menu_bar_vector);
2212 the_only_frame.menu_bar_items = menu_bar_items (Qnil);
2213 #endif
2214 }
2215
2216 keys_of_frame ()
2217 {
2218 }
2219
2220 #endif /* not MULTI_FRAME */