(Fforward_comment): Undo the previous change, since cc-mode
[emacs.git] / src / frame.c
blob8aac87023e43a2dea0b5f2219644d539ebab8cd0
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999 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;
107 static void
108 syms_of_frame_1 ()
110 /*&&& init symbols here &&&*/
111 Qframep = intern ("framep");
112 staticpro (&Qframep);
113 Qframe_live_p = intern ("frame-live-p");
114 staticpro (&Qframe_live_p);
115 Qheight = intern ("height");
116 staticpro (&Qheight);
117 Qicon = intern ("icon");
118 staticpro (&Qicon);
119 Qminibuffer = intern ("minibuffer");
120 staticpro (&Qminibuffer);
121 Qmodeline = intern ("modeline");
122 staticpro (&Qmodeline);
123 Qname = intern ("name");
124 staticpro (&Qname);
125 Qonly = intern ("only");
126 staticpro (&Qonly);
127 Qunsplittable = intern ("unsplittable");
128 staticpro (&Qunsplittable);
129 Qmenu_bar_lines = intern ("menu-bar-lines");
130 staticpro (&Qmenu_bar_lines);
131 Qtool_bar_lines = intern ("tool-bar-lines");
132 staticpro (&Qtool_bar_lines);
133 Qwidth = intern ("width");
134 staticpro (&Qwidth);
135 Qx = intern ("x");
136 staticpro (&Qx);
137 Qw32 = intern ("w32");
138 staticpro (&Qw32);
139 Qpc = intern ("pc");
140 staticpro (&Qpc);
141 Qmac = intern ("mac");
142 staticpro (&Qmac);
143 Qvisible = intern ("visible");
144 staticpro (&Qvisible);
145 Qbuffer_predicate = intern ("buffer-predicate");
146 staticpro (&Qbuffer_predicate);
147 Qbuffer_list = intern ("buffer-list");
148 staticpro (&Qbuffer_list);
149 Qtitle = intern ("title");
150 staticpro (&Qtitle);
152 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
153 "Alist of default values for frame creation.\n\
154 These may be set in your init file, like this:\n\
155 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
156 These override values given in window system configuration data,\n\
157 including X Windows' defaults database.\n\
158 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
159 For values specific to the separate minibuffer frame, see\n\
160 `minibuffer-frame-alist'.\n\
161 The `menu-bar-lines' element of the list controls whether new frames\n\
162 have menu bars; `menu-bar-mode' works by altering this element.");
163 Vdefault_frame_alist = Qnil;
166 static void
167 set_menu_bar_lines_1 (window, n)
168 Lisp_Object window;
169 int n;
171 struct window *w = XWINDOW (window);
173 XSETFASTINT (w->last_modified, 0);
174 XSETFASTINT (w->top, XFASTINT (w->top) + n);
175 XSETFASTINT (w->height, XFASTINT (w->height) - n);
177 /* Handle just the top child in a vertical split. */
178 if (!NILP (w->vchild))
179 set_menu_bar_lines_1 (w->vchild, n);
181 /* Adjust all children in a horizontal split. */
182 for (window = w->hchild; !NILP (window); window = w->next)
184 w = XWINDOW (window);
185 set_menu_bar_lines_1 (window, n);
189 void
190 set_menu_bar_lines (f, value, oldval)
191 struct frame *f;
192 Lisp_Object value, oldval;
194 int nlines;
195 int olines = FRAME_MENU_BAR_LINES (f);
197 /* Right now, menu bars don't work properly in minibuf-only frames;
198 most of the commands try to apply themselves to the minibuffer
199 frame itself, and get an error because you can't switch buffers
200 in or split the minibuffer window. */
201 if (FRAME_MINIBUF_ONLY_P (f))
202 return;
204 if (INTEGERP (value))
205 nlines = XINT (value);
206 else
207 nlines = 0;
209 if (nlines != olines)
211 windows_or_buffers_changed++;
212 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
213 FRAME_MENU_BAR_LINES (f) = nlines;
214 set_menu_bar_lines_1 (f->root_window, nlines - olines);
215 adjust_glyphs (f);
219 #include "buffer.h"
221 /* These help us bind and responding to switch-frame events. */
222 #include "commands.h"
223 #include "keyboard.h"
225 Lisp_Object Vemacs_iconified;
226 Lisp_Object Vframe_list;
228 struct x_output tty_display;
230 extern Lisp_Object Vminibuffer_list;
231 extern Lisp_Object get_minibuffer ();
232 extern Lisp_Object Fhandle_switch_frame ();
233 extern Lisp_Object Fredirect_frame_focus ();
234 extern Lisp_Object x_get_focus_frame ();
236 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
237 "Return non-nil if OBJECT is a frame.\n\
238 Value is t for a termcap frame (a character-only terminal),\n\
239 `x' for an Emacs frame that is really an X window,\n\
240 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
241 `mac' for an Emacs frame on a Macintosh display,\n\
242 `pc' for a direct-write MS-DOS frame.\n\
243 See also `frame-live-p'.")
244 (object)
245 Lisp_Object object;
247 if (!FRAMEP (object))
248 return Qnil;
249 switch (XFRAME (object)->output_method)
251 case output_termcap:
252 return Qt;
253 case output_x_window:
254 return Qx;
255 case output_w32:
256 return Qw32;
257 case output_msdos_raw:
258 return Qpc;
259 case output_mac:
260 return Qmac;
261 default:
262 abort ();
266 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
267 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
268 Value is nil if OBJECT is not a live frame. If object is a live\n\
269 frame, the return value indicates what sort of output device it is\n\
270 displayed on. Value is t for a termcap frame (a character-only\n\
271 terminal), `x' for an Emacs frame being displayed in an X window.")
272 (object)
273 Lisp_Object object;
275 return ((FRAMEP (object)
276 && FRAME_LIVE_P (XFRAME (object)))
277 ? Fframep (object)
278 : Qnil);
281 struct frame *
282 make_frame (mini_p)
283 int mini_p;
285 Lisp_Object frame;
286 register struct frame *f;
287 register Lisp_Object root_window;
288 register Lisp_Object mini_window;
289 register struct Lisp_Vector *vec;
290 int i;
292 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
293 for (i = 0; i < VECSIZE (struct frame); i++)
294 XSETFASTINT (vec->contents[i], 0);
295 vec->size = VECSIZE (struct frame);
296 f = (struct frame *)vec;
297 XSETFRAME (frame, f);
299 f->desired_matrix = 0;
300 f->current_matrix = 0;
301 f->desired_pool = 0;
302 f->current_pool = 0;
303 f->glyphs_initialized_p = 0;
304 f->decode_mode_spec_buffer = 0;
305 f->visible = 0;
306 f->async_visible = 0;
307 f->output_data.nothing = 0;
308 f->iconified = 0;
309 f->async_iconified = 0;
310 f->wants_modeline = 1;
311 f->auto_raise = 0;
312 f->auto_lower = 0;
313 f->no_split = 0;
314 f->garbaged = 0;
315 f->has_minibuffer = mini_p;
316 f->focus_frame = Qnil;
317 f->explicit_name = 0;
318 f->can_have_scroll_bars = 0;
319 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
320 f->param_alist = Qnil;
321 f->scroll_bars = Qnil;
322 f->condemned_scroll_bars = Qnil;
323 f->face_alist = Qnil;
324 f->face_cache = NULL;
325 f->menu_bar_items = Qnil;
326 f->menu_bar_vector = Qnil;
327 f->menu_bar_items_used = 0;
328 f->buffer_predicate = Qnil;
329 f->buffer_list = Qnil;
330 #ifdef MULTI_KBOARD
331 f->kboard = initial_kboard;
332 #endif
333 f->namebuf = 0;
334 f->title = Qnil;
335 f->menu_bar_window = Qnil;
336 f->tool_bar_window = Qnil;
337 f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
338 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
339 f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
341 root_window = make_window ();
342 if (mini_p)
344 mini_window = make_window ();
345 XWINDOW (root_window)->next = mini_window;
346 XWINDOW (mini_window)->prev = root_window;
347 XWINDOW (mini_window)->mini_p = Qt;
348 XWINDOW (mini_window)->frame = frame;
349 f->minibuffer_window = mini_window;
351 else
353 mini_window = Qnil;
354 XWINDOW (root_window)->next = Qnil;
355 f->minibuffer_window = Qnil;
358 XWINDOW (root_window)->frame = frame;
360 /* 10 is arbitrary,
361 just so that there is "something there."
362 Correct size will be set up later with change_frame_size. */
364 SET_FRAME_WIDTH (f, 10);
365 f->height = 10;
367 XSETFASTINT (XWINDOW (root_window)->width, 10);
368 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
370 if (mini_p)
372 XSETFASTINT (XWINDOW (mini_window)->width, 10);
373 XSETFASTINT (XWINDOW (mini_window)->top, 9);
374 XSETFASTINT (XWINDOW (mini_window)->height, 1);
377 /* Choose a buffer for the frame's root window. */
379 Lisp_Object buf;
381 XWINDOW (root_window)->buffer = Qt;
382 buf = Fcurrent_buffer ();
383 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
384 a space), try to find another one. */
385 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
386 buf = Fother_buffer (buf, Qnil, Qnil);
388 /* Use set_window_buffer, not Fset_window_buffer, and don't let
389 hooks be run by it. The reason is that the whole frame/window
390 arrangement is not yet fully intialized at this point. Windows
391 don't have the right size, glyph matrices aren't initialized
392 etc. Running Lisp functions at this point surely ends in a
393 SEGV. */
394 set_window_buffer (root_window, buf, 0);
395 f->buffer_list = Fcons (buf, Qnil);
398 if (mini_p)
400 XWINDOW (mini_window)->buffer = Qt;
401 set_window_buffer (mini_window,
402 (NILP (Vminibuffer_list)
403 ? get_minibuffer (0)
404 : Fcar (Vminibuffer_list)),
408 f->root_window = root_window;
409 f->selected_window = root_window;
410 /* Make sure this window seems more recently used than
411 a newly-created, never-selected window. */
412 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
414 #ifdef HAVE_WINDOW_SYSTEM
415 f->fontset_data = alloc_fontset_data ();
416 #endif
418 return f;
421 #ifdef HAVE_WINDOW_SYSTEM
422 /* Make a frame using a separate minibuffer window on another frame.
423 MINI_WINDOW is the minibuffer window to use. nil means use the
424 default (the global minibuffer). */
426 struct frame *
427 make_frame_without_minibuffer (mini_window, kb, display)
428 register Lisp_Object mini_window;
429 KBOARD *kb;
430 Lisp_Object display;
432 register struct frame *f;
433 struct gcpro gcpro1;
435 if (!NILP (mini_window))
436 CHECK_LIVE_WINDOW (mini_window, 0);
438 #ifdef MULTI_KBOARD
439 if (!NILP (mini_window)
440 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
441 error ("frame and minibuffer must be on the same display");
442 #endif
444 /* Make a frame containing just a root window. */
445 f = make_frame (0);
447 if (NILP (mini_window))
449 /* Use default-minibuffer-frame if possible. */
450 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
451 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
453 Lisp_Object frame_dummy;
455 XSETFRAME (frame_dummy, f);
456 GCPRO1 (frame_dummy);
457 /* If there's no minibuffer frame to use, create one. */
458 kb->Vdefault_minibuffer_frame =
459 call1 (intern ("make-initial-minibuffer-frame"), display);
460 UNGCPRO;
463 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
466 f->minibuffer_window = mini_window;
468 /* Make the chosen minibuffer window display the proper minibuffer,
469 unless it is already showing a minibuffer. */
470 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
471 Fset_window_buffer (mini_window,
472 (NILP (Vminibuffer_list)
473 ? get_minibuffer (0)
474 : Fcar (Vminibuffer_list)));
475 return f;
478 /* Make a frame containing only a minibuffer window. */
480 struct frame *
481 make_minibuffer_frame ()
483 /* First make a frame containing just a root window, no minibuffer. */
485 register struct frame *f = make_frame (0);
486 register Lisp_Object mini_window;
487 register Lisp_Object frame;
489 XSETFRAME (frame, f);
491 f->auto_raise = 0;
492 f->auto_lower = 0;
493 f->no_split = 1;
494 f->wants_modeline = 0;
495 f->has_minibuffer = 1;
497 /* Now label the root window as also being the minibuffer.
498 Avoid infinite looping on the window chain by marking next pointer
499 as nil. */
501 mini_window = f->minibuffer_window = f->root_window;
502 XWINDOW (mini_window)->mini_p = Qt;
503 XWINDOW (mini_window)->next = Qnil;
504 XWINDOW (mini_window)->prev = Qnil;
505 XWINDOW (mini_window)->frame = frame;
507 /* Put the proper buffer in that window. */
509 Fset_window_buffer (mini_window,
510 (NILP (Vminibuffer_list)
511 ? get_minibuffer (0)
512 : Fcar (Vminibuffer_list)));
513 return f;
515 #endif /* HAVE_WINDOW_SYSTEM */
517 /* Construct a frame that refers to the terminal (stdin and stdout). */
519 static int terminal_frame_count;
521 struct frame *
522 make_terminal_frame ()
524 register struct frame *f;
525 Lisp_Object frame;
526 char name[20];
528 #ifdef MULTI_KBOARD
529 if (!initial_kboard)
531 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
532 init_kboard (initial_kboard);
533 initial_kboard->next_kboard = all_kboards;
534 all_kboards = initial_kboard;
536 #endif
538 /* The first call must initialize Vframe_list. */
539 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
540 Vframe_list = Qnil;
542 f = make_frame (1);
544 XSETFRAME (frame, f);
545 Vframe_list = Fcons (frame, Vframe_list);
547 terminal_frame_count++;
548 sprintf (name, "F%d", terminal_frame_count);
549 f->name = build_string (name);
551 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
552 f->async_visible = 1; /* Don't let visible be cleared later. */
553 #ifdef MSDOS
554 f->output_data.x = &the_only_x_display;
555 if (!inhibit_window_system
556 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
557 || XFRAME (selected_frame)->output_method == output_msdos_raw))
558 f->output_method = output_msdos_raw;
559 else
560 f->output_method = output_termcap;
561 #else
562 #ifdef macintosh
563 f->output_data.mac = NewMacWindow(f);
564 f->output_data.mac->background_pixel = 0xffffff;
565 f->output_data.mac->foreground_pixel = 0;
566 f->output_data.mac->n_param_faces = 0;
567 f->output_data.mac->n_computed_faces = 0;
568 f->output_data.mac->size_computed_faces = 0;
569 f->output_method = output_mac;
570 f->auto_raise = 1;
571 f->auto_lower = 1;
572 init_frame_faces (f);
573 #else /* !macintosh */
574 f->output_data.x = &tty_display;
575 #endif /* !macintosh */
576 #endif /* MSDOS */
578 #ifndef macintosh
579 if (!noninteractive)
580 init_frame_faces (f);
581 #endif
582 return f;
585 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
586 1, 1, 0, "Create an additional terminal frame.\n\
587 You can create multiple frames on a text-only terminal in this way.\n\
588 Only the selected terminal frame is actually displayed.\n\
589 This function takes one argument, an alist specifying frame parameters.\n\
590 In practice, generally you don't need to specify any parameters.\n\
591 Note that changing the size of one terminal frame automatically affects all.")
592 (parms)
593 Lisp_Object parms;
595 struct frame *f;
596 Lisp_Object frame, tem;
597 struct frame *sf = SELECTED_FRAME ();
599 #ifdef MSDOS
600 if (sf->output_method != output_msdos_raw
601 && sf->output_method != output_termcap)
602 abort ();
603 #else /* not MSDOS */
605 #ifdef macintosh
606 if (sf->output_method != output_mac)
607 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
608 #else
609 if (sf->output_method != output_termcap)
610 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
611 #endif
612 #endif /* not MSDOS */
614 f = make_terminal_frame ();
616 change_frame_size (f, FRAME_HEIGHT (sf),
617 FRAME_WIDTH (sf), 0, 0, 0);
618 adjust_glyphs (f);
619 calculate_costs (f);
620 XSETFRAME (frame, f);
621 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
622 Fmodify_frame_parameters (frame, parms);
624 /* Make the frame face alist be frame-specific, so that each
625 frame could change its face definitions independently. */
626 f->face_alist = Fcopy_alist (sf->face_alist);
627 /* Simple Fcopy_alist isn't enough, because we need the contents of
628 the vectors which are the CDRs of associations in face_alist to
629 be copied as well. */
630 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
631 XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
632 return frame;
635 Lisp_Object
636 do_switch_frame (frame, no_enter, track)
637 Lisp_Object frame, no_enter;
638 int track;
640 struct frame *sf = SELECTED_FRAME ();
642 /* If FRAME is a switch-frame event, extract the frame we should
643 switch to. */
644 if (CONSP (frame)
645 && EQ (XCAR (frame), Qswitch_frame)
646 && CONSP (XCDR (frame)))
647 frame = XCAR (XCDR (frame));
649 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
650 a switch-frame event to arrive after a frame is no longer live,
651 especially when deleting the initial frame during startup. */
652 CHECK_FRAME (frame, 0);
653 if (! FRAME_LIVE_P (XFRAME (frame)))
654 return Qnil;
656 if (sf == XFRAME (frame))
657 return frame;
659 /* This is too greedy; it causes inappropriate focus redirection
660 that's hard to get rid of. */
661 #if 0
662 /* If a frame's focus has been redirected toward the currently
663 selected frame, we should change the redirection to point to the
664 newly selected frame. This means that if the focus is redirected
665 from a minibufferless frame to a surrogate minibuffer frame, we
666 can use `other-window' to switch between all the frames using
667 that minibuffer frame, and the focus redirection will follow us
668 around. */
669 if (track)
671 Lisp_Object tail;
673 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
675 Lisp_Object focus;
677 if (!FRAMEP (XCAR (tail)))
678 abort ();
680 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
682 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
683 Fredirect_frame_focus (XCAR (tail), frame);
686 #else /* ! 0 */
687 /* Instead, apply it only to the frame we're pointing to. */
688 #ifdef HAVE_WINDOW_SYSTEM
689 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
691 Lisp_Object focus, xfocus;
693 xfocus = x_get_focus_frame (XFRAME (frame));
694 if (FRAMEP (xfocus))
696 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
697 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
698 Fredirect_frame_focus (xfocus, frame);
701 #endif /* HAVE_X_WINDOWS */
702 #endif /* ! 0 */
704 selected_frame = frame;
705 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
706 last_nonminibuf_frame = XFRAME (selected_frame);
708 Fselect_window (XFRAME (frame)->selected_window);
710 /* We want to make sure that the next event generates a frame-switch
711 event to the appropriate frame. This seems kludgy to me, but
712 before you take it out, make sure that evaluating something like
713 (select-window (frame-root-window (new-frame))) doesn't end up
714 with your typing being interpreted in the new frame instead of
715 the one you're actually typing in. */
716 internal_last_event_frame = Qnil;
718 return frame;
721 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
722 "Select the frame FRAME.\n\
723 Subsequent editing commands apply to its selected window.\n\
724 The selection of FRAME lasts until the next time the user does\n\
725 something to select a different frame, or until the next time this\n\
726 function is called.")
727 (frame, no_enter)
728 Lisp_Object frame, no_enter;
730 return do_switch_frame (frame, no_enter, 1);
734 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
735 "Handle a switch-frame event EVENT.\n\
736 Switch-frame events are usually bound to this function.\n\
737 A switch-frame event tells Emacs that the window manager has requested\n\
738 that the user's events be directed to the frame mentioned in the event.\n\
739 This function selects the selected window of the frame of EVENT.\n\
741 If EVENT is frame object, handle it as if it were a switch-frame event\n\
742 to that frame.")
743 (event, no_enter)
744 Lisp_Object event, no_enter;
746 /* Preserve prefix arg that the command loop just cleared. */
747 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
748 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
749 return do_switch_frame (event, no_enter, 0);
752 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
753 "Do nothing, but preserve any prefix argument already specified.\n\
754 This is a suitable binding for iconify-frame and make-frame-visible.")
757 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
758 return Qnil;
761 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
762 "Return the frame that is now selected.")
765 return selected_frame;
768 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
769 "Return the frame object that window WINDOW is on.")
770 (window)
771 Lisp_Object window;
773 CHECK_LIVE_WINDOW (window, 0);
774 return XWINDOW (window)->frame;
777 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
778 "Returns the topmost, leftmost window of FRAME.\n\
779 If omitted, FRAME defaults to the currently selected frame.")
780 (frame)
781 Lisp_Object frame;
783 Lisp_Object w;
785 if (NILP (frame))
786 w = SELECTED_FRAME ()->root_window;
787 else
789 CHECK_LIVE_FRAME (frame, 0);
790 w = XFRAME (frame)->root_window;
792 while (NILP (XWINDOW (w)->buffer))
794 if (! NILP (XWINDOW (w)->hchild))
795 w = XWINDOW (w)->hchild;
796 else if (! NILP (XWINDOW (w)->vchild))
797 w = XWINDOW (w)->vchild;
798 else
799 abort ();
801 return w;
804 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
805 Sactive_minibuffer_window, 0, 0, 0,
806 "Return the currently active minibuffer window, or nil if none.")
809 return minibuf_level ? minibuf_window : Qnil;
812 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
813 "Returns the root-window of FRAME.\n\
814 If omitted, FRAME defaults to the currently selected frame.")
815 (frame)
816 Lisp_Object frame;
818 Lisp_Object window;
820 if (NILP (frame))
821 window = SELECTED_FRAME ()->root_window;
822 else
824 CHECK_LIVE_FRAME (frame, 0);
825 window = XFRAME (frame)->root_window;
828 return window;
831 DEFUN ("frame-selected-window", Fframe_selected_window,
832 Sframe_selected_window, 0, 1, 0,
833 "Return the selected window of frame object FRAME.\n\
834 If omitted, FRAME defaults to the currently selected frame.")
835 (frame)
836 Lisp_Object frame;
838 Lisp_Object window;
840 if (NILP (frame))
841 window = SELECTED_FRAME ()->selected_window;
842 else
844 CHECK_LIVE_FRAME (frame, 0);
845 window = XFRAME (frame)->selected_window;
848 return window;
851 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
852 Sset_frame_selected_window, 2, 2, 0,
853 "Set the selected window of frame object FRAME to WINDOW.\n\
854 If FRAME is nil, the selected frame is used.\n\
855 If FRAME is the selected frame, this makes WINDOW the selected window.")
856 (frame, window)
857 Lisp_Object frame, window;
859 if (NILP (frame))
860 frame = selected_frame;
862 CHECK_LIVE_FRAME (frame, 0);
863 CHECK_LIVE_WINDOW (window, 1);
865 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
866 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
868 if (EQ (frame, selected_frame))
869 return Fselect_window (window);
871 return XFRAME (frame)->selected_window = window;
874 DEFUN ("frame-list", Fframe_list, Sframe_list,
875 0, 0, 0,
876 "Return a list of all frames.")
879 return Fcopy_sequence (Vframe_list);
882 /* Return the next frame in the frame list after FRAME.
883 If MINIBUF is nil, exclude minibuffer-only frames.
884 If MINIBUF is a window, include only its own frame
885 and any frame now using that window as the minibuffer.
886 If MINIBUF is `visible', include all visible frames.
887 If MINIBUF is 0, include all visible and iconified frames.
888 Otherwise, include all frames. */
890 Lisp_Object
891 next_frame (frame, minibuf)
892 Lisp_Object frame;
893 Lisp_Object minibuf;
895 Lisp_Object tail;
896 int passed = 0;
898 /* There must always be at least one frame in Vframe_list. */
899 if (! CONSP (Vframe_list))
900 abort ();
902 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
903 forever. Forestall that. */
904 CHECK_LIVE_FRAME (frame, 0);
906 while (1)
907 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
909 Lisp_Object f;
911 f = XCAR (tail);
913 if (passed
914 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
916 /* Decide whether this frame is eligible to be returned. */
918 /* If we've looped all the way around without finding any
919 eligible frames, return the original frame. */
920 if (EQ (f, frame))
921 return f;
923 /* Let minibuf decide if this frame is acceptable. */
924 if (NILP (minibuf))
926 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
927 return f;
929 else if (EQ (minibuf, Qvisible))
931 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
932 if (FRAME_VISIBLE_P (XFRAME (f)))
933 return f;
935 else if (XFASTINT (minibuf) == 0)
937 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
938 if (FRAME_VISIBLE_P (XFRAME (f))
939 || FRAME_ICONIFIED_P (XFRAME (f)))
940 return f;
942 else if (WINDOWP (minibuf))
944 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
945 /* Check that F either is, or has forwarded its focus to,
946 MINIBUF's frame. */
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 /* Check that F either is, or has forwarded its focus to,
1006 MINIBUF's frame. */
1007 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1008 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1009 FRAME_FOCUS_FRAME (XFRAME (f)))))
1010 prev = f;
1012 else if (EQ (minibuf, Qvisible))
1014 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1015 if (FRAME_VISIBLE_P (XFRAME (f)))
1016 prev = f;
1018 else if (XFASTINT (minibuf) == 0)
1020 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1021 if (FRAME_VISIBLE_P (XFRAME (f))
1022 || FRAME_ICONIFIED_P (XFRAME (f)))
1023 prev = f;
1025 else
1026 prev = f;
1030 /* We've scanned the entire list. */
1031 if (NILP (prev))
1032 /* We went through the whole frame list without finding a single
1033 acceptable frame. Return the original frame. */
1034 return frame;
1035 else
1036 /* There were no acceptable frames in the list before FRAME; otherwise,
1037 we would have returned directly from the loop. Since PREV is the last
1038 acceptable frame in the list, return it. */
1039 return prev;
1043 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1044 "Return the next frame in the frame list after FRAME.\n\
1045 It considers only frames on the same terminal as FRAME.\n\
1046 By default, skip minibuffer-only frames.\n\
1047 If omitted, FRAME defaults to the selected frame.\n\
1048 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1049 If MINIFRAME is a window, include only its own frame\n\
1050 and any frame now using that window as the minibuffer.\n\
1051 If MINIFRAME is `visible', include all visible frames.\n\
1052 If MINIFRAME is 0, include all visible and iconified frames.\n\
1053 Otherwise, include all frames.")
1054 (frame, miniframe)
1055 Lisp_Object frame, miniframe;
1057 if (NILP (frame))
1058 frame = selected_frame;
1060 CHECK_LIVE_FRAME (frame, 0);
1061 return next_frame (frame, miniframe);
1064 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1065 "Return the previous frame in the frame list before FRAME.\n\
1066 It considers only frames on the same terminal as FRAME.\n\
1067 By default, skip minibuffer-only frames.\n\
1068 If omitted, FRAME defaults to the selected frame.\n\
1069 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1070 If MINIFRAME is a window, include only its own frame\n\
1071 and any frame now using that window as the minibuffer.\n\
1072 If MINIFRAME is `visible', include all visible frames.\n\
1073 If MINIFRAME is 0, include all visible and iconified frames.\n\
1074 Otherwise, include all frames.")
1075 (frame, miniframe)
1076 Lisp_Object frame, miniframe;
1078 if (NILP (frame))
1079 frame = selected_frame;
1080 CHECK_LIVE_FRAME (frame, 0);
1081 return prev_frame (frame, miniframe);
1084 /* Return 1 if it is ok to delete frame F;
1085 0 if all frames aside from F are invisible.
1086 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1089 other_visible_frames (f)
1090 FRAME_PTR f;
1092 /* We know the selected frame is visible,
1093 so if F is some other frame, it can't be the sole visible one. */
1094 if (f == SELECTED_FRAME ())
1096 Lisp_Object frames;
1097 int count = 0;
1099 for (frames = Vframe_list;
1100 CONSP (frames);
1101 frames = XCDR (frames))
1103 Lisp_Object this;
1105 this = XCAR (frames);
1106 /* Verify that the frame's window still exists
1107 and we can still talk to it. And note any recent change
1108 in visibility. */
1109 #ifdef HAVE_WINDOW_SYSTEM
1110 if (FRAME_WINDOW_P (XFRAME (this)))
1112 x_sync (XFRAME (this));
1113 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1115 #endif
1117 if (FRAME_VISIBLE_P (XFRAME (this))
1118 || FRAME_ICONIFIED_P (XFRAME (this))
1119 /* Allow deleting the terminal frame when at least
1120 one X frame exists! */
1121 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1122 count++;
1124 return count > 1;
1126 return 1;
1129 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1130 "Delete FRAME, permanently eliminating it from use.\n\
1131 If omitted, FRAME defaults to the selected frame.\n\
1132 A frame may not be deleted if its minibuffer is used by other frames.\n\
1133 Normally, you may not delete a frame if all other frames are invisible,\n\
1134 but if the second optional argument FORCE is non-nil, you may do so.")
1135 (frame, force)
1136 Lisp_Object frame, force;
1138 struct frame *f;
1139 struct frame *sf = SELECTED_FRAME ();
1140 int minibuffer_selected;
1142 if (EQ (frame, Qnil))
1144 f = sf;
1145 XSETFRAME (frame, f);
1147 else
1149 CHECK_FRAME (frame, 0);
1150 f = XFRAME (frame);
1153 if (! FRAME_LIVE_P (f))
1154 return Qnil;
1156 if (NILP (force) && !other_visible_frames (f))
1157 error ("Attempt to delete the sole visible or iconified frame");
1159 #if 0
1160 /* This is a nice idea, but x_connection_closed needs to be able
1161 to delete the last frame, if it is gone. */
1162 if (NILP (XCDR (Vframe_list)))
1163 error ("Attempt to delete the only frame");
1164 #endif
1166 /* Does this frame have a minibuffer, and is it the surrogate
1167 minibuffer for any other frame? */
1168 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1170 Lisp_Object frames;
1172 for (frames = Vframe_list;
1173 CONSP (frames);
1174 frames = XCDR (frames))
1176 Lisp_Object this;
1177 this = XCAR (frames);
1179 if (! EQ (this, frame)
1180 && EQ (frame,
1181 WINDOW_FRAME (XWINDOW
1182 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1183 error ("Attempt to delete a surrogate minibuffer frame");
1187 minibuffer_selected = EQ (minibuf_window, selected_window);
1189 /* Don't let the frame remain selected. */
1190 if (f == sf)
1192 Lisp_Object tail, frame1;
1194 /* Look for another visible frame on the same terminal. */
1195 frame1 = next_frame (frame, Qvisible);
1197 /* If there is none, find *some* other frame. */
1198 if (NILP (frame1) || EQ (frame1, frame))
1200 FOR_EACH_FRAME (tail, frame1)
1202 if (! EQ (frame, frame1))
1203 break;
1207 do_switch_frame (frame1, Qnil, 0);
1208 sf = SELECTED_FRAME ();
1211 /* Don't allow minibuf_window to remain on a deleted frame. */
1212 if (EQ (f->minibuffer_window, minibuf_window))
1214 Fset_window_buffer (sf->minibuffer_window,
1215 XWINDOW (minibuf_window)->buffer);
1216 minibuf_window = sf->minibuffer_window;
1218 /* If the dying minibuffer window was selected,
1219 select the new one. */
1220 if (minibuffer_selected)
1221 Fselect_window (minibuf_window);
1224 /* Clear any X selections for this frame. */
1225 #ifdef HAVE_X_WINDOWS
1226 if (FRAME_X_P (f))
1227 x_clear_frame_selections (f);
1228 #endif
1230 /* Free glyphs.
1231 This function must be called before the window tree of the
1232 frame is deleted because windows contain dynamically allocated
1233 memory. */
1234 free_glyphs (f);
1236 /* Mark all the windows that used to be on FRAME as deleted, and then
1237 remove the reference to them. */
1238 delete_all_subwindows (XWINDOW (f->root_window));
1239 f->root_window = Qnil;
1241 Vframe_list = Fdelq (frame, Vframe_list);
1242 FRAME_SET_VISIBLE (f, 0);
1244 if (f->namebuf)
1245 xfree (f->namebuf);
1246 if (FRAME_INSERT_COST (f))
1247 xfree (FRAME_INSERT_COST (f));
1248 if (FRAME_DELETEN_COST (f))
1249 xfree (FRAME_DELETEN_COST (f));
1250 if (FRAME_INSERTN_COST (f))
1251 xfree (FRAME_INSERTN_COST (f));
1252 if (FRAME_DELETE_COST (f))
1253 xfree (FRAME_DELETE_COST (f));
1254 if (FRAME_MESSAGE_BUF (f))
1255 xfree (FRAME_MESSAGE_BUF (f));
1257 #ifdef HAVE_WINDOW_SYSTEM
1258 /* Free all fontset data. */
1259 free_fontset_data (FRAME_FONTSET_DATA (f));
1260 #endif
1262 /* Since some events are handled at the interrupt level, we may get
1263 an event for f at any time; if we zero out the frame's display
1264 now, then we may trip up the event-handling code. Instead, we'll
1265 promise that the display of the frame must be valid until we have
1266 called the window-system-dependent frame destruction routine. */
1268 /* I think this should be done with a hook. */
1269 #ifdef HAVE_WINDOW_SYSTEM
1270 if (FRAME_WINDOW_P (f))
1271 x_destroy_window (f);
1272 #endif
1274 /* Done by x_destroy_window above already */
1275 #if 0
1276 #ifdef macintosh
1277 if (FRAME_MAC_P (f))
1278 DisposeMacWindow (f->output_data.mac);
1279 #endif
1280 #endif
1282 f->output_data.nothing = 0;
1284 /* If we've deleted the last_nonminibuf_frame, then try to find
1285 another one. */
1286 if (f == last_nonminibuf_frame)
1288 Lisp_Object frames;
1290 last_nonminibuf_frame = 0;
1292 for (frames = Vframe_list;
1293 CONSP (frames);
1294 frames = XCDR (frames))
1296 f = XFRAME (XCAR (frames));
1297 if (!FRAME_MINIBUF_ONLY_P (f))
1299 last_nonminibuf_frame = f;
1300 break;
1305 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1306 find another one. Prefer minibuffer-only frames, but also notice
1307 frames with other windows. */
1308 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1310 Lisp_Object frames;
1312 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1313 Lisp_Object frame_with_minibuf;
1314 /* Some frame we found on the same kboard, or nil if there are none. */
1315 Lisp_Object frame_on_same_kboard;
1317 frame_on_same_kboard = Qnil;
1318 frame_with_minibuf = Qnil;
1320 for (frames = Vframe_list;
1321 CONSP (frames);
1322 frames = XCDR (frames))
1324 Lisp_Object this;
1325 struct frame *f1;
1327 this = XCAR (frames);
1328 if (!FRAMEP (this))
1329 abort ();
1330 f1 = XFRAME (this);
1332 /* Consider only frames on the same kboard
1333 and only those with minibuffers. */
1334 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1335 && FRAME_HAS_MINIBUF_P (f1))
1337 frame_with_minibuf = this;
1338 if (FRAME_MINIBUF_ONLY_P (f1))
1339 break;
1342 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1343 frame_on_same_kboard = this;
1346 if (!NILP (frame_on_same_kboard))
1348 /* We know that there must be some frame with a minibuffer out
1349 there. If this were not true, all of the frames present
1350 would have to be minibufferless, which implies that at some
1351 point their minibuffer frames must have been deleted, but
1352 that is prohibited at the top; you can't delete surrogate
1353 minibuffer frames. */
1354 if (NILP (frame_with_minibuf))
1355 abort ();
1357 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1359 else
1360 /* No frames left on this kboard--say no minibuffer either. */
1361 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1364 /* Cause frame titles to update--necessary if we now have just one frame. */
1365 update_mode_lines = 1;
1367 return Qnil;
1370 /* Return mouse position in character cell units. */
1372 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1373 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1374 The position is given in character cells, where (0, 0) is the\n\
1375 upper-left corner.\n\
1376 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1377 to read the mouse position, it returns the selected frame for FRAME\n\
1378 and nil for X and Y.")
1381 FRAME_PTR f;
1382 Lisp_Object lispy_dummy;
1383 enum scroll_bar_part party_dummy;
1384 Lisp_Object x, y;
1385 int col, row;
1386 unsigned long long_dummy;
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 return Fcons (lispy_dummy, Fcons (x, y));
1411 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1412 Smouse_pixel_position, 0, 0, 0,
1413 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1414 The position is given in pixel units, where (0, 0) is the\n\
1415 upper-left corner.\n\
1416 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1417 to read the mouse position, it returns the selected frame for FRAME\n\
1418 and nil for X and Y.")
1421 FRAME_PTR f;
1422 Lisp_Object lispy_dummy;
1423 enum scroll_bar_part party_dummy;
1424 Lisp_Object x, y;
1425 unsigned long long_dummy;
1427 f = SELECTED_FRAME ();
1428 x = y = Qnil;
1430 #ifdef HAVE_MOUSE
1431 /* It's okay for the hook to refrain from storing anything. */
1432 if (mouse_position_hook)
1433 (*mouse_position_hook) (&f, -1,
1434 &lispy_dummy, &party_dummy,
1435 &x, &y,
1436 &long_dummy);
1437 #endif
1438 XSETFRAME (lispy_dummy, f);
1439 return Fcons (lispy_dummy, Fcons (x, y));
1442 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1443 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1444 Coordinates are relative to the frame, not a window,\n\
1445 so the coordinates of the top left character in the frame\n\
1446 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1448 This function is a no-op for an X frame that is not visible.\n\
1449 If you have just created a frame, you must wait for it to become visible\n\
1450 before calling this function on it, like this.\n\
1451 (while (not (frame-visible-p frame)) (sleep-for .5))")
1452 (frame, x, y)
1453 Lisp_Object frame, x, y;
1455 CHECK_LIVE_FRAME (frame, 0);
1456 CHECK_NUMBER (x, 2);
1457 CHECK_NUMBER (y, 1);
1459 /* I think this should be done with a hook. */
1460 #ifdef HAVE_WINDOW_SYSTEM
1461 if (FRAME_WINDOW_P (XFRAME (frame)))
1462 /* Warping the mouse will cause enternotify and focus events. */
1463 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1464 #else
1465 #if defined (MSDOS) && defined (HAVE_MOUSE)
1466 if (FRAME_MSDOS_P (XFRAME (frame)))
1468 Fselect_frame (frame, Qnil);
1469 mouse_moveto (XINT (x), XINT (y));
1471 #endif
1472 #endif
1474 return Qnil;
1477 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1478 Sset_mouse_pixel_position, 3, 3, 0,
1479 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1480 Note, this is a no-op for an X frame that is not visible.\n\
1481 If you have just created a frame, you must wait for it to become visible\n\
1482 before calling this function on it, like this.\n\
1483 (while (not (frame-visible-p frame)) (sleep-for .5))")
1484 (frame, x, y)
1485 Lisp_Object frame, x, y;
1487 CHECK_LIVE_FRAME (frame, 0);
1488 CHECK_NUMBER (x, 2);
1489 CHECK_NUMBER (y, 1);
1491 /* I think this should be done with a hook. */
1492 #ifdef HAVE_WINDOW_SYSTEM
1493 if (FRAME_WINDOW_P (XFRAME (frame)))
1494 /* Warping the mouse will cause enternotify and focus events. */
1495 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1496 #else
1497 #if defined (MSDOS) && defined (HAVE_MOUSE)
1498 if (FRAME_MSDOS_P (XFRAME (frame)))
1500 Fselect_frame (frame, Qnil);
1501 mouse_moveto (XINT (x), XINT (y));
1503 #endif
1504 #endif
1506 return Qnil;
1509 static void make_frame_visible_1 P_ ((Lisp_Object));
1511 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1512 0, 1, "",
1513 "Make the frame FRAME visible (assuming it is an X-window).\n\
1514 If omitted, FRAME defaults to the currently selected frame.")
1515 (frame)
1516 Lisp_Object frame;
1518 if (NILP (frame))
1519 frame = selected_frame;
1521 CHECK_LIVE_FRAME (frame, 0);
1523 /* I think this should be done with a hook. */
1524 #ifdef HAVE_WINDOW_SYSTEM
1525 if (FRAME_WINDOW_P (XFRAME (frame)))
1527 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1528 x_make_frame_visible (XFRAME (frame));
1530 #endif
1532 make_frame_visible_1 (XFRAME (frame)->root_window);
1534 /* Make menu bar update for the Buffers and Frams menus. */
1535 windows_or_buffers_changed++;
1537 return frame;
1540 /* Update the display_time slot of the buffers shown in WINDOW
1541 and all its descendents. */
1543 static void
1544 make_frame_visible_1 (window)
1545 Lisp_Object window;
1547 struct window *w;
1549 for (;!NILP (window); window = w->next)
1551 w = XWINDOW (window);
1553 if (!NILP (w->buffer))
1554 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1556 if (!NILP (w->vchild))
1557 make_frame_visible_1 (w->vchild);
1558 if (!NILP (w->hchild))
1559 make_frame_visible_1 (w->hchild);
1563 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1564 0, 2, "",
1565 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1566 If omitted, FRAME defaults to the currently selected frame.\n\
1567 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1568 but if the second optional argument FORCE is non-nil, you may do so.")
1569 (frame, force)
1570 Lisp_Object frame, force;
1572 if (NILP (frame))
1573 frame = selected_frame;
1575 CHECK_LIVE_FRAME (frame, 0);
1577 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1578 error ("Attempt to make invisible the sole visible or iconified frame");
1580 #if 0 /* This isn't logically necessary, and it can do GC. */
1581 /* Don't let the frame remain selected. */
1582 if (EQ (frame, selected_frame))
1583 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1584 #endif
1586 /* Don't allow minibuf_window to remain on a deleted frame. */
1587 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1589 struct frame *sf = XFRAME (selected_frame);
1590 Fset_window_buffer (sf->minibuffer_window,
1591 XWINDOW (minibuf_window)->buffer);
1592 minibuf_window = sf->minibuffer_window;
1595 /* I think this should be done with a hook. */
1596 #ifdef HAVE_WINDOW_SYSTEM
1597 if (FRAME_WINDOW_P (XFRAME (frame)))
1598 x_make_frame_invisible (XFRAME (frame));
1599 #endif
1601 /* Make menu bar update for the Buffers and Frams menus. */
1602 windows_or_buffers_changed++;
1604 return Qnil;
1607 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1608 0, 1, "",
1609 "Make the frame FRAME into an icon.\n\
1610 If omitted, FRAME defaults to the currently selected frame.")
1611 (frame)
1612 Lisp_Object frame;
1614 if (NILP (frame))
1615 frame = selected_frame;
1617 CHECK_LIVE_FRAME (frame, 0);
1619 #if 0 /* This isn't logically necessary, and it can do GC. */
1620 /* Don't let the frame remain selected. */
1621 if (EQ (frame, selected_frame))
1622 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1623 #endif
1625 /* Don't allow minibuf_window to remain on a deleted frame. */
1626 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1628 struct frame *sf = XFRAME (selected_frame);
1629 Fset_window_buffer (sf->minibuffer_window,
1630 XWINDOW (minibuf_window)->buffer);
1631 minibuf_window = sf->minibuffer_window;
1634 /* I think this should be done with a hook. */
1635 #ifdef HAVE_WINDOW_SYSTEM
1636 if (FRAME_WINDOW_P (XFRAME (frame)))
1637 x_iconify_frame (XFRAME (frame));
1638 #endif
1640 /* Make menu bar update for the Buffers and Frams menus. */
1641 windows_or_buffers_changed++;
1643 return Qnil;
1646 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1647 1, 1, 0,
1648 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1649 A frame that is not \"visible\" is not updated and, if it works through\n\
1650 a window system, it may not show at all.\n\
1651 Return the symbol `icon' if frame is visible only as an icon.")
1652 (frame)
1653 Lisp_Object frame;
1655 CHECK_LIVE_FRAME (frame, 0);
1657 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1659 if (FRAME_VISIBLE_P (XFRAME (frame)))
1660 return Qt;
1661 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1662 return Qicon;
1663 return Qnil;
1666 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1667 0, 0, 0,
1668 "Return a list of all frames now \"visible\" (being updated).")
1671 Lisp_Object tail, frame;
1672 struct frame *f;
1673 Lisp_Object value;
1675 value = Qnil;
1676 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1678 frame = XCAR (tail);
1679 if (!FRAMEP (frame))
1680 continue;
1681 f = XFRAME (frame);
1682 if (FRAME_VISIBLE_P (f))
1683 value = Fcons (frame, value);
1685 return value;
1689 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1690 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1691 If FRAME is invisible, make it visible.\n\
1692 If you don't specify a frame, the selected frame is used.\n\
1693 If Emacs is displaying on an ordinary terminal or some other device which\n\
1694 doesn't support multiple overlapping frames, this function does nothing.")
1695 (frame)
1696 Lisp_Object frame;
1698 if (NILP (frame))
1699 frame = selected_frame;
1701 CHECK_LIVE_FRAME (frame, 0);
1703 /* Do like the documentation says. */
1704 Fmake_frame_visible (frame);
1706 if (frame_raise_lower_hook)
1707 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1709 return Qnil;
1712 /* Should we have a corresponding function called Flower_Power? */
1713 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1714 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1715 If you don't specify a frame, the selected frame is used.\n\
1716 If Emacs is displaying on an ordinary terminal or some other device which\n\
1717 doesn't support multiple overlapping frames, this function does nothing.")
1718 (frame)
1719 Lisp_Object frame;
1721 if (NILP (frame))
1722 frame = selected_frame;
1724 CHECK_LIVE_FRAME (frame, 0);
1726 if (frame_raise_lower_hook)
1727 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1729 return Qnil;
1733 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1734 1, 2, 0,
1735 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1736 In other words, switch-frame events caused by events in FRAME will\n\
1737 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1738 FOCUS-FRAME after reading an event typed at FRAME.\n\
1740 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1741 cancelled, and the frame again receives its own keystrokes.\n\
1743 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1744 a surrogate minibuffer frame when a frame doesn't have its own\n\
1745 minibuffer window.\n\
1747 A frame's focus redirection can be changed by select-frame. If frame\n\
1748 FOO is selected, and then a different frame BAR is selected, any\n\
1749 frames redirecting their focus to FOO are shifted to redirect their\n\
1750 focus to BAR. This allows focus redirection to work properly when the\n\
1751 user switches from one frame to another using `select-window'.\n\
1753 This means that a frame whose focus is redirected to itself is treated\n\
1754 differently from a frame whose focus is redirected to nil; the former\n\
1755 is affected by select-frame, while the latter is not.\n\
1757 The redirection lasts until `redirect-frame-focus' is called to change it.")
1758 (frame, focus_frame)
1759 Lisp_Object frame, focus_frame;
1761 /* Note that we don't check for a live frame here. It's reasonable
1762 to redirect the focus of a frame you're about to delete, if you
1763 know what other frame should receive those keystrokes. */
1764 CHECK_FRAME (frame, 0);
1766 if (! NILP (focus_frame))
1767 CHECK_LIVE_FRAME (focus_frame, 1);
1769 XFRAME (frame)->focus_frame = focus_frame;
1771 if (frame_rehighlight_hook)
1772 (*frame_rehighlight_hook) (XFRAME (frame));
1774 return Qnil;
1778 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1779 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1780 This returns nil if FRAME's focus is not redirected.\n\
1781 See `redirect-frame-focus'.")
1782 (frame)
1783 Lisp_Object frame;
1785 CHECK_LIVE_FRAME (frame, 0);
1787 return FRAME_FOCUS_FRAME (XFRAME (frame));
1792 /* Return the value of frame parameter PROP in frame FRAME. */
1794 Lisp_Object
1795 get_frame_param (frame, prop)
1796 register struct frame *frame;
1797 Lisp_Object prop;
1799 register Lisp_Object tem;
1801 tem = Fassq (prop, frame->param_alist);
1802 if (EQ (tem, Qnil))
1803 return tem;
1804 return Fcdr (tem);
1807 /* Return the buffer-predicate of the selected frame. */
1809 Lisp_Object
1810 frame_buffer_predicate (frame)
1811 Lisp_Object frame;
1813 return XFRAME (frame)->buffer_predicate;
1816 /* Return the buffer-list of the selected frame. */
1818 Lisp_Object
1819 frame_buffer_list (frame)
1820 Lisp_Object frame;
1822 return XFRAME (frame)->buffer_list;
1825 /* Set the buffer-list of the selected frame. */
1827 void
1828 set_frame_buffer_list (frame, list)
1829 Lisp_Object frame, list;
1831 XFRAME (frame)->buffer_list = list;
1834 /* Discard BUFFER from the buffer-list of each frame. */
1836 void
1837 frames_discard_buffer (buffer)
1838 Lisp_Object buffer;
1840 Lisp_Object frame, tail;
1842 FOR_EACH_FRAME (tail, frame)
1844 XFRAME (frame)->buffer_list
1845 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1849 /* Move BUFFER to the end of the buffer-list of each frame. */
1851 void
1852 frames_bury_buffer (buffer)
1853 Lisp_Object buffer;
1855 Lisp_Object frame, tail;
1857 FOR_EACH_FRAME (tail, frame)
1859 XFRAME (frame)->buffer_list
1860 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1861 Fcons (buffer, Qnil));
1865 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1866 If the alist already has an element for PROP, we change it. */
1868 void
1869 store_in_alist (alistptr, prop, val)
1870 Lisp_Object *alistptr, val;
1871 Lisp_Object prop;
1873 register Lisp_Object tem;
1875 tem = Fassq (prop, *alistptr);
1876 if (EQ (tem, Qnil))
1877 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1878 else
1879 Fsetcdr (tem, val);
1882 static int
1883 frame_name_fnn_p (str, len)
1884 char *str;
1885 int len;
1887 if (len > 1 && str[0] == 'F')
1889 char *end_ptr;
1891 strtol (str + 1, &end_ptr, 10);
1893 if (end_ptr == str + len)
1894 return 1;
1896 return 0;
1899 /* Set the name of the terminal frame. Also used by MSDOS frames.
1900 Modeled after x_set_name which is used for WINDOW frames. */
1902 void
1903 set_term_frame_name (f, name)
1904 struct frame *f;
1905 Lisp_Object name;
1907 f->explicit_name = ! NILP (name);
1909 /* If NAME is nil, set the name to F<num>. */
1910 if (NILP (name))
1912 char namebuf[20];
1914 /* Check for no change needed in this very common case
1915 before we do any consing. */
1916 if (frame_name_fnn_p (XSTRING (f->name)->data,
1917 STRING_BYTES (XSTRING (f->name))))
1918 return;
1920 terminal_frame_count++;
1921 sprintf (namebuf, "F%d", terminal_frame_count);
1922 name = build_string (namebuf);
1924 else
1926 CHECK_STRING (name, 0);
1928 /* Don't change the name if it's already NAME. */
1929 if (! NILP (Fstring_equal (name, f->name)))
1930 return;
1932 /* Don't allow the user to set the frame name to F<num>, so it
1933 doesn't clash with the names we generate for terminal frames. */
1934 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1935 error ("Frame names of the form F<num> are usurped by Emacs");
1938 f->name = name;
1939 update_mode_lines = 1;
1942 void
1943 store_frame_param (f, prop, val)
1944 struct frame *f;
1945 Lisp_Object prop, val;
1947 register Lisp_Object tem;
1949 if (EQ (prop, Qbuffer_list))
1951 f->buffer_list = val;
1952 return;
1955 tem = Fassq (prop, f->param_alist);
1956 if (EQ (tem, Qnil))
1957 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1958 else
1959 Fsetcdr (tem, val);
1961 if (EQ (prop, Qbuffer_predicate))
1962 f->buffer_predicate = val;
1964 if (! FRAME_WINDOW_P (f))
1966 if (EQ (prop, Qmenu_bar_lines))
1967 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1968 else if (EQ (prop, Qname))
1969 set_term_frame_name (f, val);
1972 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1974 if (! MINI_WINDOW_P (XWINDOW (val)))
1975 error ("Surrogate minibuffer windows must be minibuffer windows.");
1977 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1978 && !EQ (val, f->minibuffer_window))
1979 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1981 /* Install the chosen minibuffer window, with proper buffer. */
1982 f->minibuffer_window = val;
1986 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1987 "Return the parameters-alist of frame FRAME.\n\
1988 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1989 The meaningful PARMs depend on the kind of frame.\n\
1990 If FRAME is omitted, return information on the currently selected frame.")
1991 (frame)
1992 Lisp_Object frame;
1994 Lisp_Object alist;
1995 FRAME_PTR f;
1996 int height, width;
1997 struct gcpro gcpro1;
1999 if (EQ (frame, Qnil))
2000 frame = selected_frame;
2002 CHECK_FRAME (frame, 0);
2003 f = XFRAME (frame);
2005 if (!FRAME_LIVE_P (f))
2006 return Qnil;
2008 alist = Fcopy_alist (f->param_alist);
2009 GCPRO1 (alist);
2011 if (!FRAME_WINDOW_P (f))
2013 int fg = FRAME_FOREGROUND_PIXEL (f);
2014 int bg = FRAME_BACKGROUND_PIXEL (f);
2016 store_in_alist (&alist, intern ("foreground-color"),
2017 tty_color_name (f, fg));
2018 store_in_alist (&alist, intern ("background-color"),
2019 tty_color_name (f, bg));
2020 store_in_alist (&alist, intern ("font"),
2021 build_string (FRAME_MSDOS_P (f)
2022 ? "ms-dos"
2023 : FRAME_W32_P (f) ? "w32term" : "tty"));
2025 store_in_alist (&alist, Qname, f->name);
2026 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2027 store_in_alist (&alist, Qheight, make_number (height));
2028 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2029 store_in_alist (&alist, Qwidth, make_number (width));
2030 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2031 store_in_alist (&alist, Qminibuffer,
2032 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2033 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2034 : FRAME_MINIBUF_WINDOW (f)));
2035 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2036 store_in_alist (&alist, Qbuffer_list,
2037 frame_buffer_list (selected_frame));
2039 /* I think this should be done with a hook. */
2040 #ifdef HAVE_WINDOW_SYSTEM
2041 if (FRAME_WINDOW_P (f))
2042 x_report_frame_params (f, &alist);
2043 else
2044 #endif
2046 /* This ought to be correct in f->param_alist for an X frame. */
2047 Lisp_Object lines;
2048 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2049 store_in_alist (&alist, Qmenu_bar_lines, lines);
2052 UNGCPRO;
2053 return alist;
2056 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2057 Smodify_frame_parameters, 2, 2, 0,
2058 "Modify the parameters of frame FRAME according to ALIST.\n\
2059 ALIST is an alist of parameters to change and their new values.\n\
2060 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2061 The meaningful PARMs depend on the kind of frame.\n\
2062 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2063 so that `frame-parameters' will return them.")
2064 (frame, alist)
2065 Lisp_Object frame, alist;
2067 FRAME_PTR f;
2068 register Lisp_Object tail, prop, val;
2070 if (EQ (frame, Qnil))
2071 frame = selected_frame;
2072 CHECK_LIVE_FRAME (frame, 0);
2073 f = XFRAME (frame);
2075 /* I think this should be done with a hook. */
2076 #ifdef HAVE_WINDOW_SYSTEM
2077 if (FRAME_WINDOW_P (f))
2078 x_set_frame_parameters (f, alist);
2079 else
2080 #endif
2081 #ifdef MSDOS
2082 if (FRAME_MSDOS_P (f))
2083 IT_set_frame_parameters (f, alist);
2084 else
2085 #endif
2086 #ifdef macintosh
2087 if (FRAME_MAC_P (f))
2088 mac_set_frame_parameters (f, alist);
2089 else
2090 #endif
2093 int length = XINT (Flength (alist));
2094 int i;
2095 Lisp_Object *parms
2096 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2097 Lisp_Object *values
2098 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2100 /* Extract parm names and values into those vectors. */
2102 i = 0;
2103 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2105 Lisp_Object elt;
2107 elt = Fcar (tail);
2108 parms[i] = Fcar (elt);
2109 values[i] = Fcdr (elt);
2110 i++;
2113 /* Now process them in reverse of specified order. */
2114 for (i--; i >= 0; i--)
2116 prop = parms[i];
2117 val = values[i];
2118 store_frame_param (f, prop, val);
2122 return Qnil;
2125 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2126 0, 1, 0,
2127 "Height in pixels of a line in the font in frame FRAME.\n\
2128 If FRAME is omitted, the selected frame is used.\n\
2129 For a terminal frame, the value is always 1.")
2130 (frame)
2131 Lisp_Object frame;
2133 struct frame *f;
2135 if (NILP (frame))
2136 frame = selected_frame;
2137 CHECK_FRAME (frame, 0);
2138 f = XFRAME (frame);
2140 #ifdef HAVE_WINDOW_SYSTEM
2141 if (FRAME_WINDOW_P (f))
2142 return make_number (x_char_height (f));
2143 else
2144 #endif
2145 return make_number (1);
2149 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2150 0, 1, 0,
2151 "Width in pixels of characters in the font in frame FRAME.\n\
2152 If FRAME is omitted, the selected frame is used.\n\
2153 The width is the same for all characters, because\n\
2154 currently Emacs supports only fixed-width fonts.\n\
2155 For a terminal screen, the value is always 1.")
2156 (frame)
2157 Lisp_Object frame;
2159 struct frame *f;
2161 if (NILP (frame))
2162 frame = selected_frame;
2163 CHECK_FRAME (frame, 0);
2164 f = XFRAME (frame);
2166 #ifdef HAVE_WINDOW_SYSTEM
2167 if (FRAME_WINDOW_P (f))
2168 return make_number (x_char_width (f));
2169 else
2170 #endif
2171 return make_number (1);
2174 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2175 Sframe_pixel_height, 0, 1, 0,
2176 "Return a FRAME's height in pixels.\n\
2177 This counts only the height available for text lines,\n\
2178 not menu bars on window-system Emacs frames.\n\
2179 For a terminal frame, the result really gives the height in characters.\n\
2180 If FRAME is omitted, the selected frame is used.")
2181 (frame)
2182 Lisp_Object frame;
2184 struct frame *f;
2186 if (NILP (frame))
2187 frame = selected_frame;
2188 CHECK_FRAME (frame, 0);
2189 f = XFRAME (frame);
2191 #ifdef HAVE_WINDOW_SYSTEM
2192 if (FRAME_WINDOW_P (f))
2193 return make_number (x_pixel_height (f));
2194 else
2195 #endif
2196 return make_number (FRAME_HEIGHT (f));
2199 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2200 Sframe_pixel_width, 0, 1, 0,
2201 "Return FRAME's width in pixels.\n\
2202 For a terminal frame, the result really gives the width in characters.\n\
2203 If FRAME is omitted, the selected frame is used.")
2204 (frame)
2205 Lisp_Object frame;
2207 struct frame *f;
2209 if (NILP (frame))
2210 frame = selected_frame;
2211 CHECK_FRAME (frame, 0);
2212 f = XFRAME (frame);
2214 #ifdef HAVE_WINDOW_SYSTEM
2215 if (FRAME_WINDOW_P (f))
2216 return make_number (x_pixel_width (f));
2217 else
2218 #endif
2219 return make_number (FRAME_WIDTH (f));
2222 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2223 "Specify that the frame FRAME has LINES lines.\n\
2224 Optional third arg non-nil means that redisplay should use LINES lines\n\
2225 but that the idea of the actual height of the frame should not be changed.")
2226 (frame, lines, pretend)
2227 Lisp_Object frame, lines, pretend;
2229 register struct frame *f;
2231 CHECK_NUMBER (lines, 0);
2232 if (NILP (frame))
2233 frame = selected_frame;
2234 CHECK_LIVE_FRAME (frame, 0);
2235 f = XFRAME (frame);
2237 /* I think this should be done with a hook. */
2238 #ifdef HAVE_WINDOW_SYSTEM
2239 if (FRAME_WINDOW_P (f))
2241 if (XINT (lines) != f->height)
2242 x_set_window_size (f, 1, f->width, XINT (lines));
2243 do_pending_window_change (0);
2245 else
2246 #endif
2247 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2248 return Qnil;
2251 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2252 "Specify that the frame FRAME has COLS columns.\n\
2253 Optional third arg non-nil means that redisplay should use COLS columns\n\
2254 but that the idea of the actual width of the frame should not be changed.")
2255 (frame, cols, pretend)
2256 Lisp_Object frame, cols, pretend;
2258 register struct frame *f;
2259 CHECK_NUMBER (cols, 0);
2260 if (NILP (frame))
2261 frame = selected_frame;
2262 CHECK_LIVE_FRAME (frame, 0);
2263 f = XFRAME (frame);
2265 /* I think this should be done with a hook. */
2266 #ifdef HAVE_WINDOW_SYSTEM
2267 if (FRAME_WINDOW_P (f))
2269 if (XINT (cols) != f->width)
2270 x_set_window_size (f, 1, XINT (cols), f->height);
2271 do_pending_window_change (0);
2273 else
2274 #endif
2275 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2276 return Qnil;
2279 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2280 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2281 (frame, cols, rows)
2282 Lisp_Object frame, cols, rows;
2284 register struct frame *f;
2286 CHECK_LIVE_FRAME (frame, 0);
2287 CHECK_NUMBER (cols, 2);
2288 CHECK_NUMBER (rows, 1);
2289 f = XFRAME (frame);
2291 /* I think this should be done with a hook. */
2292 #ifdef HAVE_WINDOW_SYSTEM
2293 if (FRAME_WINDOW_P (f))
2295 if (XINT (rows) != f->height || XINT (cols) != f->width
2296 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2297 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2298 do_pending_window_change (0);
2300 else
2301 #endif
2302 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2304 return Qnil;
2307 DEFUN ("set-frame-position", Fset_frame_position,
2308 Sset_frame_position, 3, 3, 0,
2309 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2310 This is actually the position of the upper left corner of the frame.\n\
2311 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2312 the rightmost or bottommost possible position (that stays within the screen).")
2313 (frame, xoffset, yoffset)
2314 Lisp_Object frame, xoffset, yoffset;
2316 register struct frame *f;
2318 CHECK_LIVE_FRAME (frame, 0);
2319 CHECK_NUMBER (xoffset, 1);
2320 CHECK_NUMBER (yoffset, 2);
2321 f = XFRAME (frame);
2323 /* I think this should be done with a hook. */
2324 #ifdef HAVE_WINDOW_SYSTEM
2325 if (FRAME_WINDOW_P (f))
2326 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2327 #endif
2329 return Qt;
2333 void
2334 syms_of_frame ()
2336 syms_of_frame_1 ();
2338 staticpro (&Vframe_list);
2340 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2341 "The initial frame-object, which represents Emacs's stdout.");
2343 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2344 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2345 Vemacs_iconified = Qnil;
2347 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2348 "Minibufferless frames use this frame's minibuffer.\n\
2350 Emacs cannot create minibufferless frames unless this is set to an\n\
2351 appropriate surrogate.\n\
2353 Emacs consults this variable only when creating minibufferless\n\
2354 frames; once the frame is created, it sticks with its assigned\n\
2355 minibuffer, no matter what this variable is set to. This means that\n\
2356 this variable doesn't necessarily say anything meaningful about the\n\
2357 current set of frames, or where the minibuffer is currently being\n\
2358 displayed.");
2360 defsubr (&Sactive_minibuffer_window);
2361 defsubr (&Sframep);
2362 defsubr (&Sframe_live_p);
2363 defsubr (&Smake_terminal_frame);
2364 defsubr (&Shandle_switch_frame);
2365 defsubr (&Signore_event);
2366 defsubr (&Sselect_frame);
2367 defsubr (&Sselected_frame);
2368 defsubr (&Swindow_frame);
2369 defsubr (&Sframe_root_window);
2370 defsubr (&Sframe_first_window);
2371 defsubr (&Sframe_selected_window);
2372 defsubr (&Sset_frame_selected_window);
2373 defsubr (&Sframe_list);
2374 defsubr (&Snext_frame);
2375 defsubr (&Sprevious_frame);
2376 defsubr (&Sdelete_frame);
2377 defsubr (&Smouse_position);
2378 defsubr (&Smouse_pixel_position);
2379 defsubr (&Sset_mouse_position);
2380 defsubr (&Sset_mouse_pixel_position);
2381 #if 0
2382 defsubr (&Sframe_configuration);
2383 defsubr (&Srestore_frame_configuration);
2384 #endif
2385 defsubr (&Smake_frame_visible);
2386 defsubr (&Smake_frame_invisible);
2387 defsubr (&Siconify_frame);
2388 defsubr (&Sframe_visible_p);
2389 defsubr (&Svisible_frame_list);
2390 defsubr (&Sraise_frame);
2391 defsubr (&Slower_frame);
2392 defsubr (&Sredirect_frame_focus);
2393 defsubr (&Sframe_focus);
2394 defsubr (&Sframe_parameters);
2395 defsubr (&Smodify_frame_parameters);
2396 defsubr (&Sframe_char_height);
2397 defsubr (&Sframe_char_width);
2398 defsubr (&Sframe_pixel_height);
2399 defsubr (&Sframe_pixel_width);
2400 defsubr (&Sset_frame_height);
2401 defsubr (&Sset_frame_width);
2402 defsubr (&Sset_frame_size);
2403 defsubr (&Sset_frame_position);
2406 void
2407 keys_of_frame ()
2409 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2410 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2411 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2412 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");