(standard-latex-block-names): Add "math".
[emacs.git] / src / frame.c
blob644e7a5347a6c634fba4194550bb05f4bf575dd1
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 #ifdef macintosh
33 #include "macterm.h"
34 #endif
35 #include "buffer.h"
36 /* These help us bind and responding to switch-frame events. */
37 #include "commands.h"
38 #include "keyboard.h"
39 #include "frame.h"
40 #ifdef HAVE_WINDOW_SYSTEM
41 #include "fontset.h"
42 #endif
43 #include "termhooks.h"
44 #include "dispextern.h"
45 #include "window.h"
46 #ifdef MSDOS
47 #include "msdos.h"
48 #include "dosfns.h"
49 #endif
51 /* Evaluate this expression to rebuild the section of syms_of_frame
52 that initializes and staticpros the symbols declared below. Note
53 that Emacs 18 has a bug that keeps C-x C-e from being able to
54 evaluate this expression.
56 (progn
57 ;; Accumulate a list of the symbols we want to initialize from the
58 ;; declarations at the top of the file.
59 (goto-char (point-min))
60 (search-forward "/\*&&& symbols declared here &&&*\/\n")
61 (let (symbol-list)
62 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
63 (setq symbol-list
64 (cons (buffer-substring (match-beginning 1) (match-end 1))
65 symbol-list))
66 (forward-line 1))
67 (setq symbol-list (nreverse symbol-list))
68 ;; Delete the section of syms_of_... where we initialize the symbols.
69 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
70 (let ((start (point)))
71 (while (looking-at "^ Q")
72 (forward-line 2))
73 (kill-region start (point)))
74 ;; Write a new symbol initialization section.
75 (while symbol-list
76 (insert (format " %s = intern (\"" (car symbol-list)))
77 (let ((start (point)))
78 (insert (substring (car symbol-list) 1))
79 (subst-char-in-region start (point) ?_ ?-))
80 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
81 (setq symbol-list (cdr symbol-list)))))
82 */
84 /*&&& symbols declared here &&&*/
85 Lisp_Object Qframep;
86 Lisp_Object Qframe_live_p;
87 Lisp_Object Qheight;
88 Lisp_Object Qicon;
89 Lisp_Object Qminibuffer;
90 Lisp_Object Qmodeline;
91 Lisp_Object Qname;
92 Lisp_Object Qonly;
93 Lisp_Object Qunsplittable;
94 Lisp_Object Qmenu_bar_lines;
95 Lisp_Object Qtool_bar_lines;
96 Lisp_Object Qwidth;
97 Lisp_Object Qx;
98 Lisp_Object Qw32;
99 Lisp_Object Qpc;
100 Lisp_Object Qmac;
101 Lisp_Object Qvisible;
102 Lisp_Object Qbuffer_predicate;
103 Lisp_Object Qbuffer_list;
104 Lisp_Object Qtitle;
105 Lisp_Object Qdisplay_type;
106 Lisp_Object Qbackground_mode;
108 Lisp_Object Vterminal_frame;
109 Lisp_Object Vdefault_frame_alist;
110 Lisp_Object Vmouse_position_function;
112 static void
113 syms_of_frame_1 ()
115 /*&&& init symbols here &&&*/
116 Qframep = intern ("framep");
117 staticpro (&Qframep);
118 Qframe_live_p = intern ("frame-live-p");
119 staticpro (&Qframe_live_p);
120 Qheight = intern ("height");
121 staticpro (&Qheight);
122 Qicon = intern ("icon");
123 staticpro (&Qicon);
124 Qminibuffer = intern ("minibuffer");
125 staticpro (&Qminibuffer);
126 Qmodeline = intern ("modeline");
127 staticpro (&Qmodeline);
128 Qname = intern ("name");
129 staticpro (&Qname);
130 Qonly = intern ("only");
131 staticpro (&Qonly);
132 Qunsplittable = intern ("unsplittable");
133 staticpro (&Qunsplittable);
134 Qmenu_bar_lines = intern ("menu-bar-lines");
135 staticpro (&Qmenu_bar_lines);
136 Qtool_bar_lines = intern ("tool-bar-lines");
137 staticpro (&Qtool_bar_lines);
138 Qwidth = intern ("width");
139 staticpro (&Qwidth);
140 Qx = intern ("x");
141 staticpro (&Qx);
142 Qw32 = intern ("w32");
143 staticpro (&Qw32);
144 Qpc = intern ("pc");
145 staticpro (&Qpc);
146 Qmac = intern ("mac");
147 staticpro (&Qmac);
148 Qvisible = intern ("visible");
149 staticpro (&Qvisible);
150 Qbuffer_predicate = intern ("buffer-predicate");
151 staticpro (&Qbuffer_predicate);
152 Qbuffer_list = intern ("buffer-list");
153 staticpro (&Qbuffer_list);
154 Qtitle = intern ("title");
155 staticpro (&Qtitle);
156 Qdisplay_type = intern ("display-type");
157 staticpro (&Qdisplay_type);
158 Qbackground_mode = intern ("background-mode");
159 staticpro (&Qbackground_mode);
161 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
162 "Alist of default values for frame creation.\n\
163 These may be set in your init file, like this:\n\
164 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
165 These override values given in window system configuration data,\n\
166 including X Windows' defaults database.\n\
167 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
168 For values specific to the separate minibuffer frame, see\n\
169 `minibuffer-frame-alist'.\n\
170 The `menu-bar-lines' element of the list controls whether new frames\n\
171 have menu bars; `menu-bar-mode' works by altering this element.");
172 Vdefault_frame_alist = Qnil;
175 static void
176 set_menu_bar_lines_1 (window, n)
177 Lisp_Object window;
178 int n;
180 struct window *w = XWINDOW (window);
182 XSETFASTINT (w->last_modified, 0);
183 XSETFASTINT (w->top, XFASTINT (w->top) + n);
184 XSETFASTINT (w->height, XFASTINT (w->height) - n);
186 if (INTEGERP (w->orig_top))
187 XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
188 if (INTEGERP (w->orig_height))
189 XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
191 /* Handle just the top child in a vertical split. */
192 if (!NILP (w->vchild))
193 set_menu_bar_lines_1 (w->vchild, n);
195 /* Adjust all children in a horizontal split. */
196 for (window = w->hchild; !NILP (window); window = w->next)
198 w = XWINDOW (window);
199 set_menu_bar_lines_1 (window, n);
203 void
204 set_menu_bar_lines (f, value, oldval)
205 struct frame *f;
206 Lisp_Object value, oldval;
208 int nlines;
209 int olines = FRAME_MENU_BAR_LINES (f);
211 /* Right now, menu bars don't work properly in minibuf-only frames;
212 most of the commands try to apply themselves to the minibuffer
213 frame itself, and get an error because you can't switch buffers
214 in or split the minibuffer window. */
215 if (FRAME_MINIBUF_ONLY_P (f))
216 return;
218 if (INTEGERP (value))
219 nlines = XINT (value);
220 else
221 nlines = 0;
223 if (nlines != olines)
225 windows_or_buffers_changed++;
226 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
227 FRAME_MENU_BAR_LINES (f) = nlines;
228 set_menu_bar_lines_1 (f->root_window, nlines - olines);
229 adjust_glyphs (f);
233 Lisp_Object Vemacs_iconified;
234 Lisp_Object Vframe_list;
236 struct x_output tty_display;
238 extern Lisp_Object Vminibuffer_list;
239 extern Lisp_Object get_minibuffer ();
240 extern Lisp_Object Fhandle_switch_frame ();
241 extern Lisp_Object Fredirect_frame_focus ();
242 extern Lisp_Object x_get_focus_frame ();
244 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
245 "Return non-nil if OBJECT is a frame.\n\
246 Value is t for a termcap frame (a character-only terminal),\n\
247 `x' for an Emacs frame that is really an X window,\n\
248 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
249 `mac' for an Emacs frame on a Macintosh display,\n\
250 `pc' for a direct-write MS-DOS frame.\n\
251 See also `frame-live-p'.")
252 (object)
253 Lisp_Object object;
255 if (!FRAMEP (object))
256 return Qnil;
257 switch (XFRAME (object)->output_method)
259 case output_termcap:
260 return Qt;
261 case output_x_window:
262 return Qx;
263 case output_w32:
264 return Qw32;
265 case output_msdos_raw:
266 return Qpc;
267 case output_mac:
268 return Qmac;
269 default:
270 abort ();
274 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
275 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
276 Value is nil if OBJECT is not a live frame. If object is a live\n\
277 frame, the return value indicates what sort of output device it is\n\
278 displayed on. Value is t for a termcap frame (a character-only\n\
279 terminal), `x' for an Emacs frame being displayed in an X window.")
280 (object)
281 Lisp_Object object;
283 return ((FRAMEP (object)
284 && FRAME_LIVE_P (XFRAME (object)))
285 ? Fframep (object)
286 : Qnil);
289 struct frame *
290 make_frame (mini_p)
291 int mini_p;
293 Lisp_Object frame;
294 register struct frame *f;
295 register Lisp_Object root_window;
296 register Lisp_Object mini_window;
297 register struct Lisp_Vector *vec;
298 int i;
300 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
301 for (i = 0; i < VECSIZE (struct frame); i++)
302 XSETFASTINT (vec->contents[i], 0);
303 vec->size = VECSIZE (struct frame);
304 f = (struct frame *)vec;
305 XSETFRAME (frame, f);
307 f->desired_matrix = 0;
308 f->current_matrix = 0;
309 f->desired_pool = 0;
310 f->current_pool = 0;
311 f->glyphs_initialized_p = 0;
312 f->decode_mode_spec_buffer = 0;
313 f->visible = 0;
314 f->async_visible = 0;
315 f->output_data.nothing = 0;
316 f->iconified = 0;
317 f->async_iconified = 0;
318 f->wants_modeline = 1;
319 f->auto_raise = 0;
320 f->auto_lower = 0;
321 f->no_split = 0;
322 f->garbaged = 1;
323 f->has_minibuffer = mini_p;
324 f->focus_frame = Qnil;
325 f->explicit_name = 0;
326 f->can_have_scroll_bars = 0;
327 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
328 f->param_alist = Qnil;
329 f->scroll_bars = Qnil;
330 f->condemned_scroll_bars = Qnil;
331 f->face_alist = Qnil;
332 f->face_cache = NULL;
333 f->menu_bar_items = Qnil;
334 f->menu_bar_vector = Qnil;
335 f->menu_bar_items_used = 0;
336 f->buffer_predicate = Qnil;
337 f->buffer_list = Qnil;
338 #ifdef MULTI_KBOARD
339 f->kboard = initial_kboard;
340 #endif
341 f->namebuf = 0;
342 f->title = Qnil;
343 f->menu_bar_window = Qnil;
344 f->tool_bar_window = Qnil;
345 f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
346 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
347 f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
349 root_window = make_window ();
350 if (mini_p)
352 mini_window = make_window ();
353 XWINDOW (root_window)->next = mini_window;
354 XWINDOW (mini_window)->prev = root_window;
355 XWINDOW (mini_window)->mini_p = Qt;
356 XWINDOW (mini_window)->frame = frame;
357 f->minibuffer_window = mini_window;
359 else
361 mini_window = Qnil;
362 XWINDOW (root_window)->next = Qnil;
363 f->minibuffer_window = Qnil;
366 XWINDOW (root_window)->frame = frame;
368 /* 10 is arbitrary,
369 just so that there is "something there."
370 Correct size will be set up later with change_frame_size. */
372 SET_FRAME_WIDTH (f, 10);
373 f->height = 10;
375 XSETFASTINT (XWINDOW (root_window)->width, 10);
376 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
378 if (mini_p)
380 XSETFASTINT (XWINDOW (mini_window)->width, 10);
381 XSETFASTINT (XWINDOW (mini_window)->top, 9);
382 XSETFASTINT (XWINDOW (mini_window)->height, 1);
385 /* Choose a buffer for the frame's root window. */
387 Lisp_Object buf;
389 XWINDOW (root_window)->buffer = Qt;
390 buf = Fcurrent_buffer ();
391 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
392 a space), try to find another one. */
393 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
394 buf = Fother_buffer (buf, Qnil, Qnil);
396 /* Use set_window_buffer, not Fset_window_buffer, and don't let
397 hooks be run by it. The reason is that the whole frame/window
398 arrangement is not yet fully intialized at this point. Windows
399 don't have the right size, glyph matrices aren't initialized
400 etc. Running Lisp functions at this point surely ends in a
401 SEGV. */
402 set_window_buffer (root_window, buf, 0);
403 f->buffer_list = Fcons (buf, Qnil);
406 if (mini_p)
408 XWINDOW (mini_window)->buffer = Qt;
409 set_window_buffer (mini_window,
410 (NILP (Vminibuffer_list)
411 ? get_minibuffer (0)
412 : Fcar (Vminibuffer_list)),
416 f->root_window = root_window;
417 f->selected_window = root_window;
418 /* Make sure this window seems more recently used than
419 a newly-created, never-selected window. */
420 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
422 return f;
425 #ifdef HAVE_WINDOW_SYSTEM
426 /* Make a frame using a separate minibuffer window on another frame.
427 MINI_WINDOW is the minibuffer window to use. nil means use the
428 default (the global minibuffer). */
430 struct frame *
431 make_frame_without_minibuffer (mini_window, kb, display)
432 register Lisp_Object mini_window;
433 KBOARD *kb;
434 Lisp_Object display;
436 register struct frame *f;
437 struct gcpro gcpro1;
439 if (!NILP (mini_window))
440 CHECK_LIVE_WINDOW (mini_window, 0);
442 #ifdef MULTI_KBOARD
443 if (!NILP (mini_window)
444 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
445 error ("frame and minibuffer must be on the same display");
446 #endif
448 /* Make a frame containing just a root window. */
449 f = make_frame (0);
451 if (NILP (mini_window))
453 /* Use default-minibuffer-frame if possible. */
454 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
455 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
457 Lisp_Object frame_dummy;
459 XSETFRAME (frame_dummy, f);
460 GCPRO1 (frame_dummy);
461 /* If there's no minibuffer frame to use, create one. */
462 kb->Vdefault_minibuffer_frame =
463 call1 (intern ("make-initial-minibuffer-frame"), display);
464 UNGCPRO;
467 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
470 f->minibuffer_window = mini_window;
472 /* Make the chosen minibuffer window display the proper minibuffer,
473 unless it is already showing a minibuffer. */
474 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
475 Fset_window_buffer (mini_window,
476 (NILP (Vminibuffer_list)
477 ? get_minibuffer (0)
478 : Fcar (Vminibuffer_list)));
479 return f;
482 /* Make a frame containing only a minibuffer window. */
484 struct frame *
485 make_minibuffer_frame ()
487 /* First make a frame containing just a root window, no minibuffer. */
489 register struct frame *f = make_frame (0);
490 register Lisp_Object mini_window;
491 register Lisp_Object frame;
493 XSETFRAME (frame, f);
495 f->auto_raise = 0;
496 f->auto_lower = 0;
497 f->no_split = 1;
498 f->wants_modeline = 0;
499 f->has_minibuffer = 1;
501 /* Now label the root window as also being the minibuffer.
502 Avoid infinite looping on the window chain by marking next pointer
503 as nil. */
505 mini_window = f->minibuffer_window = f->root_window;
506 XWINDOW (mini_window)->mini_p = Qt;
507 XWINDOW (mini_window)->next = Qnil;
508 XWINDOW (mini_window)->prev = Qnil;
509 XWINDOW (mini_window)->frame = frame;
511 /* Put the proper buffer in that window. */
513 Fset_window_buffer (mini_window,
514 (NILP (Vminibuffer_list)
515 ? get_minibuffer (0)
516 : Fcar (Vminibuffer_list)));
517 return f;
519 #endif /* HAVE_WINDOW_SYSTEM */
521 /* Construct a frame that refers to the terminal (stdin and stdout). */
523 static int terminal_frame_count;
525 struct frame *
526 make_terminal_frame ()
528 register struct frame *f;
529 Lisp_Object frame;
530 char name[20];
532 #ifdef MULTI_KBOARD
533 if (!initial_kboard)
535 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
536 init_kboard (initial_kboard);
537 initial_kboard->next_kboard = all_kboards;
538 all_kboards = initial_kboard;
540 #endif
542 /* The first call must initialize Vframe_list. */
543 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
544 Vframe_list = Qnil;
546 f = make_frame (1);
548 XSETFRAME (frame, f);
549 Vframe_list = Fcons (frame, Vframe_list);
551 terminal_frame_count++;
552 sprintf (name, "F%d", terminal_frame_count);
553 f->name = build_string (name);
555 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
556 f->async_visible = 1; /* Don't let visible be cleared later. */
557 #ifdef MSDOS
558 f->output_data.x = &the_only_x_display;
559 if (!inhibit_window_system
560 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
561 || XFRAME (selected_frame)->output_method == output_msdos_raw))
563 f->output_method = output_msdos_raw;
564 /* This initialization of foreground and background pixels is
565 only important for the initial frame created in temacs. If
566 we don't do that, we get black background and foreground in
567 the dumped Emacs because the_only_x_display is a static
568 variable, hence it is born all-zeroes, and zero is the code
569 for the black color. Other frames all inherit their pixels
570 from what's already in the_only_x_display. */
571 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
572 && f->output_data.x->background_pixel == 0
573 && f->output_data.x->foreground_pixel == 0)
575 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
576 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
579 else
580 f->output_method = output_termcap;
581 #else
582 #ifdef macintosh
583 make_mac_terminal_frame (f);
584 #else
585 f->output_data.x = &tty_display;
586 #endif /* macintosh */
587 #endif /* MSDOS */
589 if (!noninteractive)
590 init_frame_faces (f);
592 return f;
595 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
596 1, 1, 0, "Create an additional terminal frame.\n\
597 You can create multiple frames on a text-only terminal in this way.\n\
598 Only the selected terminal frame is actually displayed.\n\
599 This function takes one argument, an alist specifying frame parameters.\n\
600 In practice, generally you don't need to specify any parameters.\n\
601 Note that changing the size of one terminal frame automatically affects all.")
602 (parms)
603 Lisp_Object parms;
605 struct frame *f;
606 Lisp_Object frame, tem;
607 struct frame *sf = SELECTED_FRAME ();
609 #ifdef MSDOS
610 if (sf->output_method != output_msdos_raw
611 && sf->output_method != output_termcap)
612 abort ();
613 #else /* not MSDOS */
615 #ifdef macintosh
616 if (sf->output_method != output_mac)
617 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
618 #else
619 if (sf->output_method != output_termcap)
620 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
621 #endif
622 #endif /* not MSDOS */
624 f = make_terminal_frame ();
626 change_frame_size (f, FRAME_HEIGHT (sf),
627 FRAME_WIDTH (sf), 0, 0, 0);
628 adjust_glyphs (f);
629 calculate_costs (f);
630 XSETFRAME (frame, f);
631 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
632 Fmodify_frame_parameters (frame, parms);
634 /* Make the frame face alist be frame-specific, so that each
635 frame could change its face definitions independently. */
636 f->face_alist = Fcopy_alist (sf->face_alist);
637 /* Simple Fcopy_alist isn't enough, because we need the contents of
638 the vectors which are the CDRs of associations in face_alist to
639 be copied as well. */
640 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
641 XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
642 return frame;
645 Lisp_Object
646 do_switch_frame (frame, no_enter, track)
647 Lisp_Object frame, no_enter;
648 int track;
650 struct frame *sf = SELECTED_FRAME ();
652 /* If FRAME is a switch-frame event, extract the frame we should
653 switch to. */
654 if (CONSP (frame)
655 && EQ (XCAR (frame), Qswitch_frame)
656 && CONSP (XCDR (frame)))
657 frame = XCAR (XCDR (frame));
659 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
660 a switch-frame event to arrive after a frame is no longer live,
661 especially when deleting the initial frame during startup. */
662 CHECK_FRAME (frame, 0);
663 if (! FRAME_LIVE_P (XFRAME (frame)))
664 return Qnil;
666 if (sf == XFRAME (frame))
667 return frame;
669 /* This is too greedy; it causes inappropriate focus redirection
670 that's hard to get rid of. */
671 #if 0
672 /* If a frame's focus has been redirected toward the currently
673 selected frame, we should change the redirection to point to the
674 newly selected frame. This means that if the focus is redirected
675 from a minibufferless frame to a surrogate minibuffer frame, we
676 can use `other-window' to switch between all the frames using
677 that minibuffer frame, and the focus redirection will follow us
678 around. */
679 if (track)
681 Lisp_Object tail;
683 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
685 Lisp_Object focus;
687 if (!FRAMEP (XCAR (tail)))
688 abort ();
690 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
692 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
693 Fredirect_frame_focus (XCAR (tail), frame);
696 #else /* ! 0 */
697 /* Instead, apply it only to the frame we're pointing to. */
698 #ifdef HAVE_WINDOW_SYSTEM
699 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
701 Lisp_Object focus, xfocus;
703 xfocus = x_get_focus_frame (XFRAME (frame));
704 if (FRAMEP (xfocus))
706 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
707 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
708 Fredirect_frame_focus (xfocus, frame);
711 #endif /* HAVE_X_WINDOWS */
712 #endif /* ! 0 */
714 selected_frame = frame;
715 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
716 last_nonminibuf_frame = XFRAME (selected_frame);
718 Fselect_window (XFRAME (frame)->selected_window);
720 /* We want to make sure that the next event generates a frame-switch
721 event to the appropriate frame. This seems kludgy to me, but
722 before you take it out, make sure that evaluating something like
723 (select-window (frame-root-window (new-frame))) doesn't end up
724 with your typing being interpreted in the new frame instead of
725 the one you're actually typing in. */
726 internal_last_event_frame = Qnil;
728 return frame;
731 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
732 "Select the frame FRAME.\n\
733 Subsequent editing commands apply to its selected window.\n\
734 The selection of FRAME lasts until the next time the user does\n\
735 something to select a different frame, or until the next time this\n\
736 function is called.")
737 (frame, no_enter)
738 Lisp_Object frame, no_enter;
740 return do_switch_frame (frame, no_enter, 1);
744 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
745 "Handle a switch-frame event EVENT.\n\
746 Switch-frame events are usually bound to this function.\n\
747 A switch-frame event tells Emacs that the window manager has requested\n\
748 that the user's events be directed to the frame mentioned in the event.\n\
749 This function selects the selected window of the frame of EVENT.\n\
751 If EVENT is frame object, handle it as if it were a switch-frame event\n\
752 to that frame.")
753 (event, no_enter)
754 Lisp_Object event, no_enter;
756 /* Preserve prefix arg that the command loop just cleared. */
757 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
758 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
759 return do_switch_frame (event, no_enter, 0);
762 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
763 "Do nothing, but preserve any prefix argument already specified.\n\
764 This is a suitable binding for iconify-frame and make-frame-visible.")
767 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
768 return Qnil;
771 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
772 "Return the frame that is now selected.")
775 return selected_frame;
778 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
779 "Return the frame object that window WINDOW is on.")
780 (window)
781 Lisp_Object window;
783 CHECK_LIVE_WINDOW (window, 0);
784 return XWINDOW (window)->frame;
787 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
788 "Returns the topmost, leftmost window of FRAME.\n\
789 If omitted, FRAME defaults to the currently selected frame.")
790 (frame)
791 Lisp_Object frame;
793 Lisp_Object w;
795 if (NILP (frame))
796 w = SELECTED_FRAME ()->root_window;
797 else
799 CHECK_LIVE_FRAME (frame, 0);
800 w = XFRAME (frame)->root_window;
802 while (NILP (XWINDOW (w)->buffer))
804 if (! NILP (XWINDOW (w)->hchild))
805 w = XWINDOW (w)->hchild;
806 else if (! NILP (XWINDOW (w)->vchild))
807 w = XWINDOW (w)->vchild;
808 else
809 abort ();
811 return w;
814 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
815 Sactive_minibuffer_window, 0, 0, 0,
816 "Return the currently active minibuffer window, or nil if none.")
819 return minibuf_level ? minibuf_window : Qnil;
822 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
823 "Returns the root-window of FRAME.\n\
824 If omitted, FRAME defaults to the currently selected frame.")
825 (frame)
826 Lisp_Object frame;
828 Lisp_Object window;
830 if (NILP (frame))
831 window = SELECTED_FRAME ()->root_window;
832 else
834 CHECK_LIVE_FRAME (frame, 0);
835 window = XFRAME (frame)->root_window;
838 return window;
841 DEFUN ("frame-selected-window", Fframe_selected_window,
842 Sframe_selected_window, 0, 1, 0,
843 "Return the selected window of frame object FRAME.\n\
844 If omitted, FRAME defaults to the currently selected frame.")
845 (frame)
846 Lisp_Object frame;
848 Lisp_Object window;
850 if (NILP (frame))
851 window = SELECTED_FRAME ()->selected_window;
852 else
854 CHECK_LIVE_FRAME (frame, 0);
855 window = XFRAME (frame)->selected_window;
858 return window;
861 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
862 Sset_frame_selected_window, 2, 2, 0,
863 "Set the selected window of frame object FRAME to WINDOW.\n\
864 If FRAME is nil, the selected frame is used.\n\
865 If FRAME is the selected frame, this makes WINDOW the selected window.")
866 (frame, window)
867 Lisp_Object frame, window;
869 if (NILP (frame))
870 frame = selected_frame;
872 CHECK_LIVE_FRAME (frame, 0);
873 CHECK_LIVE_WINDOW (window, 1);
875 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
876 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
878 if (EQ (frame, selected_frame))
879 return Fselect_window (window);
881 return XFRAME (frame)->selected_window = window;
884 DEFUN ("frame-list", Fframe_list, Sframe_list,
885 0, 0, 0,
886 "Return a list of all frames.")
889 return Fcopy_sequence (Vframe_list);
892 /* Return the next frame in the frame list after FRAME.
893 If MINIBUF is nil, exclude minibuffer-only frames.
894 If MINIBUF is a window, include only its own frame
895 and any frame now using that window as the minibuffer.
896 If MINIBUF is `visible', include all visible frames.
897 If MINIBUF is 0, include all visible and iconified frames.
898 Otherwise, include all frames. */
900 Lisp_Object
901 next_frame (frame, minibuf)
902 Lisp_Object frame;
903 Lisp_Object minibuf;
905 Lisp_Object tail;
906 int passed = 0;
908 /* There must always be at least one frame in Vframe_list. */
909 if (! CONSP (Vframe_list))
910 abort ();
912 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
913 forever. Forestall that. */
914 CHECK_LIVE_FRAME (frame, 0);
916 while (1)
917 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
919 Lisp_Object f;
921 f = XCAR (tail);
923 if (passed
924 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
926 /* Decide whether this frame is eligible to be returned. */
928 /* If we've looped all the way around without finding any
929 eligible frames, return the original frame. */
930 if (EQ (f, frame))
931 return f;
933 /* Let minibuf decide if this frame is acceptable. */
934 if (NILP (minibuf))
936 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
937 return f;
939 else if (EQ (minibuf, Qvisible))
941 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
942 if (FRAME_VISIBLE_P (XFRAME (f)))
943 return f;
945 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
947 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
948 if (FRAME_VISIBLE_P (XFRAME (f))
949 || FRAME_ICONIFIED_P (XFRAME (f)))
950 return f;
952 else if (WINDOWP (minibuf))
954 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
955 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
956 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
957 FRAME_FOCUS_FRAME (XFRAME (f))))
958 return f;
960 else
961 return f;
964 if (EQ (frame, f))
965 passed++;
969 /* Return the previous frame in the frame list before FRAME.
970 If MINIBUF is nil, exclude minibuffer-only frames.
971 If MINIBUF is a window, include only its own frame
972 and any frame now using that window as the minibuffer.
973 If MINIBUF is `visible', include all visible frames.
974 If MINIBUF is 0, include all visible and iconified frames.
975 Otherwise, include all frames. */
977 Lisp_Object
978 prev_frame (frame, minibuf)
979 Lisp_Object frame;
980 Lisp_Object minibuf;
982 Lisp_Object tail;
983 Lisp_Object prev;
985 /* There must always be at least one frame in Vframe_list. */
986 if (! CONSP (Vframe_list))
987 abort ();
989 prev = Qnil;
990 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
992 Lisp_Object f;
994 f = XCAR (tail);
995 if (!FRAMEP (f))
996 abort ();
998 if (EQ (frame, f) && !NILP (prev))
999 return prev;
1001 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1003 /* Decide whether this frame is eligible to be returned,
1004 according to minibuf. */
1005 if (NILP (minibuf))
1007 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1008 prev = f;
1010 else if (WINDOWP (minibuf))
1012 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1013 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1014 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1015 FRAME_FOCUS_FRAME (XFRAME (f))))
1016 prev = f;
1018 else if (EQ (minibuf, Qvisible))
1020 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1021 if (FRAME_VISIBLE_P (XFRAME (f)))
1022 prev = f;
1024 else if (XFASTINT (minibuf) == 0)
1026 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1027 if (FRAME_VISIBLE_P (XFRAME (f))
1028 || FRAME_ICONIFIED_P (XFRAME (f)))
1029 prev = f;
1031 else
1032 prev = f;
1036 /* We've scanned the entire list. */
1037 if (NILP (prev))
1038 /* We went through the whole frame list without finding a single
1039 acceptable frame. Return the original frame. */
1040 return frame;
1041 else
1042 /* There were no acceptable frames in the list before FRAME; otherwise,
1043 we would have returned directly from the loop. Since PREV is the last
1044 acceptable frame in the list, return it. */
1045 return prev;
1049 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1050 "Return the next frame in the frame list after FRAME.\n\
1051 It considers only frames on the same terminal as FRAME.\n\
1052 By default, skip minibuffer-only frames.\n\
1053 If omitted, FRAME defaults to the selected frame.\n\
1054 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1055 If MINIFRAME is a window, include only its own frame\n\
1056 and any frame now using that window as the minibuffer.\n\
1057 If MINIFRAME is `visible', include all visible frames.\n\
1058 If MINIFRAME is 0, include all visible and iconified frames.\n\
1059 Otherwise, include all frames.")
1060 (frame, miniframe)
1061 Lisp_Object frame, miniframe;
1063 if (NILP (frame))
1064 frame = selected_frame;
1066 CHECK_LIVE_FRAME (frame, 0);
1067 return next_frame (frame, miniframe);
1070 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1071 "Return the previous frame in the frame list before FRAME.\n\
1072 It considers only frames on the same terminal as FRAME.\n\
1073 By default, skip minibuffer-only frames.\n\
1074 If omitted, FRAME defaults to the selected frame.\n\
1075 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1076 If MINIFRAME is a window, include only its own frame\n\
1077 and any frame now using that window as the minibuffer.\n\
1078 If MINIFRAME is `visible', include all visible frames.\n\
1079 If MINIFRAME is 0, include all visible and iconified frames.\n\
1080 Otherwise, include all frames.")
1081 (frame, miniframe)
1082 Lisp_Object frame, miniframe;
1084 if (NILP (frame))
1085 frame = selected_frame;
1086 CHECK_LIVE_FRAME (frame, 0);
1087 return prev_frame (frame, miniframe);
1090 /* Return 1 if it is ok to delete frame F;
1091 0 if all frames aside from F are invisible.
1092 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1095 other_visible_frames (f)
1096 FRAME_PTR f;
1098 /* We know the selected frame is visible,
1099 so if F is some other frame, it can't be the sole visible one. */
1100 if (f == SELECTED_FRAME ())
1102 Lisp_Object frames;
1103 int count = 0;
1105 for (frames = Vframe_list;
1106 CONSP (frames);
1107 frames = XCDR (frames))
1109 Lisp_Object this;
1111 this = XCAR (frames);
1112 /* Verify that the frame's window still exists
1113 and we can still talk to it. And note any recent change
1114 in visibility. */
1115 #ifdef HAVE_WINDOW_SYSTEM
1116 if (FRAME_WINDOW_P (XFRAME (this)))
1118 x_sync (XFRAME (this));
1119 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1121 #endif
1123 if (FRAME_VISIBLE_P (XFRAME (this))
1124 || FRAME_ICONIFIED_P (XFRAME (this))
1125 /* Allow deleting the terminal frame when at least
1126 one X frame exists! */
1127 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1128 count++;
1130 return count > 1;
1132 return 1;
1135 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1136 "Delete FRAME, permanently eliminating it from use.\n\
1137 If omitted, FRAME defaults to the selected frame.\n\
1138 A frame may not be deleted if its minibuffer is used by other frames.\n\
1139 Normally, you may not delete a frame if all other frames are invisible,\n\
1140 but if the second optional argument FORCE is non-nil, you may do so.\n\
1142 This function runs `delete-frame-hook' before actually deleting the\n\
1143 frame. The hook is called with one argument FRAME.")
1144 (frame, force)
1145 Lisp_Object frame, force;
1147 struct frame *f;
1148 struct frame *sf = SELECTED_FRAME ();
1149 int minibuffer_selected;
1151 if (EQ (frame, Qnil))
1153 f = sf;
1154 XSETFRAME (frame, f);
1156 else
1158 CHECK_FRAME (frame, 0);
1159 f = XFRAME (frame);
1162 if (! FRAME_LIVE_P (f))
1163 return Qnil;
1165 if (NILP (force) && !other_visible_frames (f))
1166 error ("Attempt to delete the sole visible or iconified frame");
1168 #if 0
1169 /* This is a nice idea, but x_connection_closed needs to be able
1170 to delete the last frame, if it is gone. */
1171 if (NILP (XCDR (Vframe_list)))
1172 error ("Attempt to delete the only frame");
1173 #endif
1175 /* Does this frame have a minibuffer, and is it the surrogate
1176 minibuffer for any other frame? */
1177 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1179 Lisp_Object frames;
1181 for (frames = Vframe_list;
1182 CONSP (frames);
1183 frames = XCDR (frames))
1185 Lisp_Object this;
1186 this = XCAR (frames);
1188 if (! EQ (this, frame)
1189 && EQ (frame,
1190 WINDOW_FRAME (XWINDOW
1191 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1192 error ("Attempt to delete a surrogate minibuffer frame");
1196 /* Run `delete-frame-hook'. */
1197 if (!NILP (Vrun_hooks))
1199 Lisp_Object args[2];
1200 args[0] = intern ("delete-frame-hook");
1201 args[1] = frame;
1202 Frun_hook_with_args (2, args);
1205 minibuffer_selected = EQ (minibuf_window, selected_window);
1207 /* Don't let the frame remain selected. */
1208 if (f == sf)
1210 Lisp_Object tail, frame1;
1212 /* Look for another visible frame on the same terminal. */
1213 frame1 = next_frame (frame, Qvisible);
1215 /* If there is none, find *some* other frame. */
1216 if (NILP (frame1) || EQ (frame1, frame))
1218 FOR_EACH_FRAME (tail, frame1)
1220 if (! EQ (frame, frame1))
1221 break;
1225 do_switch_frame (frame1, Qnil, 0);
1226 sf = SELECTED_FRAME ();
1229 /* Don't allow minibuf_window to remain on a deleted frame. */
1230 if (EQ (f->minibuffer_window, minibuf_window))
1232 Fset_window_buffer (sf->minibuffer_window,
1233 XWINDOW (minibuf_window)->buffer);
1234 minibuf_window = sf->minibuffer_window;
1236 /* If the dying minibuffer window was selected,
1237 select the new one. */
1238 if (minibuffer_selected)
1239 Fselect_window (minibuf_window);
1242 /* Don't let echo_area_window to remain on a deleted frame. */
1243 if (EQ (f->minibuffer_window, echo_area_window))
1244 echo_area_window = sf->minibuffer_window;
1246 /* Clear any X selections for this frame. */
1247 #ifdef HAVE_X_WINDOWS
1248 if (FRAME_X_P (f))
1249 x_clear_frame_selections (f);
1250 #endif
1252 /* Free glyphs.
1253 This function must be called before the window tree of the
1254 frame is deleted because windows contain dynamically allocated
1255 memory. */
1256 free_glyphs (f);
1258 /* Mark all the windows that used to be on FRAME as deleted, and then
1259 remove the reference to them. */
1260 delete_all_subwindows (XWINDOW (f->root_window));
1261 f->root_window = Qnil;
1263 Vframe_list = Fdelq (frame, Vframe_list);
1264 FRAME_SET_VISIBLE (f, 0);
1266 if (f->namebuf)
1267 xfree (f->namebuf);
1268 if (FRAME_INSERT_COST (f))
1269 xfree (FRAME_INSERT_COST (f));
1270 if (FRAME_DELETEN_COST (f))
1271 xfree (FRAME_DELETEN_COST (f));
1272 if (FRAME_INSERTN_COST (f))
1273 xfree (FRAME_INSERTN_COST (f));
1274 if (FRAME_DELETE_COST (f))
1275 xfree (FRAME_DELETE_COST (f));
1276 if (FRAME_MESSAGE_BUF (f))
1277 xfree (FRAME_MESSAGE_BUF (f));
1279 /* Since some events are handled at the interrupt level, we may get
1280 an event for f at any time; if we zero out the frame's display
1281 now, then we may trip up the event-handling code. Instead, we'll
1282 promise that the display of the frame must be valid until we have
1283 called the window-system-dependent frame destruction routine. */
1285 /* I think this should be done with a hook. */
1286 #ifdef HAVE_WINDOW_SYSTEM
1287 if (FRAME_WINDOW_P (f))
1288 x_destroy_window (f);
1289 #endif
1291 f->output_data.nothing = 0;
1293 /* If we've deleted the last_nonminibuf_frame, then try to find
1294 another one. */
1295 if (f == last_nonminibuf_frame)
1297 Lisp_Object frames;
1299 last_nonminibuf_frame = 0;
1301 for (frames = Vframe_list;
1302 CONSP (frames);
1303 frames = XCDR (frames))
1305 f = XFRAME (XCAR (frames));
1306 if (!FRAME_MINIBUF_ONLY_P (f))
1308 last_nonminibuf_frame = f;
1309 break;
1314 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1315 find another one. Prefer minibuffer-only frames, but also notice
1316 frames with other windows. */
1317 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1319 Lisp_Object frames;
1321 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1322 Lisp_Object frame_with_minibuf;
1323 /* Some frame we found on the same kboard, or nil if there are none. */
1324 Lisp_Object frame_on_same_kboard;
1326 frame_on_same_kboard = Qnil;
1327 frame_with_minibuf = Qnil;
1329 for (frames = Vframe_list;
1330 CONSP (frames);
1331 frames = XCDR (frames))
1333 Lisp_Object this;
1334 struct frame *f1;
1336 this = XCAR (frames);
1337 if (!FRAMEP (this))
1338 abort ();
1339 f1 = XFRAME (this);
1341 /* Consider only frames on the same kboard
1342 and only those with minibuffers. */
1343 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1344 && FRAME_HAS_MINIBUF_P (f1))
1346 frame_with_minibuf = this;
1347 if (FRAME_MINIBUF_ONLY_P (f1))
1348 break;
1351 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1352 frame_on_same_kboard = this;
1355 if (!NILP (frame_on_same_kboard))
1357 /* We know that there must be some frame with a minibuffer out
1358 there. If this were not true, all of the frames present
1359 would have to be minibufferless, which implies that at some
1360 point their minibuffer frames must have been deleted, but
1361 that is prohibited at the top; you can't delete surrogate
1362 minibuffer frames. */
1363 if (NILP (frame_with_minibuf))
1364 abort ();
1366 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1368 else
1369 /* No frames left on this kboard--say no minibuffer either. */
1370 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1373 /* Cause frame titles to update--necessary if we now have just one frame. */
1374 update_mode_lines = 1;
1376 return Qnil;
1379 /* Return mouse position in character cell units. */
1381 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1382 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1383 The position is given in character cells, where (0, 0) is the\n\
1384 upper-left corner.\n\
1385 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1386 to read the mouse position, it returns the selected frame for FRAME\n\
1387 and nil for X and Y.\n\
1388 Runs the abnormal hook `mouse-position-function' with the normal return\n\
1389 value as argument.")
1392 FRAME_PTR f;
1393 Lisp_Object lispy_dummy;
1394 enum scroll_bar_part party_dummy;
1395 Lisp_Object x, y, retval;
1396 int col, row;
1397 unsigned long long_dummy;
1398 struct gcpro gcpro1;
1400 f = SELECTED_FRAME ();
1401 x = y = Qnil;
1403 #ifdef HAVE_MOUSE
1404 /* It's okay for the hook to refrain from storing anything. */
1405 if (mouse_position_hook)
1406 (*mouse_position_hook) (&f, -1,
1407 &lispy_dummy, &party_dummy,
1408 &x, &y,
1409 &long_dummy);
1410 if (! NILP (x))
1412 col = XINT (x);
1413 row = XINT (y);
1414 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1415 XSETINT (x, col);
1416 XSETINT (y, row);
1418 #endif
1419 XSETFRAME (lispy_dummy, f);
1420 retval = Fcons (lispy_dummy, Fcons (x, y));
1421 GCPRO1 (retval);
1422 if (!NILP (Vmouse_position_function))
1423 retval = call1 (Vmouse_position_function, retval);
1424 RETURN_UNGCPRO (retval);
1427 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1428 Smouse_pixel_position, 0, 0, 0,
1429 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1430 The position is given in pixel units, where (0, 0) is the\n\
1431 upper-left corner.\n\
1432 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1433 to read the mouse position, it returns the selected frame for FRAME\n\
1434 and nil for X and Y.")
1437 FRAME_PTR f;
1438 Lisp_Object lispy_dummy;
1439 enum scroll_bar_part party_dummy;
1440 Lisp_Object x, y;
1441 unsigned long long_dummy;
1443 f = SELECTED_FRAME ();
1444 x = y = Qnil;
1446 #ifdef HAVE_MOUSE
1447 /* It's okay for the hook to refrain from storing anything. */
1448 if (mouse_position_hook)
1449 (*mouse_position_hook) (&f, -1,
1450 &lispy_dummy, &party_dummy,
1451 &x, &y,
1452 &long_dummy);
1453 #endif
1454 XSETFRAME (lispy_dummy, f);
1455 return Fcons (lispy_dummy, Fcons (x, y));
1458 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1459 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1460 Coordinates are relative to the frame, not a window,\n\
1461 so the coordinates of the top left character in the frame\n\
1462 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1464 This function is a no-op for an X frame that is not visible.\n\
1465 If you have just created a frame, you must wait for it to become visible\n\
1466 before calling this function on it, like this.\n\
1467 (while (not (frame-visible-p frame)) (sleep-for .5))")
1468 (frame, x, y)
1469 Lisp_Object frame, x, y;
1471 CHECK_LIVE_FRAME (frame, 0);
1472 CHECK_NUMBER (x, 2);
1473 CHECK_NUMBER (y, 1);
1475 /* I think this should be done with a hook. */
1476 #ifdef HAVE_WINDOW_SYSTEM
1477 if (FRAME_WINDOW_P (XFRAME (frame)))
1478 /* Warping the mouse will cause enternotify and focus events. */
1479 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1480 #else
1481 #if defined (MSDOS) && defined (HAVE_MOUSE)
1482 if (FRAME_MSDOS_P (XFRAME (frame)))
1484 Fselect_frame (frame, Qnil);
1485 mouse_moveto (XINT (x), XINT (y));
1487 #endif
1488 #endif
1490 return Qnil;
1493 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1494 Sset_mouse_pixel_position, 3, 3, 0,
1495 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1496 Note, this is a no-op for an X frame that is not visible.\n\
1497 If you have just created a frame, you must wait for it to become visible\n\
1498 before calling this function on it, like this.\n\
1499 (while (not (frame-visible-p frame)) (sleep-for .5))")
1500 (frame, x, y)
1501 Lisp_Object frame, x, y;
1503 CHECK_LIVE_FRAME (frame, 0);
1504 CHECK_NUMBER (x, 2);
1505 CHECK_NUMBER (y, 1);
1507 /* I think this should be done with a hook. */
1508 #ifdef HAVE_WINDOW_SYSTEM
1509 if (FRAME_WINDOW_P (XFRAME (frame)))
1510 /* Warping the mouse will cause enternotify and focus events. */
1511 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1512 #else
1513 #if defined (MSDOS) && defined (HAVE_MOUSE)
1514 if (FRAME_MSDOS_P (XFRAME (frame)))
1516 Fselect_frame (frame, Qnil);
1517 mouse_moveto (XINT (x), XINT (y));
1519 #endif
1520 #endif
1522 return Qnil;
1525 static void make_frame_visible_1 P_ ((Lisp_Object));
1527 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1528 0, 1, "",
1529 "Make the frame FRAME visible (assuming it is an X-window).\n\
1530 If omitted, FRAME defaults to the currently selected frame.")
1531 (frame)
1532 Lisp_Object frame;
1534 if (NILP (frame))
1535 frame = selected_frame;
1537 CHECK_LIVE_FRAME (frame, 0);
1539 /* I think this should be done with a hook. */
1540 #ifdef HAVE_WINDOW_SYSTEM
1541 if (FRAME_WINDOW_P (XFRAME (frame)))
1543 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1544 x_make_frame_visible (XFRAME (frame));
1546 #endif
1548 make_frame_visible_1 (XFRAME (frame)->root_window);
1550 /* Make menu bar update for the Buffers and Frams menus. */
1551 windows_or_buffers_changed++;
1553 return frame;
1556 /* Update the display_time slot of the buffers shown in WINDOW
1557 and all its descendents. */
1559 static void
1560 make_frame_visible_1 (window)
1561 Lisp_Object window;
1563 struct window *w;
1565 for (;!NILP (window); window = w->next)
1567 w = XWINDOW (window);
1569 if (!NILP (w->buffer))
1570 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1572 if (!NILP (w->vchild))
1573 make_frame_visible_1 (w->vchild);
1574 if (!NILP (w->hchild))
1575 make_frame_visible_1 (w->hchild);
1579 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1580 0, 2, "",
1581 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1582 If omitted, FRAME defaults to the currently selected frame.\n\
1583 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1584 but if the second optional argument FORCE is non-nil, you may do so.")
1585 (frame, force)
1586 Lisp_Object frame, force;
1588 if (NILP (frame))
1589 frame = selected_frame;
1591 CHECK_LIVE_FRAME (frame, 0);
1593 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1594 error ("Attempt to make invisible the sole visible or iconified frame");
1596 #if 0 /* This isn't logically necessary, and it can do GC. */
1597 /* Don't let the frame remain selected. */
1598 if (EQ (frame, selected_frame))
1599 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1600 #endif
1602 /* Don't allow minibuf_window to remain on a deleted frame. */
1603 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1605 struct frame *sf = XFRAME (selected_frame);
1606 Fset_window_buffer (sf->minibuffer_window,
1607 XWINDOW (minibuf_window)->buffer);
1608 minibuf_window = sf->minibuffer_window;
1611 /* I think this should be done with a hook. */
1612 #ifdef HAVE_WINDOW_SYSTEM
1613 if (FRAME_WINDOW_P (XFRAME (frame)))
1614 x_make_frame_invisible (XFRAME (frame));
1615 #endif
1617 /* Make menu bar update for the Buffers and Frams menus. */
1618 windows_or_buffers_changed++;
1620 return Qnil;
1623 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1624 0, 1, "",
1625 "Make the frame FRAME into an icon.\n\
1626 If omitted, FRAME defaults to the currently selected frame.")
1627 (frame)
1628 Lisp_Object frame;
1630 if (NILP (frame))
1631 frame = selected_frame;
1633 CHECK_LIVE_FRAME (frame, 0);
1635 #if 0 /* This isn't logically necessary, and it can do GC. */
1636 /* Don't let the frame remain selected. */
1637 if (EQ (frame, selected_frame))
1638 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1639 #endif
1641 /* Don't allow minibuf_window to remain on a deleted frame. */
1642 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1644 struct frame *sf = XFRAME (selected_frame);
1645 Fset_window_buffer (sf->minibuffer_window,
1646 XWINDOW (minibuf_window)->buffer);
1647 minibuf_window = sf->minibuffer_window;
1650 /* I think this should be done with a hook. */
1651 #ifdef HAVE_WINDOW_SYSTEM
1652 if (FRAME_WINDOW_P (XFRAME (frame)))
1653 x_iconify_frame (XFRAME (frame));
1654 #endif
1656 /* Make menu bar update for the Buffers and Frams menus. */
1657 windows_or_buffers_changed++;
1659 return Qnil;
1662 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1663 1, 1, 0,
1664 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1665 A frame that is not \"visible\" is not updated and, if it works through\n\
1666 a window system, it may not show at all.\n\
1667 Return the symbol `icon' if frame is visible only as an icon.")
1668 (frame)
1669 Lisp_Object frame;
1671 CHECK_LIVE_FRAME (frame, 0);
1673 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1675 if (FRAME_VISIBLE_P (XFRAME (frame)))
1676 return Qt;
1677 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1678 return Qicon;
1679 return Qnil;
1682 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1683 0, 0, 0,
1684 "Return a list of all frames now \"visible\" (being updated).")
1687 Lisp_Object tail, frame;
1688 struct frame *f;
1689 Lisp_Object value;
1691 value = Qnil;
1692 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1694 frame = XCAR (tail);
1695 if (!FRAMEP (frame))
1696 continue;
1697 f = XFRAME (frame);
1698 if (FRAME_VISIBLE_P (f))
1699 value = Fcons (frame, value);
1701 return value;
1705 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1706 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1707 If FRAME is invisible, make it visible.\n\
1708 If you don't specify a frame, the selected frame is used.\n\
1709 If Emacs is displaying on an ordinary terminal or some other device which\n\
1710 doesn't support multiple overlapping frames, this function does nothing.")
1711 (frame)
1712 Lisp_Object frame;
1714 if (NILP (frame))
1715 frame = selected_frame;
1717 CHECK_LIVE_FRAME (frame, 0);
1719 /* Do like the documentation says. */
1720 Fmake_frame_visible (frame);
1722 if (frame_raise_lower_hook)
1723 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1725 return Qnil;
1728 /* Should we have a corresponding function called Flower_Power? */
1729 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1730 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1731 If you don't specify a frame, the selected frame is used.\n\
1732 If Emacs is displaying on an ordinary terminal or some other device which\n\
1733 doesn't support multiple overlapping frames, this function does nothing.")
1734 (frame)
1735 Lisp_Object frame;
1737 if (NILP (frame))
1738 frame = selected_frame;
1740 CHECK_LIVE_FRAME (frame, 0);
1742 if (frame_raise_lower_hook)
1743 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1745 return Qnil;
1749 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1750 1, 2, 0,
1751 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1752 In other words, switch-frame events caused by events in FRAME will\n\
1753 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1754 FOCUS-FRAME after reading an event typed at FRAME.\n\
1756 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1757 cancelled, and the frame again receives its own keystrokes.\n\
1759 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1760 a surrogate minibuffer frame when a frame doesn't have its own\n\
1761 minibuffer window.\n\
1763 A frame's focus redirection can be changed by select-frame. If frame\n\
1764 FOO is selected, and then a different frame BAR is selected, any\n\
1765 frames redirecting their focus to FOO are shifted to redirect their\n\
1766 focus to BAR. This allows focus redirection to work properly when the\n\
1767 user switches from one frame to another using `select-window'.\n\
1769 This means that a frame whose focus is redirected to itself is treated\n\
1770 differently from a frame whose focus is redirected to nil; the former\n\
1771 is affected by select-frame, while the latter is not.\n\
1773 The redirection lasts until `redirect-frame-focus' is called to change it.")
1774 (frame, focus_frame)
1775 Lisp_Object frame, focus_frame;
1777 /* Note that we don't check for a live frame here. It's reasonable
1778 to redirect the focus of a frame you're about to delete, if you
1779 know what other frame should receive those keystrokes. */
1780 CHECK_FRAME (frame, 0);
1782 if (! NILP (focus_frame))
1783 CHECK_LIVE_FRAME (focus_frame, 1);
1785 XFRAME (frame)->focus_frame = focus_frame;
1787 if (frame_rehighlight_hook)
1788 (*frame_rehighlight_hook) (XFRAME (frame));
1790 return Qnil;
1794 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1795 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1796 This returns nil if FRAME's focus is not redirected.\n\
1797 See `redirect-frame-focus'.")
1798 (frame)
1799 Lisp_Object frame;
1801 CHECK_LIVE_FRAME (frame, 0);
1803 return FRAME_FOCUS_FRAME (XFRAME (frame));
1808 /* Return the value of frame parameter PROP in frame FRAME. */
1810 Lisp_Object
1811 get_frame_param (frame, prop)
1812 register struct frame *frame;
1813 Lisp_Object prop;
1815 register Lisp_Object tem;
1817 tem = Fassq (prop, frame->param_alist);
1818 if (EQ (tem, Qnil))
1819 return tem;
1820 return Fcdr (tem);
1823 /* Return the buffer-predicate of the selected frame. */
1825 Lisp_Object
1826 frame_buffer_predicate (frame)
1827 Lisp_Object frame;
1829 return XFRAME (frame)->buffer_predicate;
1832 /* Return the buffer-list of the selected frame. */
1834 Lisp_Object
1835 frame_buffer_list (frame)
1836 Lisp_Object frame;
1838 return XFRAME (frame)->buffer_list;
1841 /* Set the buffer-list of the selected frame. */
1843 void
1844 set_frame_buffer_list (frame, list)
1845 Lisp_Object frame, list;
1847 XFRAME (frame)->buffer_list = list;
1850 /* Discard BUFFER from the buffer-list of each frame. */
1852 void
1853 frames_discard_buffer (buffer)
1854 Lisp_Object buffer;
1856 Lisp_Object frame, tail;
1858 FOR_EACH_FRAME (tail, frame)
1860 XFRAME (frame)->buffer_list
1861 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1865 /* Move BUFFER to the end of the buffer-list of each frame. */
1867 void
1868 frames_bury_buffer (buffer)
1869 Lisp_Object buffer;
1871 Lisp_Object frame, tail;
1873 FOR_EACH_FRAME (tail, frame)
1875 struct frame *f = XFRAME (frame);
1876 Lisp_Object found;
1878 found = Fmemq (buffer, f->buffer_list);
1879 if (!NILP (found))
1880 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1881 Fcons (buffer, Qnil));
1885 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1886 If the alist already has an element for PROP, we change it. */
1888 void
1889 store_in_alist (alistptr, prop, val)
1890 Lisp_Object *alistptr, val;
1891 Lisp_Object prop;
1893 register Lisp_Object tem;
1895 tem = Fassq (prop, *alistptr);
1896 if (EQ (tem, Qnil))
1897 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1898 else
1899 Fsetcdr (tem, val);
1902 static int
1903 frame_name_fnn_p (str, len)
1904 char *str;
1905 int len;
1907 if (len > 1 && str[0] == 'F')
1909 char *end_ptr;
1911 strtol (str + 1, &end_ptr, 10);
1913 if (end_ptr == str + len)
1914 return 1;
1916 return 0;
1919 /* Set the name of the terminal frame. Also used by MSDOS frames.
1920 Modeled after x_set_name which is used for WINDOW frames. */
1922 void
1923 set_term_frame_name (f, name)
1924 struct frame *f;
1925 Lisp_Object name;
1927 f->explicit_name = ! NILP (name);
1929 /* If NAME is nil, set the name to F<num>. */
1930 if (NILP (name))
1932 char namebuf[20];
1934 /* Check for no change needed in this very common case
1935 before we do any consing. */
1936 if (frame_name_fnn_p (XSTRING (f->name)->data,
1937 STRING_BYTES (XSTRING (f->name))))
1938 return;
1940 terminal_frame_count++;
1941 sprintf (namebuf, "F%d", terminal_frame_count);
1942 name = build_string (namebuf);
1944 else
1946 CHECK_STRING (name, 0);
1948 /* Don't change the name if it's already NAME. */
1949 if (! NILP (Fstring_equal (name, f->name)))
1950 return;
1952 /* Don't allow the user to set the frame name to F<num>, so it
1953 doesn't clash with the names we generate for terminal frames. */
1954 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1955 error ("Frame names of the form F<num> are usurped by Emacs");
1958 f->name = name;
1959 update_mode_lines = 1;
1962 void
1963 store_frame_param (f, prop, val)
1964 struct frame *f;
1965 Lisp_Object prop, val;
1967 register Lisp_Object old_alist_elt;
1969 /* The buffer-alist parameter is stored in a special place and is
1970 not in the alist. */
1971 if (EQ (prop, Qbuffer_list))
1973 f->buffer_list = val;
1974 return;
1977 /* If PROP is a symbol which is supposed to have frame-local values,
1978 and it is set up based on this frame, switch to the global
1979 binding. That way, we can create or alter the frame-local binding
1980 without messing up the symbol's status. */
1981 if (SYMBOLP (prop))
1983 Lisp_Object valcontents;
1984 valcontents = XSYMBOL (prop)->value;
1985 if ((BUFFER_LOCAL_VALUEP (valcontents)
1986 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1987 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1988 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1989 swap_in_global_binding (prop);
1992 /* Update the frame parameter alist. */
1993 old_alist_elt = Fassq (prop, f->param_alist);
1994 if (EQ (old_alist_elt, Qnil))
1995 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1996 else
1997 Fsetcdr (old_alist_elt, val);
1999 /* Update some other special parameters in their special places
2000 in addition to the alist. */
2002 if (EQ (prop, Qbuffer_predicate))
2003 f->buffer_predicate = val;
2005 if (! FRAME_WINDOW_P (f))
2007 if (EQ (prop, Qmenu_bar_lines))
2008 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2009 else if (EQ (prop, Qname))
2010 set_term_frame_name (f, val);
2013 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2015 if (! MINI_WINDOW_P (XWINDOW (val)))
2016 error ("Surrogate minibuffer windows must be minibuffer windows.");
2018 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2019 && !EQ (val, f->minibuffer_window))
2020 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2022 /* Install the chosen minibuffer window, with proper buffer. */
2023 f->minibuffer_window = val;
2027 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2028 "Return the parameters-alist of frame FRAME.\n\
2029 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
2030 The meaningful PARMs depend on the kind of frame.\n\
2031 If FRAME is omitted, return information on the currently selected frame.")
2032 (frame)
2033 Lisp_Object frame;
2035 Lisp_Object alist;
2036 FRAME_PTR f;
2037 int height, width;
2038 struct gcpro gcpro1;
2040 if (EQ (frame, Qnil))
2041 frame = selected_frame;
2043 CHECK_FRAME (frame, 0);
2044 f = XFRAME (frame);
2046 if (!FRAME_LIVE_P (f))
2047 return Qnil;
2049 alist = Fcopy_alist (f->param_alist);
2050 GCPRO1 (alist);
2052 if (!FRAME_WINDOW_P (f))
2054 int fg = FRAME_FOREGROUND_PIXEL (f);
2055 int bg = FRAME_BACKGROUND_PIXEL (f);
2056 Lisp_Object elt;
2058 /* If the frame's parameter alist says the colors are
2059 unspecified and reversed, take the frame's background pixel
2060 for foreground and vice versa. */
2061 elt = Fassq (Qforeground_color, alist);
2062 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2064 if (strncmp (XSTRING (XCDR (elt))->data,
2065 unspecified_bg,
2066 XSTRING (XCDR (elt))->size) == 0)
2067 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2068 else if (strncmp (XSTRING (XCDR (elt))->data,
2069 unspecified_fg,
2070 XSTRING (XCDR (elt))->size) == 0)
2071 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2073 else
2074 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2075 elt = Fassq (Qbackground_color, alist);
2076 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2078 if (strncmp (XSTRING (XCDR (elt))->data,
2079 unspecified_fg,
2080 XSTRING (XCDR (elt))->size) == 0)
2081 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2082 else if (strncmp (XSTRING (XCDR (elt))->data,
2083 unspecified_bg,
2084 XSTRING (XCDR (elt))->size) == 0)
2085 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2087 else
2088 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2089 store_in_alist (&alist, intern ("font"),
2090 build_string (FRAME_MSDOS_P (f)
2091 ? "ms-dos"
2092 : FRAME_W32_P (f) ? "w32term" : "tty"));
2094 store_in_alist (&alist, Qname, f->name);
2095 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2096 store_in_alist (&alist, Qheight, make_number (height));
2097 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2098 store_in_alist (&alist, Qwidth, make_number (width));
2099 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2100 store_in_alist (&alist, Qminibuffer,
2101 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2102 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2103 : FRAME_MINIBUF_WINDOW (f)));
2104 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2105 store_in_alist (&alist, Qbuffer_list,
2106 frame_buffer_list (selected_frame));
2108 /* I think this should be done with a hook. */
2109 #ifdef HAVE_WINDOW_SYSTEM
2110 if (FRAME_WINDOW_P (f))
2111 x_report_frame_params (f, &alist);
2112 else
2113 #endif
2115 /* This ought to be correct in f->param_alist for an X frame. */
2116 Lisp_Object lines;
2117 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2118 store_in_alist (&alist, Qmenu_bar_lines, lines);
2121 UNGCPRO;
2122 return alist;
2126 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2127 "Return FRAME's value for parameter PARAMETER.\n\
2128 If FRAME is nil, describe the currently selected frame.")
2129 (frame, parameter)
2130 Lisp_Object frame, parameter;
2132 struct frame *f;
2133 Lisp_Object value;
2135 if (NILP (frame))
2136 frame = selected_frame;
2137 else
2138 CHECK_FRAME (frame, 0);
2139 CHECK_SYMBOL (parameter, 1);
2141 f = XFRAME (frame);
2142 value = Qnil;
2144 if (FRAME_LIVE_P (f))
2146 if (EQ (parameter, Qname))
2147 value = f->name;
2148 #ifdef HAVE_X_WINDOWS
2149 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2150 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2151 #endif /* HAVE_X_WINDOWS */
2152 else
2154 value = Fassq (parameter, f->param_alist);
2155 if (CONSP (value))
2157 value = XCDR (value);
2158 /* Fframe_parameters puts the actual fg/bg color names,
2159 even if f->param_alist says otherwise. This is
2160 important when param_alist's notion of colors is
2161 "unspecified". We need to do the same here. */
2162 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2164 char *color_name;
2165 EMACS_INT csz;
2167 if (EQ (parameter, Qbackground_color))
2169 color_name = XSTRING (value)->data;
2170 csz = XSTRING (value)->size;
2171 if (strncmp (color_name, unspecified_bg, csz) == 0)
2172 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2173 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2174 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2176 else if (EQ (parameter, Qforeground_color))
2178 color_name = XSTRING (value)->data;
2179 csz = XSTRING (value)->size;
2180 if (strncmp (color_name, unspecified_fg, csz) == 0)
2181 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2182 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2183 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2187 else if (EQ (parameter, Qdisplay_type)
2188 || EQ (parameter, Qbackground_mode))
2189 /* Avoid consing in frequent cases. */
2190 value = Qnil;
2191 else
2192 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2196 return value;
2200 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2201 Smodify_frame_parameters, 2, 2, 0,
2202 "Modify the parameters of frame FRAME according to ALIST.\n\
2203 ALIST is an alist of parameters to change and their new values.\n\
2204 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2205 The meaningful PARMs depend on the kind of frame.\n\
2206 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2207 so that `frame-parameters' will return them.\n\
2209 The value of frame parameter FOO can also be accessed\n\
2210 as a frame-local binding for the variable FOO, if you have\n\
2211 enabled such bindings for that variable with `make-variable-frame-local'.")
2212 (frame, alist)
2213 Lisp_Object frame, alist;
2215 FRAME_PTR f;
2216 register Lisp_Object tail, prop, val;
2218 if (EQ (frame, Qnil))
2219 frame = selected_frame;
2220 CHECK_LIVE_FRAME (frame, 0);
2221 f = XFRAME (frame);
2223 /* I think this should be done with a hook. */
2224 #ifdef HAVE_WINDOW_SYSTEM
2225 if (FRAME_WINDOW_P (f))
2226 x_set_frame_parameters (f, alist);
2227 else
2228 #endif
2229 #ifdef MSDOS
2230 if (FRAME_MSDOS_P (f))
2231 IT_set_frame_parameters (f, alist);
2232 else
2233 #endif
2236 int length = XINT (Flength (alist));
2237 int i;
2238 Lisp_Object *parms
2239 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2240 Lisp_Object *values
2241 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2243 /* Extract parm names and values into those vectors. */
2245 i = 0;
2246 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2248 Lisp_Object elt;
2250 elt = Fcar (tail);
2251 parms[i] = Fcar (elt);
2252 values[i] = Fcdr (elt);
2253 i++;
2256 /* Now process them in reverse of specified order. */
2257 for (i--; i >= 0; i--)
2259 prop = parms[i];
2260 val = values[i];
2261 store_frame_param (f, prop, val);
2265 return Qnil;
2268 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2269 0, 1, 0,
2270 "Height in pixels of a line in the font in frame FRAME.\n\
2271 If FRAME is omitted, the selected frame is used.\n\
2272 For a terminal frame, the value is always 1.")
2273 (frame)
2274 Lisp_Object frame;
2276 struct frame *f;
2278 if (NILP (frame))
2279 frame = selected_frame;
2280 CHECK_FRAME (frame, 0);
2281 f = XFRAME (frame);
2283 #ifdef HAVE_WINDOW_SYSTEM
2284 if (FRAME_WINDOW_P (f))
2285 return make_number (x_char_height (f));
2286 else
2287 #endif
2288 return make_number (1);
2292 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2293 0, 1, 0,
2294 "Width in pixels of characters in the font in frame FRAME.\n\
2295 If FRAME is omitted, the selected frame is used.\n\
2296 The width is the same for all characters, because\n\
2297 currently Emacs supports only fixed-width fonts.\n\
2298 For a terminal screen, the value is always 1.")
2299 (frame)
2300 Lisp_Object frame;
2302 struct frame *f;
2304 if (NILP (frame))
2305 frame = selected_frame;
2306 CHECK_FRAME (frame, 0);
2307 f = XFRAME (frame);
2309 #ifdef HAVE_WINDOW_SYSTEM
2310 if (FRAME_WINDOW_P (f))
2311 return make_number (x_char_width (f));
2312 else
2313 #endif
2314 return make_number (1);
2317 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2318 Sframe_pixel_height, 0, 1, 0,
2319 "Return a FRAME's height in pixels.\n\
2320 This counts only the height available for text lines,\n\
2321 not menu bars on window-system Emacs frames.\n\
2322 For a terminal frame, the result really gives the height in characters.\n\
2323 If FRAME is omitted, the selected frame is used.")
2324 (frame)
2325 Lisp_Object frame;
2327 struct frame *f;
2329 if (NILP (frame))
2330 frame = selected_frame;
2331 CHECK_FRAME (frame, 0);
2332 f = XFRAME (frame);
2334 #ifdef HAVE_WINDOW_SYSTEM
2335 if (FRAME_WINDOW_P (f))
2336 return make_number (x_pixel_height (f));
2337 else
2338 #endif
2339 return make_number (FRAME_HEIGHT (f));
2342 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2343 Sframe_pixel_width, 0, 1, 0,
2344 "Return FRAME's width in pixels.\n\
2345 For a terminal frame, the result really gives the width in characters.\n\
2346 If FRAME is omitted, the selected frame is used.")
2347 (frame)
2348 Lisp_Object frame;
2350 struct frame *f;
2352 if (NILP (frame))
2353 frame = selected_frame;
2354 CHECK_FRAME (frame, 0);
2355 f = XFRAME (frame);
2357 #ifdef HAVE_WINDOW_SYSTEM
2358 if (FRAME_WINDOW_P (f))
2359 return make_number (x_pixel_width (f));
2360 else
2361 #endif
2362 return make_number (FRAME_WIDTH (f));
2365 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2366 "Specify that the frame FRAME has LINES lines.\n\
2367 Optional third arg non-nil means that redisplay should use LINES lines\n\
2368 but that the idea of the actual height of the frame should not be changed.")
2369 (frame, lines, pretend)
2370 Lisp_Object frame, lines, pretend;
2372 register struct frame *f;
2374 CHECK_NUMBER (lines, 0);
2375 if (NILP (frame))
2376 frame = selected_frame;
2377 CHECK_LIVE_FRAME (frame, 0);
2378 f = XFRAME (frame);
2380 /* I think this should be done with a hook. */
2381 #ifdef HAVE_WINDOW_SYSTEM
2382 if (FRAME_WINDOW_P (f))
2384 if (XINT (lines) != f->height)
2385 x_set_window_size (f, 1, f->width, XINT (lines));
2386 do_pending_window_change (0);
2388 else
2389 #endif
2390 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2391 return Qnil;
2394 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2395 "Specify that the frame FRAME has COLS columns.\n\
2396 Optional third arg non-nil means that redisplay should use COLS columns\n\
2397 but that the idea of the actual width of the frame should not be changed.")
2398 (frame, cols, pretend)
2399 Lisp_Object frame, cols, pretend;
2401 register struct frame *f;
2402 CHECK_NUMBER (cols, 0);
2403 if (NILP (frame))
2404 frame = selected_frame;
2405 CHECK_LIVE_FRAME (frame, 0);
2406 f = XFRAME (frame);
2408 /* I think this should be done with a hook. */
2409 #ifdef HAVE_WINDOW_SYSTEM
2410 if (FRAME_WINDOW_P (f))
2412 if (XINT (cols) != f->width)
2413 x_set_window_size (f, 1, XINT (cols), f->height);
2414 do_pending_window_change (0);
2416 else
2417 #endif
2418 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2419 return Qnil;
2422 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2423 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2424 (frame, cols, rows)
2425 Lisp_Object frame, cols, rows;
2427 register struct frame *f;
2429 CHECK_LIVE_FRAME (frame, 0);
2430 CHECK_NUMBER (cols, 2);
2431 CHECK_NUMBER (rows, 1);
2432 f = XFRAME (frame);
2434 /* I think this should be done with a hook. */
2435 #ifdef HAVE_WINDOW_SYSTEM
2436 if (FRAME_WINDOW_P (f))
2438 if (XINT (rows) != f->height || XINT (cols) != f->width
2439 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2440 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2441 do_pending_window_change (0);
2443 else
2444 #endif
2445 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2447 return Qnil;
2450 DEFUN ("set-frame-position", Fset_frame_position,
2451 Sset_frame_position, 3, 3, 0,
2452 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2453 This is actually the position of the upper left corner of the frame.\n\
2454 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2455 the rightmost or bottommost possible position (that stays within the screen).")
2456 (frame, xoffset, yoffset)
2457 Lisp_Object frame, xoffset, yoffset;
2459 register struct frame *f;
2461 CHECK_LIVE_FRAME (frame, 0);
2462 CHECK_NUMBER (xoffset, 1);
2463 CHECK_NUMBER (yoffset, 2);
2464 f = XFRAME (frame);
2466 /* I think this should be done with a hook. */
2467 #ifdef HAVE_WINDOW_SYSTEM
2468 if (FRAME_WINDOW_P (f))
2469 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2470 #endif
2472 return Qt;
2476 void
2477 syms_of_frame ()
2479 syms_of_frame_1 ();
2481 staticpro (&Vframe_list);
2483 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2484 "The initial frame-object, which represents Emacs's stdout.");
2486 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2487 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2488 Vemacs_iconified = Qnil;
2490 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
2491 "If non-nil, function applied to the normal result of `mouse-position'.\n\
2492 This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
2493 which need to do mouse handling at the Lisp level.");
2494 Vmouse_position_function = Qnil;
2496 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2497 "Minibufferless frames use this frame's minibuffer.\n\
2499 Emacs cannot create minibufferless frames unless this is set to an\n\
2500 appropriate surrogate.\n\
2502 Emacs consults this variable only when creating minibufferless\n\
2503 frames; once the frame is created, it sticks with its assigned\n\
2504 minibuffer, no matter what this variable is set to. This means that\n\
2505 this variable doesn't necessarily say anything meaningful about the\n\
2506 current set of frames, or where the minibuffer is currently being\n\
2507 displayed.");
2509 defsubr (&Sactive_minibuffer_window);
2510 defsubr (&Sframep);
2511 defsubr (&Sframe_live_p);
2512 defsubr (&Smake_terminal_frame);
2513 defsubr (&Shandle_switch_frame);
2514 defsubr (&Signore_event);
2515 defsubr (&Sselect_frame);
2516 defsubr (&Sselected_frame);
2517 defsubr (&Swindow_frame);
2518 defsubr (&Sframe_root_window);
2519 defsubr (&Sframe_first_window);
2520 defsubr (&Sframe_selected_window);
2521 defsubr (&Sset_frame_selected_window);
2522 defsubr (&Sframe_list);
2523 defsubr (&Snext_frame);
2524 defsubr (&Sprevious_frame);
2525 defsubr (&Sdelete_frame);
2526 defsubr (&Smouse_position);
2527 defsubr (&Smouse_pixel_position);
2528 defsubr (&Sset_mouse_position);
2529 defsubr (&Sset_mouse_pixel_position);
2530 #if 0
2531 defsubr (&Sframe_configuration);
2532 defsubr (&Srestore_frame_configuration);
2533 #endif
2534 defsubr (&Smake_frame_visible);
2535 defsubr (&Smake_frame_invisible);
2536 defsubr (&Siconify_frame);
2537 defsubr (&Sframe_visible_p);
2538 defsubr (&Svisible_frame_list);
2539 defsubr (&Sraise_frame);
2540 defsubr (&Slower_frame);
2541 defsubr (&Sredirect_frame_focus);
2542 defsubr (&Sframe_focus);
2543 defsubr (&Sframe_parameters);
2544 defsubr (&Sframe_parameter);
2545 defsubr (&Smodify_frame_parameters);
2546 defsubr (&Sframe_char_height);
2547 defsubr (&Sframe_char_width);
2548 defsubr (&Sframe_pixel_height);
2549 defsubr (&Sframe_pixel_width);
2550 defsubr (&Sset_frame_height);
2551 defsubr (&Sset_frame_width);
2552 defsubr (&Sset_frame_size);
2553 defsubr (&Sset_frame_position);
2556 void
2557 keys_of_frame ()
2559 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2560 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2561 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2562 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");