(Disabling backups): Replace reference to
[emacs.git] / src / frame.c
blobefbf7a122596fe04264cfab46de379a798796835
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000 Free Software Foundation.
4 This file is part of GNU Emacs.
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.
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.
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. */
21 #include <config.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "charset.h"
26 #ifdef HAVE_X_WINDOWS
27 #include "xterm.h"
28 #endif
29 #ifdef WINDOWSNT
30 #include "w32term.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
44 #ifdef macintosh
45 extern struct mac_output *NewMacWindow ();
46 extern void DisposeMacWindow (struct mac_output *);
47 #endif
49 /* Evaluate this expression to rebuild the section of syms_of_frame
50 that initializes and staticpros the symbols declared below. Note
51 that Emacs 18 has a bug that keeps C-x C-e from being able to
52 evaluate this expression.
54 (progn
55 ;; Accumulate a list of the symbols we want to initialize from the
56 ;; declarations at the top of the file.
57 (goto-char (point-min))
58 (search-forward "/\*&&& symbols declared here &&&*\/\n")
59 (let (symbol-list)
60 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
61 (setq symbol-list
62 (cons (buffer-substring (match-beginning 1) (match-end 1))
63 symbol-list))
64 (forward-line 1))
65 (setq symbol-list (nreverse symbol-list))
66 ;; Delete the section of syms_of_... where we initialize the symbols.
67 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
68 (let ((start (point)))
69 (while (looking-at "^ Q")
70 (forward-line 2))
71 (kill-region start (point)))
72 ;; Write a new symbol initialization section.
73 (while symbol-list
74 (insert (format " %s = intern (\"" (car symbol-list)))
75 (let ((start (point)))
76 (insert (substring (car symbol-list) 1))
77 (subst-char-in-region start (point) ?_ ?-))
78 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
79 (setq symbol-list (cdr symbol-list)))))
80 */
82 /*&&& symbols declared here &&&*/
83 Lisp_Object Qframep;
84 Lisp_Object Qframe_live_p;
85 Lisp_Object Qheight;
86 Lisp_Object Qicon;
87 Lisp_Object Qminibuffer;
88 Lisp_Object Qmodeline;
89 Lisp_Object Qname;
90 Lisp_Object Qonly;
91 Lisp_Object Qunsplittable;
92 Lisp_Object Qmenu_bar_lines;
93 Lisp_Object Qtool_bar_lines;
94 Lisp_Object Qwidth;
95 Lisp_Object Qx;
96 Lisp_Object Qw32;
97 Lisp_Object Qpc;
98 Lisp_Object Qmac;
99 Lisp_Object Qvisible;
100 Lisp_Object Qbuffer_predicate;
101 Lisp_Object Qbuffer_list;
102 Lisp_Object Qtitle;
104 Lisp_Object Vterminal_frame;
105 Lisp_Object Vdefault_frame_alist;
106 Lisp_Object Vmouse_position_function;
108 static void
109 syms_of_frame_1 ()
111 /*&&& init symbols here &&&*/
112 Qframep = intern ("framep");
113 staticpro (&Qframep);
114 Qframe_live_p = intern ("frame-live-p");
115 staticpro (&Qframe_live_p);
116 Qheight = intern ("height");
117 staticpro (&Qheight);
118 Qicon = intern ("icon");
119 staticpro (&Qicon);
120 Qminibuffer = intern ("minibuffer");
121 staticpro (&Qminibuffer);
122 Qmodeline = intern ("modeline");
123 staticpro (&Qmodeline);
124 Qname = intern ("name");
125 staticpro (&Qname);
126 Qonly = intern ("only");
127 staticpro (&Qonly);
128 Qunsplittable = intern ("unsplittable");
129 staticpro (&Qunsplittable);
130 Qmenu_bar_lines = intern ("menu-bar-lines");
131 staticpro (&Qmenu_bar_lines);
132 Qtool_bar_lines = intern ("tool-bar-lines");
133 staticpro (&Qtool_bar_lines);
134 Qwidth = intern ("width");
135 staticpro (&Qwidth);
136 Qx = intern ("x");
137 staticpro (&Qx);
138 Qw32 = intern ("w32");
139 staticpro (&Qw32);
140 Qpc = intern ("pc");
141 staticpro (&Qpc);
142 Qmac = intern ("mac");
143 staticpro (&Qmac);
144 Qvisible = intern ("visible");
145 staticpro (&Qvisible);
146 Qbuffer_predicate = intern ("buffer-predicate");
147 staticpro (&Qbuffer_predicate);
148 Qbuffer_list = intern ("buffer-list");
149 staticpro (&Qbuffer_list);
150 Qtitle = intern ("title");
151 staticpro (&Qtitle);
153 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
154 "Alist of default values for frame creation.\n\
155 These may be set in your init file, like this:\n\
156 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
157 These override values given in window system configuration data,\n\
158 including X Windows' defaults database.\n\
159 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
160 For values specific to the separate minibuffer frame, see\n\
161 `minibuffer-frame-alist'.\n\
162 The `menu-bar-lines' element of the list controls whether new frames\n\
163 have menu bars; `menu-bar-mode' works by altering this element.");
164 Vdefault_frame_alist = Qnil;
167 static void
168 set_menu_bar_lines_1 (window, n)
169 Lisp_Object window;
170 int n;
172 struct window *w = XWINDOW (window);
174 XSETFASTINT (w->last_modified, 0);
175 XSETFASTINT (w->top, XFASTINT (w->top) + n);
176 XSETFASTINT (w->height, XFASTINT (w->height) - n);
178 if (INTEGERP (w->orig_top))
179 XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
180 if (INTEGERP (w->orig_height))
181 XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
183 /* Handle just the top child in a vertical split. */
184 if (!NILP (w->vchild))
185 set_menu_bar_lines_1 (w->vchild, n);
187 /* Adjust all children in a horizontal split. */
188 for (window = w->hchild; !NILP (window); window = w->next)
190 w = XWINDOW (window);
191 set_menu_bar_lines_1 (window, n);
195 void
196 set_menu_bar_lines (f, value, oldval)
197 struct frame *f;
198 Lisp_Object value, oldval;
200 int nlines;
201 int olines = FRAME_MENU_BAR_LINES (f);
203 /* Right now, menu bars don't work properly in minibuf-only frames;
204 most of the commands try to apply themselves to the minibuffer
205 frame itself, and get an error because you can't switch buffers
206 in or split the minibuffer window. */
207 if (FRAME_MINIBUF_ONLY_P (f))
208 return;
210 if (INTEGERP (value))
211 nlines = XINT (value);
212 else
213 nlines = 0;
215 if (nlines != olines)
217 windows_or_buffers_changed++;
218 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
219 FRAME_MENU_BAR_LINES (f) = nlines;
220 set_menu_bar_lines_1 (f->root_window, nlines - olines);
221 adjust_glyphs (f);
225 #include "buffer.h"
227 /* These help us bind and responding to switch-frame events. */
228 #include "commands.h"
229 #include "keyboard.h"
231 Lisp_Object Vemacs_iconified;
232 Lisp_Object Vframe_list;
234 struct x_output tty_display;
236 extern Lisp_Object Vminibuffer_list;
237 extern Lisp_Object get_minibuffer ();
238 extern Lisp_Object Fhandle_switch_frame ();
239 extern Lisp_Object Fredirect_frame_focus ();
240 extern Lisp_Object x_get_focus_frame ();
242 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
243 "Return non-nil if OBJECT is a frame.\n\
244 Value is t for a termcap frame (a character-only terminal),\n\
245 `x' for an Emacs frame that is really an X window,\n\
246 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
247 `mac' for an Emacs frame on a Macintosh display,\n\
248 `pc' for a direct-write MS-DOS frame.\n\
249 See also `frame-live-p'.")
250 (object)
251 Lisp_Object object;
253 if (!FRAMEP (object))
254 return Qnil;
255 switch (XFRAME (object)->output_method)
257 case output_termcap:
258 return Qt;
259 case output_x_window:
260 return Qx;
261 case output_w32:
262 return Qw32;
263 case output_msdos_raw:
264 return Qpc;
265 case output_mac:
266 return Qmac;
267 default:
268 abort ();
272 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
273 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
274 Value is nil if OBJECT is not a live frame. If object is a live\n\
275 frame, the return value indicates what sort of output device it is\n\
276 displayed on. Value is t for a termcap frame (a character-only\n\
277 terminal), `x' for an Emacs frame being displayed in an X window.")
278 (object)
279 Lisp_Object object;
281 return ((FRAMEP (object)
282 && FRAME_LIVE_P (XFRAME (object)))
283 ? Fframep (object)
284 : Qnil);
287 struct frame *
288 make_frame (mini_p)
289 int mini_p;
291 Lisp_Object frame;
292 register struct frame *f;
293 register Lisp_Object root_window;
294 register Lisp_Object mini_window;
295 register struct Lisp_Vector *vec;
296 int i;
298 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
299 for (i = 0; i < VECSIZE (struct frame); i++)
300 XSETFASTINT (vec->contents[i], 0);
301 vec->size = VECSIZE (struct frame);
302 f = (struct frame *)vec;
303 XSETFRAME (frame, f);
305 f->desired_matrix = 0;
306 f->current_matrix = 0;
307 f->desired_pool = 0;
308 f->current_pool = 0;
309 f->glyphs_initialized_p = 0;
310 f->decode_mode_spec_buffer = 0;
311 f->visible = 0;
312 f->async_visible = 0;
313 f->output_data.nothing = 0;
314 f->iconified = 0;
315 f->async_iconified = 0;
316 f->wants_modeline = 1;
317 f->auto_raise = 0;
318 f->auto_lower = 0;
319 f->no_split = 0;
320 f->garbaged = 1;
321 f->has_minibuffer = mini_p;
322 f->focus_frame = Qnil;
323 f->explicit_name = 0;
324 f->can_have_scroll_bars = 0;
325 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
326 f->param_alist = Qnil;
327 f->scroll_bars = Qnil;
328 f->condemned_scroll_bars = Qnil;
329 f->face_alist = Qnil;
330 f->face_cache = NULL;
331 f->menu_bar_items = Qnil;
332 f->menu_bar_vector = Qnil;
333 f->menu_bar_items_used = 0;
334 f->buffer_predicate = Qnil;
335 f->buffer_list = Qnil;
336 #ifdef MULTI_KBOARD
337 f->kboard = initial_kboard;
338 #endif
339 f->namebuf = 0;
340 f->title = Qnil;
341 f->menu_bar_window = Qnil;
342 f->tool_bar_window = Qnil;
343 f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
344 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
345 f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
347 root_window = make_window ();
348 if (mini_p)
350 mini_window = make_window ();
351 XWINDOW (root_window)->next = mini_window;
352 XWINDOW (mini_window)->prev = root_window;
353 XWINDOW (mini_window)->mini_p = Qt;
354 XWINDOW (mini_window)->frame = frame;
355 f->minibuffer_window = mini_window;
357 else
359 mini_window = Qnil;
360 XWINDOW (root_window)->next = Qnil;
361 f->minibuffer_window = Qnil;
364 XWINDOW (root_window)->frame = frame;
366 /* 10 is arbitrary,
367 just so that there is "something there."
368 Correct size will be set up later with change_frame_size. */
370 SET_FRAME_WIDTH (f, 10);
371 f->height = 10;
373 XSETFASTINT (XWINDOW (root_window)->width, 10);
374 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
376 if (mini_p)
378 XSETFASTINT (XWINDOW (mini_window)->width, 10);
379 XSETFASTINT (XWINDOW (mini_window)->top, 9);
380 XSETFASTINT (XWINDOW (mini_window)->height, 1);
383 /* Choose a buffer for the frame's root window. */
385 Lisp_Object buf;
387 XWINDOW (root_window)->buffer = Qt;
388 buf = Fcurrent_buffer ();
389 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
390 a space), try to find another one. */
391 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
392 buf = Fother_buffer (buf, Qnil, Qnil);
394 /* Use set_window_buffer, not Fset_window_buffer, and don't let
395 hooks be run by it. The reason is that the whole frame/window
396 arrangement is not yet fully intialized at this point. Windows
397 don't have the right size, glyph matrices aren't initialized
398 etc. Running Lisp functions at this point surely ends in a
399 SEGV. */
400 set_window_buffer (root_window, buf, 0);
401 f->buffer_list = Fcons (buf, Qnil);
404 if (mini_p)
406 XWINDOW (mini_window)->buffer = Qt;
407 set_window_buffer (mini_window,
408 (NILP (Vminibuffer_list)
409 ? get_minibuffer (0)
410 : Fcar (Vminibuffer_list)),
414 f->root_window = root_window;
415 f->selected_window = root_window;
416 /* Make sure this window seems more recently used than
417 a newly-created, never-selected window. */
418 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
420 return f;
423 #ifdef HAVE_WINDOW_SYSTEM
424 /* Make a frame using a separate minibuffer window on another frame.
425 MINI_WINDOW is the minibuffer window to use. nil means use the
426 default (the global minibuffer). */
428 struct frame *
429 make_frame_without_minibuffer (mini_window, kb, display)
430 register Lisp_Object mini_window;
431 KBOARD *kb;
432 Lisp_Object display;
434 register struct frame *f;
435 struct gcpro gcpro1;
437 if (!NILP (mini_window))
438 CHECK_LIVE_WINDOW (mini_window, 0);
440 #ifdef MULTI_KBOARD
441 if (!NILP (mini_window)
442 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
443 error ("frame and minibuffer must be on the same display");
444 #endif
446 /* Make a frame containing just a root window. */
447 f = make_frame (0);
449 if (NILP (mini_window))
451 /* Use default-minibuffer-frame if possible. */
452 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
453 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
455 Lisp_Object frame_dummy;
457 XSETFRAME (frame_dummy, f);
458 GCPRO1 (frame_dummy);
459 /* If there's no minibuffer frame to use, create one. */
460 kb->Vdefault_minibuffer_frame =
461 call1 (intern ("make-initial-minibuffer-frame"), display);
462 UNGCPRO;
465 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
468 f->minibuffer_window = mini_window;
470 /* Make the chosen minibuffer window display the proper minibuffer,
471 unless it is already showing a minibuffer. */
472 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
473 Fset_window_buffer (mini_window,
474 (NILP (Vminibuffer_list)
475 ? get_minibuffer (0)
476 : Fcar (Vminibuffer_list)));
477 return f;
480 /* Make a frame containing only a minibuffer window. */
482 struct frame *
483 make_minibuffer_frame ()
485 /* First make a frame containing just a root window, no minibuffer. */
487 register struct frame *f = make_frame (0);
488 register Lisp_Object mini_window;
489 register Lisp_Object frame;
491 XSETFRAME (frame, f);
493 f->auto_raise = 0;
494 f->auto_lower = 0;
495 f->no_split = 1;
496 f->wants_modeline = 0;
497 f->has_minibuffer = 1;
499 /* Now label the root window as also being the minibuffer.
500 Avoid infinite looping on the window chain by marking next pointer
501 as nil. */
503 mini_window = f->minibuffer_window = f->root_window;
504 XWINDOW (mini_window)->mini_p = Qt;
505 XWINDOW (mini_window)->next = Qnil;
506 XWINDOW (mini_window)->prev = Qnil;
507 XWINDOW (mini_window)->frame = frame;
509 /* Put the proper buffer in that window. */
511 Fset_window_buffer (mini_window,
512 (NILP (Vminibuffer_list)
513 ? get_minibuffer (0)
514 : Fcar (Vminibuffer_list)));
515 return f;
517 #endif /* HAVE_WINDOW_SYSTEM */
519 /* Construct a frame that refers to the terminal (stdin and stdout). */
521 static int terminal_frame_count;
523 struct frame *
524 make_terminal_frame ()
526 register struct frame *f;
527 Lisp_Object frame;
528 char name[20];
530 #ifdef MULTI_KBOARD
531 if (!initial_kboard)
533 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
534 init_kboard (initial_kboard);
535 initial_kboard->next_kboard = all_kboards;
536 all_kboards = initial_kboard;
538 #endif
540 /* The first call must initialize Vframe_list. */
541 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
542 Vframe_list = Qnil;
544 f = make_frame (1);
546 XSETFRAME (frame, f);
547 Vframe_list = Fcons (frame, Vframe_list);
549 terminal_frame_count++;
550 sprintf (name, "F%d", terminal_frame_count);
551 f->name = build_string (name);
553 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
554 f->async_visible = 1; /* Don't let visible be cleared later. */
555 #ifdef MSDOS
556 f->output_data.x = &the_only_x_display;
557 if (!inhibit_window_system
558 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
559 || XFRAME (selected_frame)->output_method == output_msdos_raw))
560 f->output_method = output_msdos_raw;
561 else
562 f->output_method = output_termcap;
563 #else
564 #ifdef macintosh
565 f->output_data.mac = NewMacWindow(f);
566 f->output_data.mac->background_pixel = 0xffffff;
567 f->output_data.mac->foreground_pixel = 0;
568 f->output_data.mac->n_param_faces = 0;
569 f->output_data.mac->n_computed_faces = 0;
570 f->output_data.mac->size_computed_faces = 0;
571 f->output_method = output_mac;
572 f->auto_raise = 1;
573 f->auto_lower = 1;
574 init_frame_faces (f);
575 #else /* !macintosh */
576 f->output_data.x = &tty_display;
577 #endif /* !macintosh */
578 #endif /* MSDOS */
580 #ifndef macintosh
581 if (!noninteractive)
582 init_frame_faces (f);
583 #endif
584 return f;
587 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
588 1, 1, 0, "Create an additional terminal frame.\n\
589 You can create multiple frames on a text-only terminal in this way.\n\
590 Only the selected terminal frame is actually displayed.\n\
591 This function takes one argument, an alist specifying frame parameters.\n\
592 In practice, generally you don't need to specify any parameters.\n\
593 Note that changing the size of one terminal frame automatically affects all.")
594 (parms)
595 Lisp_Object parms;
597 struct frame *f;
598 Lisp_Object frame, tem;
599 struct frame *sf = SELECTED_FRAME ();
601 #ifdef MSDOS
602 if (sf->output_method != output_msdos_raw
603 && sf->output_method != output_termcap)
604 abort ();
605 #else /* not MSDOS */
607 #ifdef macintosh
608 if (sf->output_method != output_mac)
609 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
610 #else
611 if (sf->output_method != output_termcap)
612 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
613 #endif
614 #endif /* not MSDOS */
616 f = make_terminal_frame ();
618 change_frame_size (f, FRAME_HEIGHT (sf),
619 FRAME_WIDTH (sf), 0, 0, 0);
620 adjust_glyphs (f);
621 calculate_costs (f);
622 XSETFRAME (frame, f);
623 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
624 Fmodify_frame_parameters (frame, parms);
626 /* Make the frame face alist be frame-specific, so that each
627 frame could change its face definitions independently. */
628 f->face_alist = Fcopy_alist (sf->face_alist);
629 /* Simple Fcopy_alist isn't enough, because we need the contents of
630 the vectors which are the CDRs of associations in face_alist to
631 be copied as well. */
632 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
633 XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
634 return frame;
637 Lisp_Object
638 do_switch_frame (frame, no_enter, track)
639 Lisp_Object frame, no_enter;
640 int track;
642 struct frame *sf = SELECTED_FRAME ();
644 /* If FRAME is a switch-frame event, extract the frame we should
645 switch to. */
646 if (CONSP (frame)
647 && EQ (XCAR (frame), Qswitch_frame)
648 && CONSP (XCDR (frame)))
649 frame = XCAR (XCDR (frame));
651 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
652 a switch-frame event to arrive after a frame is no longer live,
653 especially when deleting the initial frame during startup. */
654 CHECK_FRAME (frame, 0);
655 if (! FRAME_LIVE_P (XFRAME (frame)))
656 return Qnil;
658 if (sf == XFRAME (frame))
659 return frame;
661 /* This is too greedy; it causes inappropriate focus redirection
662 that's hard to get rid of. */
663 #if 0
664 /* If a frame's focus has been redirected toward the currently
665 selected frame, we should change the redirection to point to the
666 newly selected frame. This means that if the focus is redirected
667 from a minibufferless frame to a surrogate minibuffer frame, we
668 can use `other-window' to switch between all the frames using
669 that minibuffer frame, and the focus redirection will follow us
670 around. */
671 if (track)
673 Lisp_Object tail;
675 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
677 Lisp_Object focus;
679 if (!FRAMEP (XCAR (tail)))
680 abort ();
682 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
684 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
685 Fredirect_frame_focus (XCAR (tail), frame);
688 #else /* ! 0 */
689 /* Instead, apply it only to the frame we're pointing to. */
690 #ifdef HAVE_WINDOW_SYSTEM
691 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
693 Lisp_Object focus, xfocus;
695 xfocus = x_get_focus_frame (XFRAME (frame));
696 if (FRAMEP (xfocus))
698 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
699 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
700 Fredirect_frame_focus (xfocus, frame);
703 #endif /* HAVE_X_WINDOWS */
704 #endif /* ! 0 */
706 selected_frame = frame;
707 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
708 last_nonminibuf_frame = XFRAME (selected_frame);
710 Fselect_window (XFRAME (frame)->selected_window);
712 /* We want to make sure that the next event generates a frame-switch
713 event to the appropriate frame. This seems kludgy to me, but
714 before you take it out, make sure that evaluating something like
715 (select-window (frame-root-window (new-frame))) doesn't end up
716 with your typing being interpreted in the new frame instead of
717 the one you're actually typing in. */
718 internal_last_event_frame = Qnil;
720 return frame;
723 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
724 "Select the frame FRAME.\n\
725 Subsequent editing commands apply to its selected window.\n\
726 The selection of FRAME lasts until the next time the user does\n\
727 something to select a different frame, or until the next time this\n\
728 function is called.")
729 (frame, no_enter)
730 Lisp_Object frame, no_enter;
732 return do_switch_frame (frame, no_enter, 1);
736 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
737 "Handle a switch-frame event EVENT.\n\
738 Switch-frame events are usually bound to this function.\n\
739 A switch-frame event tells Emacs that the window manager has requested\n\
740 that the user's events be directed to the frame mentioned in the event.\n\
741 This function selects the selected window of the frame of EVENT.\n\
743 If EVENT is frame object, handle it as if it were a switch-frame event\n\
744 to that frame.")
745 (event, no_enter)
746 Lisp_Object event, no_enter;
748 /* Preserve prefix arg that the command loop just cleared. */
749 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
750 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
751 return do_switch_frame (event, no_enter, 0);
754 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
755 "Do nothing, but preserve any prefix argument already specified.\n\
756 This is a suitable binding for iconify-frame and make-frame-visible.")
759 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
760 return Qnil;
763 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
764 "Return the frame that is now selected.")
767 return selected_frame;
770 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
771 "Return the frame object that window WINDOW is on.")
772 (window)
773 Lisp_Object window;
775 CHECK_LIVE_WINDOW (window, 0);
776 return XWINDOW (window)->frame;
779 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
780 "Returns the topmost, leftmost window of FRAME.\n\
781 If omitted, FRAME defaults to the currently selected frame.")
782 (frame)
783 Lisp_Object frame;
785 Lisp_Object w;
787 if (NILP (frame))
788 w = SELECTED_FRAME ()->root_window;
789 else
791 CHECK_LIVE_FRAME (frame, 0);
792 w = XFRAME (frame)->root_window;
794 while (NILP (XWINDOW (w)->buffer))
796 if (! NILP (XWINDOW (w)->hchild))
797 w = XWINDOW (w)->hchild;
798 else if (! NILP (XWINDOW (w)->vchild))
799 w = XWINDOW (w)->vchild;
800 else
801 abort ();
803 return w;
806 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
807 Sactive_minibuffer_window, 0, 0, 0,
808 "Return the currently active minibuffer window, or nil if none.")
811 return minibuf_level ? minibuf_window : Qnil;
814 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
815 "Returns the root-window of FRAME.\n\
816 If omitted, FRAME defaults to the currently selected frame.")
817 (frame)
818 Lisp_Object frame;
820 Lisp_Object window;
822 if (NILP (frame))
823 window = SELECTED_FRAME ()->root_window;
824 else
826 CHECK_LIVE_FRAME (frame, 0);
827 window = XFRAME (frame)->root_window;
830 return window;
833 DEFUN ("frame-selected-window", Fframe_selected_window,
834 Sframe_selected_window, 0, 1, 0,
835 "Return the selected window of frame object FRAME.\n\
836 If omitted, FRAME defaults to the currently selected frame.")
837 (frame)
838 Lisp_Object frame;
840 Lisp_Object window;
842 if (NILP (frame))
843 window = SELECTED_FRAME ()->selected_window;
844 else
846 CHECK_LIVE_FRAME (frame, 0);
847 window = XFRAME (frame)->selected_window;
850 return window;
853 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
854 Sset_frame_selected_window, 2, 2, 0,
855 "Set the selected window of frame object FRAME to WINDOW.\n\
856 If FRAME is nil, the selected frame is used.\n\
857 If FRAME is the selected frame, this makes WINDOW the selected window.")
858 (frame, window)
859 Lisp_Object frame, window;
861 if (NILP (frame))
862 frame = selected_frame;
864 CHECK_LIVE_FRAME (frame, 0);
865 CHECK_LIVE_WINDOW (window, 1);
867 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
868 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
870 if (EQ (frame, selected_frame))
871 return Fselect_window (window);
873 return XFRAME (frame)->selected_window = window;
876 DEFUN ("frame-list", Fframe_list, Sframe_list,
877 0, 0, 0,
878 "Return a list of all frames.")
881 return Fcopy_sequence (Vframe_list);
884 /* Return the next frame in the frame list after FRAME.
885 If MINIBUF is nil, exclude minibuffer-only frames.
886 If MINIBUF is a window, include only its own frame
887 and any frame now using that window as the minibuffer.
888 If MINIBUF is `visible', include all visible frames.
889 If MINIBUF is 0, include all visible and iconified frames.
890 Otherwise, include all frames. */
892 Lisp_Object
893 next_frame (frame, minibuf)
894 Lisp_Object frame;
895 Lisp_Object minibuf;
897 Lisp_Object tail;
898 int passed = 0;
900 /* There must always be at least one frame in Vframe_list. */
901 if (! CONSP (Vframe_list))
902 abort ();
904 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
905 forever. Forestall that. */
906 CHECK_LIVE_FRAME (frame, 0);
908 while (1)
909 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
911 Lisp_Object f;
913 f = XCAR (tail);
915 if (passed
916 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
918 /* Decide whether this frame is eligible to be returned. */
920 /* If we've looped all the way around without finding any
921 eligible frames, return the original frame. */
922 if (EQ (f, frame))
923 return f;
925 /* Let minibuf decide if this frame is acceptable. */
926 if (NILP (minibuf))
928 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
929 return f;
931 else if (EQ (minibuf, Qvisible))
933 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
934 if (FRAME_VISIBLE_P (XFRAME (f)))
935 return f;
937 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
939 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
940 if (FRAME_VISIBLE_P (XFRAME (f))
941 || FRAME_ICONIFIED_P (XFRAME (f)))
942 return f;
944 else if (WINDOWP (minibuf))
946 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
947 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
948 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
949 FRAME_FOCUS_FRAME (XFRAME (f))))
950 return f;
952 else
953 return f;
956 if (EQ (frame, f))
957 passed++;
961 /* Return the previous frame in the frame list before FRAME.
962 If MINIBUF is nil, exclude minibuffer-only frames.
963 If MINIBUF is a window, include only its own frame
964 and any frame now using that window as the minibuffer.
965 If MINIBUF is `visible', include all visible frames.
966 If MINIBUF is 0, include all visible and iconified frames.
967 Otherwise, include all frames. */
969 Lisp_Object
970 prev_frame (frame, minibuf)
971 Lisp_Object frame;
972 Lisp_Object minibuf;
974 Lisp_Object tail;
975 Lisp_Object prev;
977 /* There must always be at least one frame in Vframe_list. */
978 if (! CONSP (Vframe_list))
979 abort ();
981 prev = Qnil;
982 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
984 Lisp_Object f;
986 f = XCAR (tail);
987 if (!FRAMEP (f))
988 abort ();
990 if (EQ (frame, f) && !NILP (prev))
991 return prev;
993 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
995 /* Decide whether this frame is eligible to be returned,
996 according to minibuf. */
997 if (NILP (minibuf))
999 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1000 prev = f;
1002 else if (WINDOWP (minibuf))
1004 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1005 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1006 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1007 FRAME_FOCUS_FRAME (XFRAME (f))))
1008 prev = f;
1010 else if (EQ (minibuf, Qvisible))
1012 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1013 if (FRAME_VISIBLE_P (XFRAME (f)))
1014 prev = f;
1016 else if (XFASTINT (minibuf) == 0)
1018 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1019 if (FRAME_VISIBLE_P (XFRAME (f))
1020 || FRAME_ICONIFIED_P (XFRAME (f)))
1021 prev = f;
1023 else
1024 prev = f;
1028 /* We've scanned the entire list. */
1029 if (NILP (prev))
1030 /* We went through the whole frame list without finding a single
1031 acceptable frame. Return the original frame. */
1032 return frame;
1033 else
1034 /* There were no acceptable frames in the list before FRAME; otherwise,
1035 we would have returned directly from the loop. Since PREV is the last
1036 acceptable frame in the list, return it. */
1037 return prev;
1041 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1042 "Return the next frame in the frame list after FRAME.\n\
1043 It considers only frames on the same terminal as FRAME.\n\
1044 By default, skip minibuffer-only frames.\n\
1045 If omitted, FRAME defaults to the selected frame.\n\
1046 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1047 If MINIFRAME is a window, include only its own frame\n\
1048 and any frame now using that window as the minibuffer.\n\
1049 If MINIFRAME is `visible', include all visible frames.\n\
1050 If MINIFRAME is 0, include all visible and iconified frames.\n\
1051 Otherwise, include all frames.")
1052 (frame, miniframe)
1053 Lisp_Object frame, miniframe;
1055 if (NILP (frame))
1056 frame = selected_frame;
1058 CHECK_LIVE_FRAME (frame, 0);
1059 return next_frame (frame, miniframe);
1062 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1063 "Return the previous frame in the frame list before FRAME.\n\
1064 It considers only frames on the same terminal as FRAME.\n\
1065 By default, skip minibuffer-only frames.\n\
1066 If omitted, FRAME defaults to the selected frame.\n\
1067 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1068 If MINIFRAME is a window, include only its own frame\n\
1069 and any frame now using that window as the minibuffer.\n\
1070 If MINIFRAME is `visible', include all visible frames.\n\
1071 If MINIFRAME is 0, include all visible and iconified frames.\n\
1072 Otherwise, include all frames.")
1073 (frame, miniframe)
1074 Lisp_Object frame, miniframe;
1076 if (NILP (frame))
1077 frame = selected_frame;
1078 CHECK_LIVE_FRAME (frame, 0);
1079 return prev_frame (frame, miniframe);
1082 /* Return 1 if it is ok to delete frame F;
1083 0 if all frames aside from F are invisible.
1084 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1087 other_visible_frames (f)
1088 FRAME_PTR f;
1090 /* We know the selected frame is visible,
1091 so if F is some other frame, it can't be the sole visible one. */
1092 if (f == SELECTED_FRAME ())
1094 Lisp_Object frames;
1095 int count = 0;
1097 for (frames = Vframe_list;
1098 CONSP (frames);
1099 frames = XCDR (frames))
1101 Lisp_Object this;
1103 this = XCAR (frames);
1104 /* Verify that the frame's window still exists
1105 and we can still talk to it. And note any recent change
1106 in visibility. */
1107 #ifdef HAVE_WINDOW_SYSTEM
1108 if (FRAME_WINDOW_P (XFRAME (this)))
1110 x_sync (XFRAME (this));
1111 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1113 #endif
1115 if (FRAME_VISIBLE_P (XFRAME (this))
1116 || FRAME_ICONIFIED_P (XFRAME (this))
1117 /* Allow deleting the terminal frame when at least
1118 one X frame exists! */
1119 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1120 count++;
1122 return count > 1;
1124 return 1;
1127 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1128 "Delete FRAME, permanently eliminating it from use.\n\
1129 If omitted, FRAME defaults to the selected frame.\n\
1130 A frame may not be deleted if its minibuffer is used by other frames.\n\
1131 Normally, you may not delete a frame if all other frames are invisible,\n\
1132 but if the second optional argument FORCE is non-nil, you may do so.")
1133 (frame, force)
1134 Lisp_Object frame, force;
1136 struct frame *f;
1137 struct frame *sf = SELECTED_FRAME ();
1138 int minibuffer_selected;
1140 if (EQ (frame, Qnil))
1142 f = sf;
1143 XSETFRAME (frame, f);
1145 else
1147 CHECK_FRAME (frame, 0);
1148 f = XFRAME (frame);
1151 if (! FRAME_LIVE_P (f))
1152 return Qnil;
1154 if (NILP (force) && !other_visible_frames (f))
1155 error ("Attempt to delete the sole visible or iconified frame");
1157 #if 0
1158 /* This is a nice idea, but x_connection_closed needs to be able
1159 to delete the last frame, if it is gone. */
1160 if (NILP (XCDR (Vframe_list)))
1161 error ("Attempt to delete the only frame");
1162 #endif
1164 /* Does this frame have a minibuffer, and is it the surrogate
1165 minibuffer for any other frame? */
1166 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1168 Lisp_Object frames;
1170 for (frames = Vframe_list;
1171 CONSP (frames);
1172 frames = XCDR (frames))
1174 Lisp_Object this;
1175 this = XCAR (frames);
1177 if (! EQ (this, frame)
1178 && EQ (frame,
1179 WINDOW_FRAME (XWINDOW
1180 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1181 error ("Attempt to delete a surrogate minibuffer frame");
1185 minibuffer_selected = EQ (minibuf_window, selected_window);
1187 /* Don't let the frame remain selected. */
1188 if (f == sf)
1190 Lisp_Object tail, frame1;
1192 /* Look for another visible frame on the same terminal. */
1193 frame1 = next_frame (frame, Qvisible);
1195 /* If there is none, find *some* other frame. */
1196 if (NILP (frame1) || EQ (frame1, frame))
1198 FOR_EACH_FRAME (tail, frame1)
1200 if (! EQ (frame, frame1))
1201 break;
1205 do_switch_frame (frame1, Qnil, 0);
1206 sf = SELECTED_FRAME ();
1209 /* Don't allow minibuf_window to remain on a deleted frame. */
1210 if (EQ (f->minibuffer_window, minibuf_window))
1212 Fset_window_buffer (sf->minibuffer_window,
1213 XWINDOW (minibuf_window)->buffer);
1214 minibuf_window = sf->minibuffer_window;
1216 /* If the dying minibuffer window was selected,
1217 select the new one. */
1218 if (minibuffer_selected)
1219 Fselect_window (minibuf_window);
1222 /* Don't let echo_area_window to remain on a deleted frame. */
1223 if (EQ (f->minibuffer_window, echo_area_window))
1224 echo_area_window = sf->minibuffer_window;
1226 /* Clear any X selections for this frame. */
1227 #ifdef HAVE_X_WINDOWS
1228 if (FRAME_X_P (f))
1229 x_clear_frame_selections (f);
1230 #endif
1232 /* Free glyphs.
1233 This function must be called before the window tree of the
1234 frame is deleted because windows contain dynamically allocated
1235 memory. */
1236 free_glyphs (f);
1238 /* Mark all the windows that used to be on FRAME as deleted, and then
1239 remove the reference to them. */
1240 delete_all_subwindows (XWINDOW (f->root_window));
1241 f->root_window = Qnil;
1243 Vframe_list = Fdelq (frame, Vframe_list);
1244 FRAME_SET_VISIBLE (f, 0);
1246 if (f->namebuf)
1247 xfree (f->namebuf);
1248 if (FRAME_INSERT_COST (f))
1249 xfree (FRAME_INSERT_COST (f));
1250 if (FRAME_DELETEN_COST (f))
1251 xfree (FRAME_DELETEN_COST (f));
1252 if (FRAME_INSERTN_COST (f))
1253 xfree (FRAME_INSERTN_COST (f));
1254 if (FRAME_DELETE_COST (f))
1255 xfree (FRAME_DELETE_COST (f));
1256 if (FRAME_MESSAGE_BUF (f))
1257 xfree (FRAME_MESSAGE_BUF (f));
1259 /* Since some events are handled at the interrupt level, we may get
1260 an event for f at any time; if we zero out the frame's display
1261 now, then we may trip up the event-handling code. Instead, we'll
1262 promise that the display of the frame must be valid until we have
1263 called the window-system-dependent frame destruction routine. */
1265 /* I think this should be done with a hook. */
1266 #ifdef HAVE_WINDOW_SYSTEM
1267 if (FRAME_WINDOW_P (f))
1268 x_destroy_window (f);
1269 #endif
1271 /* Done by x_destroy_window above already */
1272 #if 0
1273 #ifdef macintosh
1274 if (FRAME_MAC_P (f))
1275 DisposeMacWindow (f->output_data.mac);
1276 #endif
1277 #endif
1279 f->output_data.nothing = 0;
1281 /* If we've deleted the last_nonminibuf_frame, then try to find
1282 another one. */
1283 if (f == last_nonminibuf_frame)
1285 Lisp_Object frames;
1287 last_nonminibuf_frame = 0;
1289 for (frames = Vframe_list;
1290 CONSP (frames);
1291 frames = XCDR (frames))
1293 f = XFRAME (XCAR (frames));
1294 if (!FRAME_MINIBUF_ONLY_P (f))
1296 last_nonminibuf_frame = f;
1297 break;
1302 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1303 find another one. Prefer minibuffer-only frames, but also notice
1304 frames with other windows. */
1305 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1307 Lisp_Object frames;
1309 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1310 Lisp_Object frame_with_minibuf;
1311 /* Some frame we found on the same kboard, or nil if there are none. */
1312 Lisp_Object frame_on_same_kboard;
1314 frame_on_same_kboard = Qnil;
1315 frame_with_minibuf = Qnil;
1317 for (frames = Vframe_list;
1318 CONSP (frames);
1319 frames = XCDR (frames))
1321 Lisp_Object this;
1322 struct frame *f1;
1324 this = XCAR (frames);
1325 if (!FRAMEP (this))
1326 abort ();
1327 f1 = XFRAME (this);
1329 /* Consider only frames on the same kboard
1330 and only those with minibuffers. */
1331 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1332 && FRAME_HAS_MINIBUF_P (f1))
1334 frame_with_minibuf = this;
1335 if (FRAME_MINIBUF_ONLY_P (f1))
1336 break;
1339 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1340 frame_on_same_kboard = this;
1343 if (!NILP (frame_on_same_kboard))
1345 /* We know that there must be some frame with a minibuffer out
1346 there. If this were not true, all of the frames present
1347 would have to be minibufferless, which implies that at some
1348 point their minibuffer frames must have been deleted, but
1349 that is prohibited at the top; you can't delete surrogate
1350 minibuffer frames. */
1351 if (NILP (frame_with_minibuf))
1352 abort ();
1354 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1356 else
1357 /* No frames left on this kboard--say no minibuffer either. */
1358 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1361 /* Cause frame titles to update--necessary if we now have just one frame. */
1362 update_mode_lines = 1;
1364 return Qnil;
1367 /* Return mouse position in character cell units. */
1369 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1370 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1371 The position is given in character cells, where (0, 0) is the\n\
1372 upper-left corner.\n\
1373 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1374 to read the mouse position, it returns the selected frame for FRAME\n\
1375 and nil for X and Y.\n\
1376 Runs the abnormal hook `mouse-position-function' with the normal return\n\
1377 value as argument.")
1380 FRAME_PTR f;
1381 Lisp_Object lispy_dummy;
1382 enum scroll_bar_part party_dummy;
1383 Lisp_Object x, y, retval;
1384 int col, row;
1385 unsigned long long_dummy;
1386 struct gcpro gcpro1;
1388 f = SELECTED_FRAME ();
1389 x = y = Qnil;
1391 #ifdef HAVE_MOUSE
1392 /* It's okay for the hook to refrain from storing anything. */
1393 if (mouse_position_hook)
1394 (*mouse_position_hook) (&f, -1,
1395 &lispy_dummy, &party_dummy,
1396 &x, &y,
1397 &long_dummy);
1398 if (! NILP (x))
1400 col = XINT (x);
1401 row = XINT (y);
1402 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1403 XSETINT (x, col);
1404 XSETINT (y, row);
1406 #endif
1407 XSETFRAME (lispy_dummy, f);
1408 retval = Fcons (lispy_dummy, Fcons (x, y));
1409 GCPRO1 (retval);
1410 if (!NILP (Vmouse_position_function))
1411 retval = call1 (Vmouse_position_function, retval);
1412 RETURN_UNGCPRO (retval);
1415 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1416 Smouse_pixel_position, 0, 0, 0,
1417 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1418 The position is given in pixel units, where (0, 0) is the\n\
1419 upper-left corner.\n\
1420 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1421 to read the mouse position, it returns the selected frame for FRAME\n\
1422 and nil for X and Y.")
1425 FRAME_PTR f;
1426 Lisp_Object lispy_dummy;
1427 enum scroll_bar_part party_dummy;
1428 Lisp_Object x, y;
1429 unsigned long long_dummy;
1431 f = SELECTED_FRAME ();
1432 x = y = Qnil;
1434 #ifdef HAVE_MOUSE
1435 /* It's okay for the hook to refrain from storing anything. */
1436 if (mouse_position_hook)
1437 (*mouse_position_hook) (&f, -1,
1438 &lispy_dummy, &party_dummy,
1439 &x, &y,
1440 &long_dummy);
1441 #endif
1442 XSETFRAME (lispy_dummy, f);
1443 return Fcons (lispy_dummy, Fcons (x, y));
1446 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1447 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1448 Coordinates are relative to the frame, not a window,\n\
1449 so the coordinates of the top left character in the frame\n\
1450 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1452 This function is a no-op for an X frame that is not visible.\n\
1453 If you have just created a frame, you must wait for it to become visible\n\
1454 before calling this function on it, like this.\n\
1455 (while (not (frame-visible-p frame)) (sleep-for .5))")
1456 (frame, x, y)
1457 Lisp_Object frame, x, y;
1459 CHECK_LIVE_FRAME (frame, 0);
1460 CHECK_NUMBER (x, 2);
1461 CHECK_NUMBER (y, 1);
1463 /* I think this should be done with a hook. */
1464 #ifdef HAVE_WINDOW_SYSTEM
1465 if (FRAME_WINDOW_P (XFRAME (frame)))
1466 /* Warping the mouse will cause enternotify and focus events. */
1467 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1468 #else
1469 #if defined (MSDOS) && defined (HAVE_MOUSE)
1470 if (FRAME_MSDOS_P (XFRAME (frame)))
1472 Fselect_frame (frame, Qnil);
1473 mouse_moveto (XINT (x), XINT (y));
1475 #endif
1476 #endif
1478 return Qnil;
1481 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1482 Sset_mouse_pixel_position, 3, 3, 0,
1483 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1484 Note, this is a no-op for an X frame that is not visible.\n\
1485 If you have just created a frame, you must wait for it to become visible\n\
1486 before calling this function on it, like this.\n\
1487 (while (not (frame-visible-p frame)) (sleep-for .5))")
1488 (frame, x, y)
1489 Lisp_Object frame, x, y;
1491 CHECK_LIVE_FRAME (frame, 0);
1492 CHECK_NUMBER (x, 2);
1493 CHECK_NUMBER (y, 1);
1495 /* I think this should be done with a hook. */
1496 #ifdef HAVE_WINDOW_SYSTEM
1497 if (FRAME_WINDOW_P (XFRAME (frame)))
1498 /* Warping the mouse will cause enternotify and focus events. */
1499 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1500 #else
1501 #if defined (MSDOS) && defined (HAVE_MOUSE)
1502 if (FRAME_MSDOS_P (XFRAME (frame)))
1504 Fselect_frame (frame, Qnil);
1505 mouse_moveto (XINT (x), XINT (y));
1507 #endif
1508 #endif
1510 return Qnil;
1513 static void make_frame_visible_1 P_ ((Lisp_Object));
1515 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1516 0, 1, "",
1517 "Make the frame FRAME visible (assuming it is an X-window).\n\
1518 If omitted, FRAME defaults to the currently selected frame.")
1519 (frame)
1520 Lisp_Object frame;
1522 if (NILP (frame))
1523 frame = selected_frame;
1525 CHECK_LIVE_FRAME (frame, 0);
1527 /* I think this should be done with a hook. */
1528 #ifdef HAVE_WINDOW_SYSTEM
1529 if (FRAME_WINDOW_P (XFRAME (frame)))
1531 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1532 x_make_frame_visible (XFRAME (frame));
1534 #endif
1536 make_frame_visible_1 (XFRAME (frame)->root_window);
1538 /* Make menu bar update for the Buffers and Frams menus. */
1539 windows_or_buffers_changed++;
1541 return frame;
1544 /* Update the display_time slot of the buffers shown in WINDOW
1545 and all its descendents. */
1547 static void
1548 make_frame_visible_1 (window)
1549 Lisp_Object window;
1551 struct window *w;
1553 for (;!NILP (window); window = w->next)
1555 w = XWINDOW (window);
1557 if (!NILP (w->buffer))
1558 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1560 if (!NILP (w->vchild))
1561 make_frame_visible_1 (w->vchild);
1562 if (!NILP (w->hchild))
1563 make_frame_visible_1 (w->hchild);
1567 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1568 0, 2, "",
1569 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1570 If omitted, FRAME defaults to the currently selected frame.\n\
1571 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1572 but if the second optional argument FORCE is non-nil, you may do so.")
1573 (frame, force)
1574 Lisp_Object frame, force;
1576 if (NILP (frame))
1577 frame = selected_frame;
1579 CHECK_LIVE_FRAME (frame, 0);
1581 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1582 error ("Attempt to make invisible the sole visible or iconified frame");
1584 #if 0 /* This isn't logically necessary, and it can do GC. */
1585 /* Don't let the frame remain selected. */
1586 if (EQ (frame, selected_frame))
1587 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1588 #endif
1590 /* Don't allow minibuf_window to remain on a deleted frame. */
1591 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1593 struct frame *sf = XFRAME (selected_frame);
1594 Fset_window_buffer (sf->minibuffer_window,
1595 XWINDOW (minibuf_window)->buffer);
1596 minibuf_window = sf->minibuffer_window;
1599 /* I think this should be done with a hook. */
1600 #ifdef HAVE_WINDOW_SYSTEM
1601 if (FRAME_WINDOW_P (XFRAME (frame)))
1602 x_make_frame_invisible (XFRAME (frame));
1603 #endif
1605 /* Make menu bar update for the Buffers and Frams menus. */
1606 windows_or_buffers_changed++;
1608 return Qnil;
1611 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1612 0, 1, "",
1613 "Make the frame FRAME into an icon.\n\
1614 If omitted, FRAME defaults to the currently selected frame.")
1615 (frame)
1616 Lisp_Object frame;
1618 if (NILP (frame))
1619 frame = selected_frame;
1621 CHECK_LIVE_FRAME (frame, 0);
1623 #if 0 /* This isn't logically necessary, and it can do GC. */
1624 /* Don't let the frame remain selected. */
1625 if (EQ (frame, selected_frame))
1626 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1627 #endif
1629 /* Don't allow minibuf_window to remain on a deleted frame. */
1630 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1632 struct frame *sf = XFRAME (selected_frame);
1633 Fset_window_buffer (sf->minibuffer_window,
1634 XWINDOW (minibuf_window)->buffer);
1635 minibuf_window = sf->minibuffer_window;
1638 /* I think this should be done with a hook. */
1639 #ifdef HAVE_WINDOW_SYSTEM
1640 if (FRAME_WINDOW_P (XFRAME (frame)))
1641 x_iconify_frame (XFRAME (frame));
1642 #endif
1644 /* Make menu bar update for the Buffers and Frams menus. */
1645 windows_or_buffers_changed++;
1647 return Qnil;
1650 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1651 1, 1, 0,
1652 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1653 A frame that is not \"visible\" is not updated and, if it works through\n\
1654 a window system, it may not show at all.\n\
1655 Return the symbol `icon' if frame is visible only as an icon.")
1656 (frame)
1657 Lisp_Object frame;
1659 CHECK_LIVE_FRAME (frame, 0);
1661 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1663 if (FRAME_VISIBLE_P (XFRAME (frame)))
1664 return Qt;
1665 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1666 return Qicon;
1667 return Qnil;
1670 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1671 0, 0, 0,
1672 "Return a list of all frames now \"visible\" (being updated).")
1675 Lisp_Object tail, frame;
1676 struct frame *f;
1677 Lisp_Object value;
1679 value = Qnil;
1680 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1682 frame = XCAR (tail);
1683 if (!FRAMEP (frame))
1684 continue;
1685 f = XFRAME (frame);
1686 if (FRAME_VISIBLE_P (f))
1687 value = Fcons (frame, value);
1689 return value;
1693 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1694 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1695 If FRAME is invisible, make it visible.\n\
1696 If you don't specify a frame, the selected frame is used.\n\
1697 If Emacs is displaying on an ordinary terminal or some other device which\n\
1698 doesn't support multiple overlapping frames, this function does nothing.")
1699 (frame)
1700 Lisp_Object frame;
1702 if (NILP (frame))
1703 frame = selected_frame;
1705 CHECK_LIVE_FRAME (frame, 0);
1707 /* Do like the documentation says. */
1708 Fmake_frame_visible (frame);
1710 if (frame_raise_lower_hook)
1711 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1713 return Qnil;
1716 /* Should we have a corresponding function called Flower_Power? */
1717 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1718 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1719 If you don't specify a frame, the selected frame is used.\n\
1720 If Emacs is displaying on an ordinary terminal or some other device which\n\
1721 doesn't support multiple overlapping frames, this function does nothing.")
1722 (frame)
1723 Lisp_Object frame;
1725 if (NILP (frame))
1726 frame = selected_frame;
1728 CHECK_LIVE_FRAME (frame, 0);
1730 if (frame_raise_lower_hook)
1731 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1733 return Qnil;
1737 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1738 1, 2, 0,
1739 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1740 In other words, switch-frame events caused by events in FRAME will\n\
1741 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1742 FOCUS-FRAME after reading an event typed at FRAME.\n\
1744 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1745 cancelled, and the frame again receives its own keystrokes.\n\
1747 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1748 a surrogate minibuffer frame when a frame doesn't have its own\n\
1749 minibuffer window.\n\
1751 A frame's focus redirection can be changed by select-frame. If frame\n\
1752 FOO is selected, and then a different frame BAR is selected, any\n\
1753 frames redirecting their focus to FOO are shifted to redirect their\n\
1754 focus to BAR. This allows focus redirection to work properly when the\n\
1755 user switches from one frame to another using `select-window'.\n\
1757 This means that a frame whose focus is redirected to itself is treated\n\
1758 differently from a frame whose focus is redirected to nil; the former\n\
1759 is affected by select-frame, while the latter is not.\n\
1761 The redirection lasts until `redirect-frame-focus' is called to change it.")
1762 (frame, focus_frame)
1763 Lisp_Object frame, focus_frame;
1765 /* Note that we don't check for a live frame here. It's reasonable
1766 to redirect the focus of a frame you're about to delete, if you
1767 know what other frame should receive those keystrokes. */
1768 CHECK_FRAME (frame, 0);
1770 if (! NILP (focus_frame))
1771 CHECK_LIVE_FRAME (focus_frame, 1);
1773 XFRAME (frame)->focus_frame = focus_frame;
1775 if (frame_rehighlight_hook)
1776 (*frame_rehighlight_hook) (XFRAME (frame));
1778 return Qnil;
1782 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1783 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1784 This returns nil if FRAME's focus is not redirected.\n\
1785 See `redirect-frame-focus'.")
1786 (frame)
1787 Lisp_Object frame;
1789 CHECK_LIVE_FRAME (frame, 0);
1791 return FRAME_FOCUS_FRAME (XFRAME (frame));
1796 /* Return the value of frame parameter PROP in frame FRAME. */
1798 Lisp_Object
1799 get_frame_param (frame, prop)
1800 register struct frame *frame;
1801 Lisp_Object prop;
1803 register Lisp_Object tem;
1805 tem = Fassq (prop, frame->param_alist);
1806 if (EQ (tem, Qnil))
1807 return tem;
1808 return Fcdr (tem);
1811 /* Return the buffer-predicate of the selected frame. */
1813 Lisp_Object
1814 frame_buffer_predicate (frame)
1815 Lisp_Object frame;
1817 return XFRAME (frame)->buffer_predicate;
1820 /* Return the buffer-list of the selected frame. */
1822 Lisp_Object
1823 frame_buffer_list (frame)
1824 Lisp_Object frame;
1826 return XFRAME (frame)->buffer_list;
1829 /* Set the buffer-list of the selected frame. */
1831 void
1832 set_frame_buffer_list (frame, list)
1833 Lisp_Object frame, list;
1835 XFRAME (frame)->buffer_list = list;
1838 /* Discard BUFFER from the buffer-list of each frame. */
1840 void
1841 frames_discard_buffer (buffer)
1842 Lisp_Object buffer;
1844 Lisp_Object frame, tail;
1846 FOR_EACH_FRAME (tail, frame)
1848 XFRAME (frame)->buffer_list
1849 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1853 /* Move BUFFER to the end of the buffer-list of each frame. */
1855 void
1856 frames_bury_buffer (buffer)
1857 Lisp_Object buffer;
1859 Lisp_Object frame, tail;
1861 FOR_EACH_FRAME (tail, frame)
1863 struct frame *f = XFRAME (frame);
1864 Lisp_Object found;
1866 found = Fmemq (buffer, f->buffer_list);
1867 if (!NILP (found))
1868 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1869 Fcons (buffer, Qnil));
1873 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1874 If the alist already has an element for PROP, we change it. */
1876 void
1877 store_in_alist (alistptr, prop, val)
1878 Lisp_Object *alistptr, val;
1879 Lisp_Object prop;
1881 register Lisp_Object tem;
1883 tem = Fassq (prop, *alistptr);
1884 if (EQ (tem, Qnil))
1885 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1886 else
1887 Fsetcdr (tem, val);
1890 static int
1891 frame_name_fnn_p (str, len)
1892 char *str;
1893 int len;
1895 if (len > 1 && str[0] == 'F')
1897 char *end_ptr;
1899 strtol (str + 1, &end_ptr, 10);
1901 if (end_ptr == str + len)
1902 return 1;
1904 return 0;
1907 /* Set the name of the terminal frame. Also used by MSDOS frames.
1908 Modeled after x_set_name which is used for WINDOW frames. */
1910 void
1911 set_term_frame_name (f, name)
1912 struct frame *f;
1913 Lisp_Object name;
1915 f->explicit_name = ! NILP (name);
1917 /* If NAME is nil, set the name to F<num>. */
1918 if (NILP (name))
1920 char namebuf[20];
1922 /* Check for no change needed in this very common case
1923 before we do any consing. */
1924 if (frame_name_fnn_p (XSTRING (f->name)->data,
1925 STRING_BYTES (XSTRING (f->name))))
1926 return;
1928 terminal_frame_count++;
1929 sprintf (namebuf, "F%d", terminal_frame_count);
1930 name = build_string (namebuf);
1932 else
1934 CHECK_STRING (name, 0);
1936 /* Don't change the name if it's already NAME. */
1937 if (! NILP (Fstring_equal (name, f->name)))
1938 return;
1940 /* Don't allow the user to set the frame name to F<num>, so it
1941 doesn't clash with the names we generate for terminal frames. */
1942 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1943 error ("Frame names of the form F<num> are usurped by Emacs");
1946 f->name = name;
1947 update_mode_lines = 1;
1950 void
1951 store_frame_param (f, prop, val)
1952 struct frame *f;
1953 Lisp_Object prop, val;
1955 register Lisp_Object old_alist_elt;
1957 /* The buffer-alist parameter is stored in a special place and is
1958 not in the alist. */
1959 if (EQ (prop, Qbuffer_list))
1961 f->buffer_list = val;
1962 return;
1965 /* If PROP is a symbol which is supposed to have frame-local values,
1966 and it is set up based on this frame, switch to the global
1967 binding. That way, we can create or alter the frame-local binding
1968 without messing up the symbol's status. */
1969 if (SYMBOLP (prop))
1971 Lisp_Object valcontents;
1972 valcontents = XSYMBOL (prop)->value;
1973 if ((BUFFER_LOCAL_VALUEP (valcontents)
1974 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1975 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1976 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1977 swap_in_global_binding (prop);
1980 /* Update the frame parameter alist. */
1981 old_alist_elt = Fassq (prop, f->param_alist);
1982 if (EQ (old_alist_elt, Qnil))
1983 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1984 else
1985 Fsetcdr (old_alist_elt, val);
1987 /* Update some other special parameters in their special places
1988 in addition to the alist. */
1990 if (EQ (prop, Qbuffer_predicate))
1991 f->buffer_predicate = val;
1993 if (! FRAME_WINDOW_P (f))
1995 if (EQ (prop, Qmenu_bar_lines))
1996 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1997 else if (EQ (prop, Qname))
1998 set_term_frame_name (f, val);
2001 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2003 if (! MINI_WINDOW_P (XWINDOW (val)))
2004 error ("Surrogate minibuffer windows must be minibuffer windows.");
2006 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2007 && !EQ (val, f->minibuffer_window))
2008 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2010 /* Install the chosen minibuffer window, with proper buffer. */
2011 f->minibuffer_window = val;
2015 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2016 "Return the parameters-alist of frame FRAME.\n\
2017 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
2018 The meaningful PARMs depend on the kind of frame.\n\
2019 If FRAME is omitted, return information on the currently selected frame.")
2020 (frame)
2021 Lisp_Object frame;
2023 Lisp_Object alist;
2024 FRAME_PTR f;
2025 int height, width;
2026 struct gcpro gcpro1;
2028 if (EQ (frame, Qnil))
2029 frame = selected_frame;
2031 CHECK_FRAME (frame, 0);
2032 f = XFRAME (frame);
2034 if (!FRAME_LIVE_P (f))
2035 return Qnil;
2037 alist = Fcopy_alist (f->param_alist);
2038 GCPRO1 (alist);
2040 if (!FRAME_WINDOW_P (f))
2042 int fg = FRAME_FOREGROUND_PIXEL (f);
2043 int bg = FRAME_BACKGROUND_PIXEL (f);
2045 store_in_alist (&alist, intern ("foreground-color"),
2046 tty_color_name (f, fg));
2047 store_in_alist (&alist, intern ("background-color"),
2048 tty_color_name (f, bg));
2049 store_in_alist (&alist, intern ("font"),
2050 build_string (FRAME_MSDOS_P (f)
2051 ? "ms-dos"
2052 : FRAME_W32_P (f) ? "w32term" : "tty"));
2054 store_in_alist (&alist, Qname, f->name);
2055 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2056 store_in_alist (&alist, Qheight, make_number (height));
2057 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2058 store_in_alist (&alist, Qwidth, make_number (width));
2059 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2060 store_in_alist (&alist, Qminibuffer,
2061 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2062 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2063 : FRAME_MINIBUF_WINDOW (f)));
2064 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2065 store_in_alist (&alist, Qbuffer_list,
2066 frame_buffer_list (selected_frame));
2068 /* I think this should be done with a hook. */
2069 #ifdef HAVE_WINDOW_SYSTEM
2070 if (FRAME_WINDOW_P (f))
2071 x_report_frame_params (f, &alist);
2072 else
2073 #endif
2075 /* This ought to be correct in f->param_alist for an X frame. */
2076 Lisp_Object lines;
2077 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2078 store_in_alist (&alist, Qmenu_bar_lines, lines);
2081 UNGCPRO;
2082 return alist;
2085 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2086 Smodify_frame_parameters, 2, 2, 0,
2087 "Modify the parameters of frame FRAME according to ALIST.\n\
2088 ALIST is an alist of parameters to change and their new values.\n\
2089 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2090 The meaningful PARMs depend on the kind of frame.\n\
2091 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2092 so that `frame-parameters' will return them.\n\
2094 The value of frame parameter FOO can also be accessed\n\
2095 as a frame-local binding for the variable FOO, if you have\n\
2096 enabled such bindings for that variable with `make-variable-frame-local'.")
2097 (frame, alist)
2098 Lisp_Object frame, alist;
2100 FRAME_PTR f;
2101 register Lisp_Object tail, prop, val;
2103 if (EQ (frame, Qnil))
2104 frame = selected_frame;
2105 CHECK_LIVE_FRAME (frame, 0);
2106 f = XFRAME (frame);
2108 /* I think this should be done with a hook. */
2109 #ifdef HAVE_WINDOW_SYSTEM
2110 if (FRAME_WINDOW_P (f))
2111 x_set_frame_parameters (f, alist);
2112 else
2113 #endif
2114 #ifdef MSDOS
2115 if (FRAME_MSDOS_P (f))
2116 IT_set_frame_parameters (f, alist);
2117 else
2118 #endif
2119 #ifdef macintosh
2120 if (FRAME_MAC_P (f))
2121 mac_set_frame_parameters (f, alist);
2122 else
2123 #endif
2126 int length = XINT (Flength (alist));
2127 int i;
2128 Lisp_Object *parms
2129 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2130 Lisp_Object *values
2131 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2133 /* Extract parm names and values into those vectors. */
2135 i = 0;
2136 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2138 Lisp_Object elt;
2140 elt = Fcar (tail);
2141 parms[i] = Fcar (elt);
2142 values[i] = Fcdr (elt);
2143 i++;
2146 /* Now process them in reverse of specified order. */
2147 for (i--; i >= 0; i--)
2149 prop = parms[i];
2150 val = values[i];
2151 store_frame_param (f, prop, val);
2155 return Qnil;
2158 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2159 0, 1, 0,
2160 "Height in pixels of a line in the font in frame FRAME.\n\
2161 If FRAME is omitted, the selected frame is used.\n\
2162 For a terminal frame, the value is always 1.")
2163 (frame)
2164 Lisp_Object frame;
2166 struct frame *f;
2168 if (NILP (frame))
2169 frame = selected_frame;
2170 CHECK_FRAME (frame, 0);
2171 f = XFRAME (frame);
2173 #ifdef HAVE_WINDOW_SYSTEM
2174 if (FRAME_WINDOW_P (f))
2175 return make_number (x_char_height (f));
2176 else
2177 #endif
2178 return make_number (1);
2182 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2183 0, 1, 0,
2184 "Width in pixels of characters in the font in frame FRAME.\n\
2185 If FRAME is omitted, the selected frame is used.\n\
2186 The width is the same for all characters, because\n\
2187 currently Emacs supports only fixed-width fonts.\n\
2188 For a terminal screen, the value is always 1.")
2189 (frame)
2190 Lisp_Object frame;
2192 struct frame *f;
2194 if (NILP (frame))
2195 frame = selected_frame;
2196 CHECK_FRAME (frame, 0);
2197 f = XFRAME (frame);
2199 #ifdef HAVE_WINDOW_SYSTEM
2200 if (FRAME_WINDOW_P (f))
2201 return make_number (x_char_width (f));
2202 else
2203 #endif
2204 return make_number (1);
2207 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2208 Sframe_pixel_height, 0, 1, 0,
2209 "Return a FRAME's height in pixels.\n\
2210 This counts only the height available for text lines,\n\
2211 not menu bars on window-system Emacs frames.\n\
2212 For a terminal frame, the result really gives the height in characters.\n\
2213 If FRAME is omitted, the selected frame is used.")
2214 (frame)
2215 Lisp_Object frame;
2217 struct frame *f;
2219 if (NILP (frame))
2220 frame = selected_frame;
2221 CHECK_FRAME (frame, 0);
2222 f = XFRAME (frame);
2224 #ifdef HAVE_WINDOW_SYSTEM
2225 if (FRAME_WINDOW_P (f))
2226 return make_number (x_pixel_height (f));
2227 else
2228 #endif
2229 return make_number (FRAME_HEIGHT (f));
2232 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2233 Sframe_pixel_width, 0, 1, 0,
2234 "Return FRAME's width in pixels.\n\
2235 For a terminal frame, the result really gives the width in characters.\n\
2236 If FRAME is omitted, the selected frame is used.")
2237 (frame)
2238 Lisp_Object frame;
2240 struct frame *f;
2242 if (NILP (frame))
2243 frame = selected_frame;
2244 CHECK_FRAME (frame, 0);
2245 f = XFRAME (frame);
2247 #ifdef HAVE_WINDOW_SYSTEM
2248 if (FRAME_WINDOW_P (f))
2249 return make_number (x_pixel_width (f));
2250 else
2251 #endif
2252 return make_number (FRAME_WIDTH (f));
2255 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2256 "Specify that the frame FRAME has LINES lines.\n\
2257 Optional third arg non-nil means that redisplay should use LINES lines\n\
2258 but that the idea of the actual height of the frame should not be changed.")
2259 (frame, lines, pretend)
2260 Lisp_Object frame, lines, pretend;
2262 register struct frame *f;
2264 CHECK_NUMBER (lines, 0);
2265 if (NILP (frame))
2266 frame = selected_frame;
2267 CHECK_LIVE_FRAME (frame, 0);
2268 f = XFRAME (frame);
2270 /* I think this should be done with a hook. */
2271 #ifdef HAVE_WINDOW_SYSTEM
2272 if (FRAME_WINDOW_P (f))
2274 if (XINT (lines) != f->height)
2275 x_set_window_size (f, 1, f->width, XINT (lines));
2276 do_pending_window_change (0);
2278 else
2279 #endif
2280 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2281 return Qnil;
2284 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2285 "Specify that the frame FRAME has COLS columns.\n\
2286 Optional third arg non-nil means that redisplay should use COLS columns\n\
2287 but that the idea of the actual width of the frame should not be changed.")
2288 (frame, cols, pretend)
2289 Lisp_Object frame, cols, pretend;
2291 register struct frame *f;
2292 CHECK_NUMBER (cols, 0);
2293 if (NILP (frame))
2294 frame = selected_frame;
2295 CHECK_LIVE_FRAME (frame, 0);
2296 f = XFRAME (frame);
2298 /* I think this should be done with a hook. */
2299 #ifdef HAVE_WINDOW_SYSTEM
2300 if (FRAME_WINDOW_P (f))
2302 if (XINT (cols) != f->width)
2303 x_set_window_size (f, 1, XINT (cols), f->height);
2304 do_pending_window_change (0);
2306 else
2307 #endif
2308 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2309 return Qnil;
2312 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2313 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2314 (frame, cols, rows)
2315 Lisp_Object frame, cols, rows;
2317 register struct frame *f;
2319 CHECK_LIVE_FRAME (frame, 0);
2320 CHECK_NUMBER (cols, 2);
2321 CHECK_NUMBER (rows, 1);
2322 f = XFRAME (frame);
2324 /* I think this should be done with a hook. */
2325 #ifdef HAVE_WINDOW_SYSTEM
2326 if (FRAME_WINDOW_P (f))
2328 if (XINT (rows) != f->height || XINT (cols) != f->width
2329 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2330 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2331 do_pending_window_change (0);
2333 else
2334 #endif
2335 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2337 return Qnil;
2340 DEFUN ("set-frame-position", Fset_frame_position,
2341 Sset_frame_position, 3, 3, 0,
2342 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2343 This is actually the position of the upper left corner of the frame.\n\
2344 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2345 the rightmost or bottommost possible position (that stays within the screen).")
2346 (frame, xoffset, yoffset)
2347 Lisp_Object frame, xoffset, yoffset;
2349 register struct frame *f;
2351 CHECK_LIVE_FRAME (frame, 0);
2352 CHECK_NUMBER (xoffset, 1);
2353 CHECK_NUMBER (yoffset, 2);
2354 f = XFRAME (frame);
2356 /* I think this should be done with a hook. */
2357 #ifdef HAVE_WINDOW_SYSTEM
2358 if (FRAME_WINDOW_P (f))
2359 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2360 #endif
2362 return Qt;
2366 void
2367 syms_of_frame ()
2369 syms_of_frame_1 ();
2371 staticpro (&Vframe_list);
2373 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2374 "The initial frame-object, which represents Emacs's stdout.");
2376 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2377 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2378 Vemacs_iconified = Qnil;
2380 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
2381 "If non-nil, function applied to the normal result of `mouse-position'.\n\
2382 This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
2383 which need to do mouse handling at the Lisp level.");
2384 Vmouse_position_function = Qnil;
2386 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2387 "Minibufferless frames use this frame's minibuffer.\n\
2389 Emacs cannot create minibufferless frames unless this is set to an\n\
2390 appropriate surrogate.\n\
2392 Emacs consults this variable only when creating minibufferless\n\
2393 frames; once the frame is created, it sticks with its assigned\n\
2394 minibuffer, no matter what this variable is set to. This means that\n\
2395 this variable doesn't necessarily say anything meaningful about the\n\
2396 current set of frames, or where the minibuffer is currently being\n\
2397 displayed.");
2399 defsubr (&Sactive_minibuffer_window);
2400 defsubr (&Sframep);
2401 defsubr (&Sframe_live_p);
2402 defsubr (&Smake_terminal_frame);
2403 defsubr (&Shandle_switch_frame);
2404 defsubr (&Signore_event);
2405 defsubr (&Sselect_frame);
2406 defsubr (&Sselected_frame);
2407 defsubr (&Swindow_frame);
2408 defsubr (&Sframe_root_window);
2409 defsubr (&Sframe_first_window);
2410 defsubr (&Sframe_selected_window);
2411 defsubr (&Sset_frame_selected_window);
2412 defsubr (&Sframe_list);
2413 defsubr (&Snext_frame);
2414 defsubr (&Sprevious_frame);
2415 defsubr (&Sdelete_frame);
2416 defsubr (&Smouse_position);
2417 defsubr (&Smouse_pixel_position);
2418 defsubr (&Sset_mouse_position);
2419 defsubr (&Sset_mouse_pixel_position);
2420 #if 0
2421 defsubr (&Sframe_configuration);
2422 defsubr (&Srestore_frame_configuration);
2423 #endif
2424 defsubr (&Smake_frame_visible);
2425 defsubr (&Smake_frame_invisible);
2426 defsubr (&Siconify_frame);
2427 defsubr (&Sframe_visible_p);
2428 defsubr (&Svisible_frame_list);
2429 defsubr (&Sraise_frame);
2430 defsubr (&Slower_frame);
2431 defsubr (&Sredirect_frame_focus);
2432 defsubr (&Sframe_focus);
2433 defsubr (&Sframe_parameters);
2434 defsubr (&Smodify_frame_parameters);
2435 defsubr (&Sframe_char_height);
2436 defsubr (&Sframe_char_width);
2437 defsubr (&Sframe_pixel_height);
2438 defsubr (&Sframe_pixel_width);
2439 defsubr (&Sset_frame_height);
2440 defsubr (&Sset_frame_width);
2441 defsubr (&Sset_frame_size);
2442 defsubr (&Sset_frame_position);
2445 void
2446 keys_of_frame ()
2448 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2449 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2450 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2451 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");