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