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