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