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