64-bit on Solaris now works.
[emacs.git] / src / frame.c
blob714aaad9d7715be62852415713879e6dd54d4c37
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <config.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "charset.h"
26 #ifdef HAVE_X_WINDOWS
27 #include "xterm.h"
28 #endif
29 #ifdef WINDOWSNT
30 #include "w32term.h"
31 #endif
32 #include "buffer.h"
33 /* These help us bind and responding to switch-frame events. */
34 #include "commands.h"
35 #include "keyboard.h"
36 #include "frame.h"
37 #ifdef HAVE_WINDOW_SYSTEM
38 #include "fontset.h"
39 #endif
40 #include "termhooks.h"
41 #include "dispextern.h"
42 #include "window.h"
43 #ifdef MSDOS
44 #include "msdos.h"
45 #include "dosfns.h"
46 #endif
48 #ifdef macintosh
49 extern struct mac_output *NewMacWindow ();
50 extern void DisposeMacWindow (struct mac_output *);
51 #endif
53 /* Evaluate this expression to rebuild the section of syms_of_frame
54 that initializes and staticpros the symbols declared below. Note
55 that Emacs 18 has a bug that keeps C-x C-e from being able to
56 evaluate this expression.
58 (progn
59 ;; Accumulate a list of the symbols we want to initialize from the
60 ;; declarations at the top of the file.
61 (goto-char (point-min))
62 (search-forward "/\*&&& symbols declared here &&&*\/\n")
63 (let (symbol-list)
64 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
65 (setq symbol-list
66 (cons (buffer-substring (match-beginning 1) (match-end 1))
67 symbol-list))
68 (forward-line 1))
69 (setq symbol-list (nreverse symbol-list))
70 ;; Delete the section of syms_of_... where we initialize the symbols.
71 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
72 (let ((start (point)))
73 (while (looking-at "^ Q")
74 (forward-line 2))
75 (kill-region start (point)))
76 ;; Write a new symbol initialization section.
77 (while symbol-list
78 (insert (format " %s = intern (\"" (car symbol-list)))
79 (let ((start (point)))
80 (insert (substring (car symbol-list) 1))
81 (subst-char-in-region start (point) ?_ ?-))
82 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
83 (setq symbol-list (cdr symbol-list)))))
84 */
86 /*&&& symbols declared here &&&*/
87 Lisp_Object Qframep;
88 Lisp_Object Qframe_live_p;
89 Lisp_Object Qheight;
90 Lisp_Object Qicon;
91 Lisp_Object Qminibuffer;
92 Lisp_Object Qmodeline;
93 Lisp_Object Qname;
94 Lisp_Object Qonly;
95 Lisp_Object Qunsplittable;
96 Lisp_Object Qmenu_bar_lines;
97 Lisp_Object Qtool_bar_lines;
98 Lisp_Object Qwidth;
99 Lisp_Object Qx;
100 Lisp_Object Qw32;
101 Lisp_Object Qpc;
102 Lisp_Object Qmac;
103 Lisp_Object Qvisible;
104 Lisp_Object Qbuffer_predicate;
105 Lisp_Object Qbuffer_list;
106 Lisp_Object Qtitle;
108 Lisp_Object Vterminal_frame;
109 Lisp_Object Vdefault_frame_alist;
110 Lisp_Object Vmouse_position_function;
112 static void
113 syms_of_frame_1 ()
115 /*&&& init symbols here &&&*/
116 Qframep = intern ("framep");
117 staticpro (&Qframep);
118 Qframe_live_p = intern ("frame-live-p");
119 staticpro (&Qframe_live_p);
120 Qheight = intern ("height");
121 staticpro (&Qheight);
122 Qicon = intern ("icon");
123 staticpro (&Qicon);
124 Qminibuffer = intern ("minibuffer");
125 staticpro (&Qminibuffer);
126 Qmodeline = intern ("modeline");
127 staticpro (&Qmodeline);
128 Qname = intern ("name");
129 staticpro (&Qname);
130 Qonly = intern ("only");
131 staticpro (&Qonly);
132 Qunsplittable = intern ("unsplittable");
133 staticpro (&Qunsplittable);
134 Qmenu_bar_lines = intern ("menu-bar-lines");
135 staticpro (&Qmenu_bar_lines);
136 Qtool_bar_lines = intern ("tool-bar-lines");
137 staticpro (&Qtool_bar_lines);
138 Qwidth = intern ("width");
139 staticpro (&Qwidth);
140 Qx = intern ("x");
141 staticpro (&Qx);
142 Qw32 = intern ("w32");
143 staticpro (&Qw32);
144 Qpc = intern ("pc");
145 staticpro (&Qpc);
146 Qmac = intern ("mac");
147 staticpro (&Qmac);
148 Qvisible = intern ("visible");
149 staticpro (&Qvisible);
150 Qbuffer_predicate = intern ("buffer-predicate");
151 staticpro (&Qbuffer_predicate);
152 Qbuffer_list = intern ("buffer-list");
153 staticpro (&Qbuffer_list);
154 Qtitle = intern ("title");
155 staticpro (&Qtitle);
157 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
158 "Alist of default values for frame creation.\n\
159 These may be set in your init file, like this:\n\
160 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
161 These override values given in window system configuration data,\n\
162 including X Windows' defaults database.\n\
163 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
164 For values specific to the separate minibuffer frame, see\n\
165 `minibuffer-frame-alist'.\n\
166 The `menu-bar-lines' element of the list controls whether new frames\n\
167 have menu bars; `menu-bar-mode' works by altering this element.");
168 Vdefault_frame_alist = Qnil;
171 static void
172 set_menu_bar_lines_1 (window, n)
173 Lisp_Object window;
174 int n;
176 struct window *w = XWINDOW (window);
178 XSETFASTINT (w->last_modified, 0);
179 XSETFASTINT (w->top, XFASTINT (w->top) + n);
180 XSETFASTINT (w->height, XFASTINT (w->height) - n);
182 if (INTEGERP (w->orig_top))
183 XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
184 if (INTEGERP (w->orig_height))
185 XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
187 /* Handle just the top child in a vertical split. */
188 if (!NILP (w->vchild))
189 set_menu_bar_lines_1 (w->vchild, n);
191 /* Adjust all children in a horizontal split. */
192 for (window = w->hchild; !NILP (window); window = w->next)
194 w = XWINDOW (window);
195 set_menu_bar_lines_1 (window, n);
199 void
200 set_menu_bar_lines (f, value, oldval)
201 struct frame *f;
202 Lisp_Object value, oldval;
204 int nlines;
205 int olines = FRAME_MENU_BAR_LINES (f);
207 /* Right now, menu bars don't work properly in minibuf-only frames;
208 most of the commands try to apply themselves to the minibuffer
209 frame itself, and get an error because you can't switch buffers
210 in or split the minibuffer window. */
211 if (FRAME_MINIBUF_ONLY_P (f))
212 return;
214 if (INTEGERP (value))
215 nlines = XINT (value);
216 else
217 nlines = 0;
219 if (nlines != olines)
221 windows_or_buffers_changed++;
222 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
223 FRAME_MENU_BAR_LINES (f) = nlines;
224 set_menu_bar_lines_1 (f->root_window, nlines - olines);
225 adjust_glyphs (f);
229 Lisp_Object Vemacs_iconified;
230 Lisp_Object Vframe_list;
232 struct x_output tty_display;
234 extern Lisp_Object Vminibuffer_list;
235 extern Lisp_Object get_minibuffer ();
236 extern Lisp_Object Fhandle_switch_frame ();
237 extern Lisp_Object Fredirect_frame_focus ();
238 extern Lisp_Object x_get_focus_frame ();
240 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
241 "Return non-nil if OBJECT is a frame.\n\
242 Value is t for a termcap frame (a character-only terminal),\n\
243 `x' for an Emacs frame that is really an X window,\n\
244 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
245 `mac' for an Emacs frame on a Macintosh display,\n\
246 `pc' for a direct-write MS-DOS frame.\n\
247 See also `frame-live-p'.")
248 (object)
249 Lisp_Object object;
251 if (!FRAMEP (object))
252 return Qnil;
253 switch (XFRAME (object)->output_method)
255 case output_termcap:
256 return Qt;
257 case output_x_window:
258 return Qx;
259 case output_w32:
260 return Qw32;
261 case output_msdos_raw:
262 return Qpc;
263 case output_mac:
264 return Qmac;
265 default:
266 abort ();
270 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
271 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
272 Value is nil if OBJECT is not a live frame. If object is a live\n\
273 frame, the return value indicates what sort of output device it is\n\
274 displayed on. Value is t for a termcap frame (a character-only\n\
275 terminal), `x' for an Emacs frame being displayed in an X window.")
276 (object)
277 Lisp_Object object;
279 return ((FRAMEP (object)
280 && FRAME_LIVE_P (XFRAME (object)))
281 ? Fframep (object)
282 : Qnil);
285 struct frame *
286 make_frame (mini_p)
287 int mini_p;
289 Lisp_Object frame;
290 register struct frame *f;
291 register Lisp_Object root_window;
292 register Lisp_Object mini_window;
293 register struct Lisp_Vector *vec;
294 int i;
296 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
297 for (i = 0; i < VECSIZE (struct frame); i++)
298 XSETFASTINT (vec->contents[i], 0);
299 vec->size = VECSIZE (struct frame);
300 f = (struct frame *)vec;
301 XSETFRAME (frame, f);
303 f->desired_matrix = 0;
304 f->current_matrix = 0;
305 f->desired_pool = 0;
306 f->current_pool = 0;
307 f->glyphs_initialized_p = 0;
308 f->decode_mode_spec_buffer = 0;
309 f->visible = 0;
310 f->async_visible = 0;
311 f->output_data.nothing = 0;
312 f->iconified = 0;
313 f->async_iconified = 0;
314 f->wants_modeline = 1;
315 f->auto_raise = 0;
316 f->auto_lower = 0;
317 f->no_split = 0;
318 f->garbaged = 1;
319 f->has_minibuffer = mini_p;
320 f->focus_frame = Qnil;
321 f->explicit_name = 0;
322 f->can_have_scroll_bars = 0;
323 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
324 f->param_alist = Qnil;
325 f->scroll_bars = Qnil;
326 f->condemned_scroll_bars = Qnil;
327 f->face_alist = Qnil;
328 f->face_cache = NULL;
329 f->menu_bar_items = Qnil;
330 f->menu_bar_vector = Qnil;
331 f->menu_bar_items_used = 0;
332 f->buffer_predicate = Qnil;
333 f->buffer_list = Qnil;
334 #ifdef MULTI_KBOARD
335 f->kboard = initial_kboard;
336 #endif
337 f->namebuf = 0;
338 f->title = Qnil;
339 f->menu_bar_window = Qnil;
340 f->tool_bar_window = Qnil;
341 f->desired_tool_bar_items = f->current_tool_bar_items = Qnil;
342 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
343 f->n_desired_tool_bar_items = f->n_current_tool_bar_items = 0;
345 root_window = make_window ();
346 if (mini_p)
348 mini_window = make_window ();
349 XWINDOW (root_window)->next = mini_window;
350 XWINDOW (mini_window)->prev = root_window;
351 XWINDOW (mini_window)->mini_p = Qt;
352 XWINDOW (mini_window)->frame = frame;
353 f->minibuffer_window = mini_window;
355 else
357 mini_window = Qnil;
358 XWINDOW (root_window)->next = Qnil;
359 f->minibuffer_window = Qnil;
362 XWINDOW (root_window)->frame = frame;
364 /* 10 is arbitrary,
365 just so that there is "something there."
366 Correct size will be set up later with change_frame_size. */
368 SET_FRAME_WIDTH (f, 10);
369 f->height = 10;
371 XSETFASTINT (XWINDOW (root_window)->width, 10);
372 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
374 if (mini_p)
376 XSETFASTINT (XWINDOW (mini_window)->width, 10);
377 XSETFASTINT (XWINDOW (mini_window)->top, 9);
378 XSETFASTINT (XWINDOW (mini_window)->height, 1);
381 /* Choose a buffer for the frame's root window. */
383 Lisp_Object buf;
385 XWINDOW (root_window)->buffer = Qt;
386 buf = Fcurrent_buffer ();
387 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
388 a space), try to find another one. */
389 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
390 buf = Fother_buffer (buf, Qnil, Qnil);
392 /* Use set_window_buffer, not Fset_window_buffer, and don't let
393 hooks be run by it. The reason is that the whole frame/window
394 arrangement is not yet fully intialized at this point. Windows
395 don't have the right size, glyph matrices aren't initialized
396 etc. Running Lisp functions at this point surely ends in a
397 SEGV. */
398 set_window_buffer (root_window, buf, 0);
399 f->buffer_list = Fcons (buf, Qnil);
402 if (mini_p)
404 XWINDOW (mini_window)->buffer = Qt;
405 set_window_buffer (mini_window,
406 (NILP (Vminibuffer_list)
407 ? get_minibuffer (0)
408 : Fcar (Vminibuffer_list)),
412 f->root_window = root_window;
413 f->selected_window = root_window;
414 /* Make sure this window seems more recently used than
415 a newly-created, never-selected window. */
416 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
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 (INTEGERP (minibuf) && XINT (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 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
946 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
947 FRAME_FOCUS_FRAME (XFRAME (f))))
948 return f;
950 else
951 return f;
954 if (EQ (frame, f))
955 passed++;
959 /* Return the previous frame in the frame list before FRAME.
960 If MINIBUF is nil, exclude minibuffer-only frames.
961 If MINIBUF is a window, include only its own frame
962 and any frame now using that window as the minibuffer.
963 If MINIBUF is `visible', include all visible frames.
964 If MINIBUF is 0, include all visible and iconified frames.
965 Otherwise, include all frames. */
967 Lisp_Object
968 prev_frame (frame, minibuf)
969 Lisp_Object frame;
970 Lisp_Object minibuf;
972 Lisp_Object tail;
973 Lisp_Object prev;
975 /* There must always be at least one frame in Vframe_list. */
976 if (! CONSP (Vframe_list))
977 abort ();
979 prev = Qnil;
980 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
982 Lisp_Object f;
984 f = XCAR (tail);
985 if (!FRAMEP (f))
986 abort ();
988 if (EQ (frame, f) && !NILP (prev))
989 return prev;
991 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
993 /* Decide whether this frame is eligible to be returned,
994 according to minibuf. */
995 if (NILP (minibuf))
997 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
998 prev = f;
1000 else if (WINDOWP (minibuf))
1002 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1003 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1004 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1005 FRAME_FOCUS_FRAME (XFRAME (f))))
1006 prev = f;
1008 else if (EQ (minibuf, Qvisible))
1010 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1011 if (FRAME_VISIBLE_P (XFRAME (f)))
1012 prev = f;
1014 else if (XFASTINT (minibuf) == 0)
1016 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1017 if (FRAME_VISIBLE_P (XFRAME (f))
1018 || FRAME_ICONIFIED_P (XFRAME (f)))
1019 prev = f;
1021 else
1022 prev = f;
1026 /* We've scanned the entire list. */
1027 if (NILP (prev))
1028 /* We went through the whole frame list without finding a single
1029 acceptable frame. Return the original frame. */
1030 return frame;
1031 else
1032 /* There were no acceptable frames in the list before FRAME; otherwise,
1033 we would have returned directly from the loop. Since PREV is the last
1034 acceptable frame in the list, return it. */
1035 return prev;
1039 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1040 "Return the next frame in the frame list after FRAME.\n\
1041 It considers only frames on the same terminal as FRAME.\n\
1042 By default, skip minibuffer-only frames.\n\
1043 If omitted, FRAME defaults to the selected frame.\n\
1044 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1045 If MINIFRAME is a window, include only its own frame\n\
1046 and any frame now using that window as the minibuffer.\n\
1047 If MINIFRAME is `visible', include all visible frames.\n\
1048 If MINIFRAME is 0, include all visible and iconified frames.\n\
1049 Otherwise, include all frames.")
1050 (frame, miniframe)
1051 Lisp_Object frame, miniframe;
1053 if (NILP (frame))
1054 frame = selected_frame;
1056 CHECK_LIVE_FRAME (frame, 0);
1057 return next_frame (frame, miniframe);
1060 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1061 "Return the previous frame in the frame list before FRAME.\n\
1062 It considers only frames on the same terminal as FRAME.\n\
1063 By default, skip minibuffer-only frames.\n\
1064 If omitted, FRAME defaults to the selected frame.\n\
1065 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1066 If MINIFRAME is a window, include only its own frame\n\
1067 and any frame now using that window as the minibuffer.\n\
1068 If MINIFRAME is `visible', include all visible frames.\n\
1069 If MINIFRAME is 0, include all visible and iconified frames.\n\
1070 Otherwise, include all frames.")
1071 (frame, miniframe)
1072 Lisp_Object frame, miniframe;
1074 if (NILP (frame))
1075 frame = selected_frame;
1076 CHECK_LIVE_FRAME (frame, 0);
1077 return prev_frame (frame, miniframe);
1080 /* Return 1 if it is ok to delete frame F;
1081 0 if all frames aside from F are invisible.
1082 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1085 other_visible_frames (f)
1086 FRAME_PTR f;
1088 /* We know the selected frame is visible,
1089 so if F is some other frame, it can't be the sole visible one. */
1090 if (f == SELECTED_FRAME ())
1092 Lisp_Object frames;
1093 int count = 0;
1095 for (frames = Vframe_list;
1096 CONSP (frames);
1097 frames = XCDR (frames))
1099 Lisp_Object this;
1101 this = XCAR (frames);
1102 /* Verify that the frame's window still exists
1103 and we can still talk to it. And note any recent change
1104 in visibility. */
1105 #ifdef HAVE_WINDOW_SYSTEM
1106 if (FRAME_WINDOW_P (XFRAME (this)))
1108 x_sync (XFRAME (this));
1109 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1111 #endif
1113 if (FRAME_VISIBLE_P (XFRAME (this))
1114 || FRAME_ICONIFIED_P (XFRAME (this))
1115 /* Allow deleting the terminal frame when at least
1116 one X frame exists! */
1117 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1118 count++;
1120 return count > 1;
1122 return 1;
1125 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1126 "Delete FRAME, permanently eliminating it from use.\n\
1127 If omitted, FRAME defaults to the selected frame.\n\
1128 A frame may not be deleted if its minibuffer is used by other frames.\n\
1129 Normally, you may not delete a frame if all other frames are invisible,\n\
1130 but if the second optional argument FORCE is non-nil, you may do so.")
1131 (frame, force)
1132 Lisp_Object frame, force;
1134 struct frame *f;
1135 struct frame *sf = SELECTED_FRAME ();
1136 int minibuffer_selected;
1138 if (EQ (frame, Qnil))
1140 f = sf;
1141 XSETFRAME (frame, f);
1143 else
1145 CHECK_FRAME (frame, 0);
1146 f = XFRAME (frame);
1149 if (! FRAME_LIVE_P (f))
1150 return Qnil;
1152 if (NILP (force) && !other_visible_frames (f))
1153 error ("Attempt to delete the sole visible or iconified frame");
1155 #if 0
1156 /* This is a nice idea, but x_connection_closed needs to be able
1157 to delete the last frame, if it is gone. */
1158 if (NILP (XCDR (Vframe_list)))
1159 error ("Attempt to delete the only frame");
1160 #endif
1162 /* Does this frame have a minibuffer, and is it the surrogate
1163 minibuffer for any other frame? */
1164 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1166 Lisp_Object frames;
1168 for (frames = Vframe_list;
1169 CONSP (frames);
1170 frames = XCDR (frames))
1172 Lisp_Object this;
1173 this = XCAR (frames);
1175 if (! EQ (this, frame)
1176 && EQ (frame,
1177 WINDOW_FRAME (XWINDOW
1178 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1179 error ("Attempt to delete a surrogate minibuffer frame");
1183 minibuffer_selected = EQ (minibuf_window, selected_window);
1185 /* Don't let the frame remain selected. */
1186 if (f == sf)
1188 Lisp_Object tail, frame1;
1190 /* Look for another visible frame on the same terminal. */
1191 frame1 = next_frame (frame, Qvisible);
1193 /* If there is none, find *some* other frame. */
1194 if (NILP (frame1) || EQ (frame1, frame))
1196 FOR_EACH_FRAME (tail, frame1)
1198 if (! EQ (frame, frame1))
1199 break;
1203 do_switch_frame (frame1, Qnil, 0);
1204 sf = SELECTED_FRAME ();
1207 /* Don't allow minibuf_window to remain on a deleted frame. */
1208 if (EQ (f->minibuffer_window, minibuf_window))
1210 Fset_window_buffer (sf->minibuffer_window,
1211 XWINDOW (minibuf_window)->buffer);
1212 minibuf_window = sf->minibuffer_window;
1214 /* If the dying minibuffer window was selected,
1215 select the new one. */
1216 if (minibuffer_selected)
1217 Fselect_window (minibuf_window);
1220 /* Don't let echo_area_window to remain on a deleted frame. */
1221 if (EQ (f->minibuffer_window, echo_area_window))
1222 echo_area_window = sf->minibuffer_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 /* Since some events are handled at the interrupt level, we may get
1258 an event for f at any time; if we zero out the frame's display
1259 now, then we may trip up the event-handling code. Instead, we'll
1260 promise that the display of the frame must be valid until we have
1261 called the window-system-dependent frame destruction routine. */
1263 /* I think this should be done with a hook. */
1264 #ifdef HAVE_WINDOW_SYSTEM
1265 if (FRAME_WINDOW_P (f))
1266 x_destroy_window (f);
1267 #endif
1269 /* Done by x_destroy_window above already */
1270 #if 0
1271 #ifdef macintosh
1272 if (FRAME_MAC_P (f))
1273 DisposeMacWindow (f->output_data.mac);
1274 #endif
1275 #endif
1277 f->output_data.nothing = 0;
1279 /* If we've deleted the last_nonminibuf_frame, then try to find
1280 another one. */
1281 if (f == last_nonminibuf_frame)
1283 Lisp_Object frames;
1285 last_nonminibuf_frame = 0;
1287 for (frames = Vframe_list;
1288 CONSP (frames);
1289 frames = XCDR (frames))
1291 f = XFRAME (XCAR (frames));
1292 if (!FRAME_MINIBUF_ONLY_P (f))
1294 last_nonminibuf_frame = f;
1295 break;
1300 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1301 find another one. Prefer minibuffer-only frames, but also notice
1302 frames with other windows. */
1303 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1305 Lisp_Object frames;
1307 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1308 Lisp_Object frame_with_minibuf;
1309 /* Some frame we found on the same kboard, or nil if there are none. */
1310 Lisp_Object frame_on_same_kboard;
1312 frame_on_same_kboard = Qnil;
1313 frame_with_minibuf = Qnil;
1315 for (frames = Vframe_list;
1316 CONSP (frames);
1317 frames = XCDR (frames))
1319 Lisp_Object this;
1320 struct frame *f1;
1322 this = XCAR (frames);
1323 if (!FRAMEP (this))
1324 abort ();
1325 f1 = XFRAME (this);
1327 /* Consider only frames on the same kboard
1328 and only those with minibuffers. */
1329 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1330 && FRAME_HAS_MINIBUF_P (f1))
1332 frame_with_minibuf = this;
1333 if (FRAME_MINIBUF_ONLY_P (f1))
1334 break;
1337 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1338 frame_on_same_kboard = this;
1341 if (!NILP (frame_on_same_kboard))
1343 /* We know that there must be some frame with a minibuffer out
1344 there. If this were not true, all of the frames present
1345 would have to be minibufferless, which implies that at some
1346 point their minibuffer frames must have been deleted, but
1347 that is prohibited at the top; you can't delete surrogate
1348 minibuffer frames. */
1349 if (NILP (frame_with_minibuf))
1350 abort ();
1352 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1354 else
1355 /* No frames left on this kboard--say no minibuffer either. */
1356 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1359 /* Cause frame titles to update--necessary if we now have just one frame. */
1360 update_mode_lines = 1;
1362 return Qnil;
1365 /* Return mouse position in character cell units. */
1367 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1368 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1369 The position is given in character cells, where (0, 0) is the\n\
1370 upper-left corner.\n\
1371 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1372 to read the mouse position, it returns the selected frame for FRAME\n\
1373 and nil for X and Y.\n\
1374 Runs the abnormal hook `mouse-position-function' with the normal return\n\
1375 value as argument.")
1378 FRAME_PTR f;
1379 Lisp_Object lispy_dummy;
1380 enum scroll_bar_part party_dummy;
1381 Lisp_Object x, y, retval;
1382 int col, row;
1383 unsigned long long_dummy;
1384 struct gcpro gcpro1;
1386 f = SELECTED_FRAME ();
1387 x = y = Qnil;
1389 #ifdef HAVE_MOUSE
1390 /* It's okay for the hook to refrain from storing anything. */
1391 if (mouse_position_hook)
1392 (*mouse_position_hook) (&f, -1,
1393 &lispy_dummy, &party_dummy,
1394 &x, &y,
1395 &long_dummy);
1396 if (! NILP (x))
1398 col = XINT (x);
1399 row = XINT (y);
1400 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1401 XSETINT (x, col);
1402 XSETINT (y, row);
1404 #endif
1405 XSETFRAME (lispy_dummy, f);
1406 retval = Fcons (lispy_dummy, Fcons (x, y));
1407 GCPRO1 (retval);
1408 if (!NILP (Vmouse_position_function))
1409 retval = call1 (Vmouse_position_function, retval);
1410 RETURN_UNGCPRO (retval);
1413 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1414 Smouse_pixel_position, 0, 0, 0,
1415 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1416 The position is given in pixel units, where (0, 0) is the\n\
1417 upper-left corner.\n\
1418 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1419 to read the mouse position, it returns the selected frame for FRAME\n\
1420 and nil for X and Y.")
1423 FRAME_PTR f;
1424 Lisp_Object lispy_dummy;
1425 enum scroll_bar_part party_dummy;
1426 Lisp_Object x, y;
1427 unsigned long long_dummy;
1429 f = SELECTED_FRAME ();
1430 x = y = Qnil;
1432 #ifdef HAVE_MOUSE
1433 /* It's okay for the hook to refrain from storing anything. */
1434 if (mouse_position_hook)
1435 (*mouse_position_hook) (&f, -1,
1436 &lispy_dummy, &party_dummy,
1437 &x, &y,
1438 &long_dummy);
1439 #endif
1440 XSETFRAME (lispy_dummy, f);
1441 return Fcons (lispy_dummy, Fcons (x, y));
1444 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1445 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1446 Coordinates are relative to the frame, not a window,\n\
1447 so the coordinates of the top left character in the frame\n\
1448 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1450 This function is a no-op for an X frame that is not visible.\n\
1451 If you have just created a frame, you must wait for it to become visible\n\
1452 before calling this function on it, like this.\n\
1453 (while (not (frame-visible-p frame)) (sleep-for .5))")
1454 (frame, x, y)
1455 Lisp_Object frame, x, y;
1457 CHECK_LIVE_FRAME (frame, 0);
1458 CHECK_NUMBER (x, 2);
1459 CHECK_NUMBER (y, 1);
1461 /* I think this should be done with a hook. */
1462 #ifdef HAVE_WINDOW_SYSTEM
1463 if (FRAME_WINDOW_P (XFRAME (frame)))
1464 /* Warping the mouse will cause enternotify and focus events. */
1465 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1466 #else
1467 #if defined (MSDOS) && defined (HAVE_MOUSE)
1468 if (FRAME_MSDOS_P (XFRAME (frame)))
1470 Fselect_frame (frame, Qnil);
1471 mouse_moveto (XINT (x), XINT (y));
1473 #endif
1474 #endif
1476 return Qnil;
1479 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1480 Sset_mouse_pixel_position, 3, 3, 0,
1481 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1482 Note, this is a no-op for an X frame that is not visible.\n\
1483 If you have just created a frame, you must wait for it to become visible\n\
1484 before calling this function on it, like this.\n\
1485 (while (not (frame-visible-p frame)) (sleep-for .5))")
1486 (frame, x, y)
1487 Lisp_Object frame, x, y;
1489 CHECK_LIVE_FRAME (frame, 0);
1490 CHECK_NUMBER (x, 2);
1491 CHECK_NUMBER (y, 1);
1493 /* I think this should be done with a hook. */
1494 #ifdef HAVE_WINDOW_SYSTEM
1495 if (FRAME_WINDOW_P (XFRAME (frame)))
1496 /* Warping the mouse will cause enternotify and focus events. */
1497 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1498 #else
1499 #if defined (MSDOS) && defined (HAVE_MOUSE)
1500 if (FRAME_MSDOS_P (XFRAME (frame)))
1502 Fselect_frame (frame, Qnil);
1503 mouse_moveto (XINT (x), XINT (y));
1505 #endif
1506 #endif
1508 return Qnil;
1511 static void make_frame_visible_1 P_ ((Lisp_Object));
1513 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1514 0, 1, "",
1515 "Make the frame FRAME visible (assuming it is an X-window).\n\
1516 If omitted, FRAME defaults to the currently selected frame.")
1517 (frame)
1518 Lisp_Object frame;
1520 if (NILP (frame))
1521 frame = selected_frame;
1523 CHECK_LIVE_FRAME (frame, 0);
1525 /* I think this should be done with a hook. */
1526 #ifdef HAVE_WINDOW_SYSTEM
1527 if (FRAME_WINDOW_P (XFRAME (frame)))
1529 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1530 x_make_frame_visible (XFRAME (frame));
1532 #endif
1534 make_frame_visible_1 (XFRAME (frame)->root_window);
1536 /* Make menu bar update for the Buffers and Frams menus. */
1537 windows_or_buffers_changed++;
1539 return frame;
1542 /* Update the display_time slot of the buffers shown in WINDOW
1543 and all its descendents. */
1545 static void
1546 make_frame_visible_1 (window)
1547 Lisp_Object window;
1549 struct window *w;
1551 for (;!NILP (window); window = w->next)
1553 w = XWINDOW (window);
1555 if (!NILP (w->buffer))
1556 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1558 if (!NILP (w->vchild))
1559 make_frame_visible_1 (w->vchild);
1560 if (!NILP (w->hchild))
1561 make_frame_visible_1 (w->hchild);
1565 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1566 0, 2, "",
1567 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1568 If omitted, FRAME defaults to the currently selected frame.\n\
1569 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1570 but if the second optional argument FORCE is non-nil, you may do so.")
1571 (frame, force)
1572 Lisp_Object frame, force;
1574 if (NILP (frame))
1575 frame = selected_frame;
1577 CHECK_LIVE_FRAME (frame, 0);
1579 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1580 error ("Attempt to make invisible the sole visible or iconified frame");
1582 #if 0 /* This isn't logically necessary, and it can do GC. */
1583 /* Don't let the frame remain selected. */
1584 if (EQ (frame, selected_frame))
1585 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1586 #endif
1588 /* Don't allow minibuf_window to remain on a deleted frame. */
1589 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1591 struct frame *sf = XFRAME (selected_frame);
1592 Fset_window_buffer (sf->minibuffer_window,
1593 XWINDOW (minibuf_window)->buffer);
1594 minibuf_window = sf->minibuffer_window;
1597 /* I think this should be done with a hook. */
1598 #ifdef HAVE_WINDOW_SYSTEM
1599 if (FRAME_WINDOW_P (XFRAME (frame)))
1600 x_make_frame_invisible (XFRAME (frame));
1601 #endif
1603 /* Make menu bar update for the Buffers and Frams menus. */
1604 windows_or_buffers_changed++;
1606 return Qnil;
1609 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1610 0, 1, "",
1611 "Make the frame FRAME into an icon.\n\
1612 If omitted, FRAME defaults to the currently selected frame.")
1613 (frame)
1614 Lisp_Object frame;
1616 if (NILP (frame))
1617 frame = selected_frame;
1619 CHECK_LIVE_FRAME (frame, 0);
1621 #if 0 /* This isn't logically necessary, and it can do GC. */
1622 /* Don't let the frame remain selected. */
1623 if (EQ (frame, selected_frame))
1624 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1625 #endif
1627 /* Don't allow minibuf_window to remain on a deleted frame. */
1628 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1630 struct frame *sf = XFRAME (selected_frame);
1631 Fset_window_buffer (sf->minibuffer_window,
1632 XWINDOW (minibuf_window)->buffer);
1633 minibuf_window = sf->minibuffer_window;
1636 /* I think this should be done with a hook. */
1637 #ifdef HAVE_WINDOW_SYSTEM
1638 if (FRAME_WINDOW_P (XFRAME (frame)))
1639 x_iconify_frame (XFRAME (frame));
1640 #endif
1642 /* Make menu bar update for the Buffers and Frams menus. */
1643 windows_or_buffers_changed++;
1645 return Qnil;
1648 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1649 1, 1, 0,
1650 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1651 A frame that is not \"visible\" is not updated and, if it works through\n\
1652 a window system, it may not show at all.\n\
1653 Return the symbol `icon' if frame is visible only as an icon.")
1654 (frame)
1655 Lisp_Object frame;
1657 CHECK_LIVE_FRAME (frame, 0);
1659 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1661 if (FRAME_VISIBLE_P (XFRAME (frame)))
1662 return Qt;
1663 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1664 return Qicon;
1665 return Qnil;
1668 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1669 0, 0, 0,
1670 "Return a list of all frames now \"visible\" (being updated).")
1673 Lisp_Object tail, frame;
1674 struct frame *f;
1675 Lisp_Object value;
1677 value = Qnil;
1678 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1680 frame = XCAR (tail);
1681 if (!FRAMEP (frame))
1682 continue;
1683 f = XFRAME (frame);
1684 if (FRAME_VISIBLE_P (f))
1685 value = Fcons (frame, value);
1687 return value;
1691 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1692 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1693 If FRAME is invisible, make it visible.\n\
1694 If you don't specify a frame, the selected frame is used.\n\
1695 If Emacs is displaying on an ordinary terminal or some other device which\n\
1696 doesn't support multiple overlapping frames, this function does nothing.")
1697 (frame)
1698 Lisp_Object frame;
1700 if (NILP (frame))
1701 frame = selected_frame;
1703 CHECK_LIVE_FRAME (frame, 0);
1705 /* Do like the documentation says. */
1706 Fmake_frame_visible (frame);
1708 if (frame_raise_lower_hook)
1709 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1711 return Qnil;
1714 /* Should we have a corresponding function called Flower_Power? */
1715 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1716 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1717 If you don't specify a frame, the selected frame is used.\n\
1718 If Emacs is displaying on an ordinary terminal or some other device which\n\
1719 doesn't support multiple overlapping frames, this function does nothing.")
1720 (frame)
1721 Lisp_Object frame;
1723 if (NILP (frame))
1724 frame = selected_frame;
1726 CHECK_LIVE_FRAME (frame, 0);
1728 if (frame_raise_lower_hook)
1729 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1731 return Qnil;
1735 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1736 1, 2, 0,
1737 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1738 In other words, switch-frame events caused by events in FRAME will\n\
1739 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1740 FOCUS-FRAME after reading an event typed at FRAME.\n\
1742 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1743 cancelled, and the frame again receives its own keystrokes.\n\
1745 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1746 a surrogate minibuffer frame when a frame doesn't have its own\n\
1747 minibuffer window.\n\
1749 A frame's focus redirection can be changed by select-frame. If frame\n\
1750 FOO is selected, and then a different frame BAR is selected, any\n\
1751 frames redirecting their focus to FOO are shifted to redirect their\n\
1752 focus to BAR. This allows focus redirection to work properly when the\n\
1753 user switches from one frame to another using `select-window'.\n\
1755 This means that a frame whose focus is redirected to itself is treated\n\
1756 differently from a frame whose focus is redirected to nil; the former\n\
1757 is affected by select-frame, while the latter is not.\n\
1759 The redirection lasts until `redirect-frame-focus' is called to change it.")
1760 (frame, focus_frame)
1761 Lisp_Object frame, focus_frame;
1763 /* Note that we don't check for a live frame here. It's reasonable
1764 to redirect the focus of a frame you're about to delete, if you
1765 know what other frame should receive those keystrokes. */
1766 CHECK_FRAME (frame, 0);
1768 if (! NILP (focus_frame))
1769 CHECK_LIVE_FRAME (focus_frame, 1);
1771 XFRAME (frame)->focus_frame = focus_frame;
1773 if (frame_rehighlight_hook)
1774 (*frame_rehighlight_hook) (XFRAME (frame));
1776 return Qnil;
1780 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1781 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1782 This returns nil if FRAME's focus is not redirected.\n\
1783 See `redirect-frame-focus'.")
1784 (frame)
1785 Lisp_Object frame;
1787 CHECK_LIVE_FRAME (frame, 0);
1789 return FRAME_FOCUS_FRAME (XFRAME (frame));
1794 /* Return the value of frame parameter PROP in frame FRAME. */
1796 Lisp_Object
1797 get_frame_param (frame, prop)
1798 register struct frame *frame;
1799 Lisp_Object prop;
1801 register Lisp_Object tem;
1803 tem = Fassq (prop, frame->param_alist);
1804 if (EQ (tem, Qnil))
1805 return tem;
1806 return Fcdr (tem);
1809 /* Return the buffer-predicate of the selected frame. */
1811 Lisp_Object
1812 frame_buffer_predicate (frame)
1813 Lisp_Object frame;
1815 return XFRAME (frame)->buffer_predicate;
1818 /* Return the buffer-list of the selected frame. */
1820 Lisp_Object
1821 frame_buffer_list (frame)
1822 Lisp_Object frame;
1824 return XFRAME (frame)->buffer_list;
1827 /* Set the buffer-list of the selected frame. */
1829 void
1830 set_frame_buffer_list (frame, list)
1831 Lisp_Object frame, list;
1833 XFRAME (frame)->buffer_list = list;
1836 /* Discard BUFFER from the buffer-list of each frame. */
1838 void
1839 frames_discard_buffer (buffer)
1840 Lisp_Object buffer;
1842 Lisp_Object frame, tail;
1844 FOR_EACH_FRAME (tail, frame)
1846 XFRAME (frame)->buffer_list
1847 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1851 /* Move BUFFER to the end of the buffer-list of each frame. */
1853 void
1854 frames_bury_buffer (buffer)
1855 Lisp_Object buffer;
1857 Lisp_Object frame, tail;
1859 FOR_EACH_FRAME (tail, frame)
1861 struct frame *f = XFRAME (frame);
1862 Lisp_Object found;
1864 found = Fmemq (buffer, f->buffer_list);
1865 if (!NILP (found))
1866 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1867 Fcons (buffer, Qnil));
1871 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1872 If the alist already has an element for PROP, we change it. */
1874 void
1875 store_in_alist (alistptr, prop, val)
1876 Lisp_Object *alistptr, val;
1877 Lisp_Object prop;
1879 register Lisp_Object tem;
1881 tem = Fassq (prop, *alistptr);
1882 if (EQ (tem, Qnil))
1883 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1884 else
1885 Fsetcdr (tem, val);
1888 static int
1889 frame_name_fnn_p (str, len)
1890 char *str;
1891 int len;
1893 if (len > 1 && str[0] == 'F')
1895 char *end_ptr;
1897 strtol (str + 1, &end_ptr, 10);
1899 if (end_ptr == str + len)
1900 return 1;
1902 return 0;
1905 /* Set the name of the terminal frame. Also used by MSDOS frames.
1906 Modeled after x_set_name which is used for WINDOW frames. */
1908 void
1909 set_term_frame_name (f, name)
1910 struct frame *f;
1911 Lisp_Object name;
1913 f->explicit_name = ! NILP (name);
1915 /* If NAME is nil, set the name to F<num>. */
1916 if (NILP (name))
1918 char namebuf[20];
1920 /* Check for no change needed in this very common case
1921 before we do any consing. */
1922 if (frame_name_fnn_p (XSTRING (f->name)->data,
1923 STRING_BYTES (XSTRING (f->name))))
1924 return;
1926 terminal_frame_count++;
1927 sprintf (namebuf, "F%d", terminal_frame_count);
1928 name = build_string (namebuf);
1930 else
1932 CHECK_STRING (name, 0);
1934 /* Don't change the name if it's already NAME. */
1935 if (! NILP (Fstring_equal (name, f->name)))
1936 return;
1938 /* Don't allow the user to set the frame name to F<num>, so it
1939 doesn't clash with the names we generate for terminal frames. */
1940 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1941 error ("Frame names of the form F<num> are usurped by Emacs");
1944 f->name = name;
1945 update_mode_lines = 1;
1948 void
1949 store_frame_param (f, prop, val)
1950 struct frame *f;
1951 Lisp_Object prop, val;
1953 register Lisp_Object old_alist_elt;
1955 /* The buffer-alist parameter is stored in a special place and is
1956 not in the alist. */
1957 if (EQ (prop, Qbuffer_list))
1959 f->buffer_list = val;
1960 return;
1963 /* If PROP is a symbol which is supposed to have frame-local values,
1964 and it is set up based on this frame, switch to the global
1965 binding. That way, we can create or alter the frame-local binding
1966 without messing up the symbol's status. */
1967 if (SYMBOLP (prop))
1969 Lisp_Object valcontents;
1970 valcontents = XSYMBOL (prop)->value;
1971 if ((BUFFER_LOCAL_VALUEP (valcontents)
1972 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1973 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1974 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1975 swap_in_global_binding (prop);
1978 /* Update the frame parameter alist. */
1979 old_alist_elt = Fassq (prop, f->param_alist);
1980 if (EQ (old_alist_elt, Qnil))
1981 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1982 else
1983 Fsetcdr (old_alist_elt, val);
1985 /* Update some other special parameters in their special places
1986 in addition to the alist. */
1988 if (EQ (prop, Qbuffer_predicate))
1989 f->buffer_predicate = val;
1991 if (! FRAME_WINDOW_P (f))
1993 if (EQ (prop, Qmenu_bar_lines))
1994 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1995 else if (EQ (prop, Qname))
1996 set_term_frame_name (f, val);
1999 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2001 if (! MINI_WINDOW_P (XWINDOW (val)))
2002 error ("Surrogate minibuffer windows must be minibuffer windows.");
2004 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2005 && !EQ (val, f->minibuffer_window))
2006 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2008 /* Install the chosen minibuffer window, with proper buffer. */
2009 f->minibuffer_window = val;
2013 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2014 "Return the parameters-alist of frame FRAME.\n\
2015 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
2016 The meaningful PARMs depend on the kind of frame.\n\
2017 If FRAME is omitted, return information on the currently selected frame.")
2018 (frame)
2019 Lisp_Object frame;
2021 Lisp_Object alist;
2022 FRAME_PTR f;
2023 int height, width;
2024 struct gcpro gcpro1;
2026 if (EQ (frame, Qnil))
2027 frame = selected_frame;
2029 CHECK_FRAME (frame, 0);
2030 f = XFRAME (frame);
2032 if (!FRAME_LIVE_P (f))
2033 return Qnil;
2035 alist = Fcopy_alist (f->param_alist);
2036 GCPRO1 (alist);
2038 if (!FRAME_WINDOW_P (f))
2040 int fg = FRAME_FOREGROUND_PIXEL (f);
2041 int bg = FRAME_BACKGROUND_PIXEL (f);
2043 store_in_alist (&alist, intern ("foreground-color"),
2044 tty_color_name (f, fg));
2045 store_in_alist (&alist, intern ("background-color"),
2046 tty_color_name (f, bg));
2047 store_in_alist (&alist, intern ("font"),
2048 build_string (FRAME_MSDOS_P (f)
2049 ? "ms-dos"
2050 : FRAME_W32_P (f) ? "w32term" : "tty"));
2052 store_in_alist (&alist, Qname, f->name);
2053 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2054 store_in_alist (&alist, Qheight, make_number (height));
2055 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2056 store_in_alist (&alist, Qwidth, make_number (width));
2057 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2058 store_in_alist (&alist, Qminibuffer,
2059 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2060 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2061 : FRAME_MINIBUF_WINDOW (f)));
2062 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2063 store_in_alist (&alist, Qbuffer_list,
2064 frame_buffer_list (selected_frame));
2066 /* I think this should be done with a hook. */
2067 #ifdef HAVE_WINDOW_SYSTEM
2068 if (FRAME_WINDOW_P (f))
2069 x_report_frame_params (f, &alist);
2070 else
2071 #endif
2073 /* This ought to be correct in f->param_alist for an X frame. */
2074 Lisp_Object lines;
2075 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2076 store_in_alist (&alist, Qmenu_bar_lines, lines);
2079 UNGCPRO;
2080 return alist;
2083 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2084 Smodify_frame_parameters, 2, 2, 0,
2085 "Modify the parameters of frame FRAME according to ALIST.\n\
2086 ALIST is an alist of parameters to change and their new values.\n\
2087 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2088 The meaningful PARMs depend on the kind of frame.\n\
2089 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2090 so that `frame-parameters' will return them.\n\
2092 The value of frame parameter FOO can also be accessed\n\
2093 as a frame-local binding for the variable FOO, if you have\n\
2094 enabled such bindings for that variable with `make-variable-frame-local'.")
2095 (frame, alist)
2096 Lisp_Object frame, alist;
2098 FRAME_PTR f;
2099 register Lisp_Object tail, prop, val;
2101 if (EQ (frame, Qnil))
2102 frame = selected_frame;
2103 CHECK_LIVE_FRAME (frame, 0);
2104 f = XFRAME (frame);
2106 /* I think this should be done with a hook. */
2107 #ifdef HAVE_WINDOW_SYSTEM
2108 if (FRAME_WINDOW_P (f))
2109 x_set_frame_parameters (f, alist);
2110 else
2111 #endif
2112 #ifdef MSDOS
2113 if (FRAME_MSDOS_P (f))
2114 IT_set_frame_parameters (f, alist);
2115 else
2116 #endif
2117 #ifdef macintosh
2118 if (FRAME_MAC_P (f))
2119 mac_set_frame_parameters (f, alist);
2120 else
2121 #endif
2124 int length = XINT (Flength (alist));
2125 int i;
2126 Lisp_Object *parms
2127 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2128 Lisp_Object *values
2129 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2131 /* Extract parm names and values into those vectors. */
2133 i = 0;
2134 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2136 Lisp_Object elt;
2138 elt = Fcar (tail);
2139 parms[i] = Fcar (elt);
2140 values[i] = Fcdr (elt);
2141 i++;
2144 /* Now process them in reverse of specified order. */
2145 for (i--; i >= 0; i--)
2147 prop = parms[i];
2148 val = values[i];
2149 store_frame_param (f, prop, val);
2153 return Qnil;
2156 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2157 0, 1, 0,
2158 "Height in pixels of a line in the font in frame FRAME.\n\
2159 If FRAME is omitted, the selected frame is used.\n\
2160 For a terminal frame, the value is always 1.")
2161 (frame)
2162 Lisp_Object frame;
2164 struct frame *f;
2166 if (NILP (frame))
2167 frame = selected_frame;
2168 CHECK_FRAME (frame, 0);
2169 f = XFRAME (frame);
2171 #ifdef HAVE_WINDOW_SYSTEM
2172 if (FRAME_WINDOW_P (f))
2173 return make_number (x_char_height (f));
2174 else
2175 #endif
2176 return make_number (1);
2180 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2181 0, 1, 0,
2182 "Width in pixels of characters in the font in frame FRAME.\n\
2183 If FRAME is omitted, the selected frame is used.\n\
2184 The width is the same for all characters, because\n\
2185 currently Emacs supports only fixed-width fonts.\n\
2186 For a terminal screen, the value is always 1.")
2187 (frame)
2188 Lisp_Object frame;
2190 struct frame *f;
2192 if (NILP (frame))
2193 frame = selected_frame;
2194 CHECK_FRAME (frame, 0);
2195 f = XFRAME (frame);
2197 #ifdef HAVE_WINDOW_SYSTEM
2198 if (FRAME_WINDOW_P (f))
2199 return make_number (x_char_width (f));
2200 else
2201 #endif
2202 return make_number (1);
2205 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2206 Sframe_pixel_height, 0, 1, 0,
2207 "Return a FRAME's height in pixels.\n\
2208 This counts only the height available for text lines,\n\
2209 not menu bars on window-system Emacs frames.\n\
2210 For a terminal frame, the result really gives the height in characters.\n\
2211 If FRAME is omitted, the selected frame is used.")
2212 (frame)
2213 Lisp_Object frame;
2215 struct frame *f;
2217 if (NILP (frame))
2218 frame = selected_frame;
2219 CHECK_FRAME (frame, 0);
2220 f = XFRAME (frame);
2222 #ifdef HAVE_WINDOW_SYSTEM
2223 if (FRAME_WINDOW_P (f))
2224 return make_number (x_pixel_height (f));
2225 else
2226 #endif
2227 return make_number (FRAME_HEIGHT (f));
2230 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2231 Sframe_pixel_width, 0, 1, 0,
2232 "Return FRAME's width in pixels.\n\
2233 For a terminal frame, the result really gives the width in characters.\n\
2234 If FRAME is omitted, the selected frame is used.")
2235 (frame)
2236 Lisp_Object frame;
2238 struct frame *f;
2240 if (NILP (frame))
2241 frame = selected_frame;
2242 CHECK_FRAME (frame, 0);
2243 f = XFRAME (frame);
2245 #ifdef HAVE_WINDOW_SYSTEM
2246 if (FRAME_WINDOW_P (f))
2247 return make_number (x_pixel_width (f));
2248 else
2249 #endif
2250 return make_number (FRAME_WIDTH (f));
2253 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2254 "Specify that the frame FRAME has LINES lines.\n\
2255 Optional third arg non-nil means that redisplay should use LINES lines\n\
2256 but that the idea of the actual height of the frame should not be changed.")
2257 (frame, lines, pretend)
2258 Lisp_Object frame, lines, pretend;
2260 register struct frame *f;
2262 CHECK_NUMBER (lines, 0);
2263 if (NILP (frame))
2264 frame = selected_frame;
2265 CHECK_LIVE_FRAME (frame, 0);
2266 f = XFRAME (frame);
2268 /* I think this should be done with a hook. */
2269 #ifdef HAVE_WINDOW_SYSTEM
2270 if (FRAME_WINDOW_P (f))
2272 if (XINT (lines) != f->height)
2273 x_set_window_size (f, 1, f->width, XINT (lines));
2274 do_pending_window_change (0);
2276 else
2277 #endif
2278 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2279 return Qnil;
2282 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2283 "Specify that the frame FRAME has COLS columns.\n\
2284 Optional third arg non-nil means that redisplay should use COLS columns\n\
2285 but that the idea of the actual width of the frame should not be changed.")
2286 (frame, cols, pretend)
2287 Lisp_Object frame, cols, pretend;
2289 register struct frame *f;
2290 CHECK_NUMBER (cols, 0);
2291 if (NILP (frame))
2292 frame = selected_frame;
2293 CHECK_LIVE_FRAME (frame, 0);
2294 f = XFRAME (frame);
2296 /* I think this should be done with a hook. */
2297 #ifdef HAVE_WINDOW_SYSTEM
2298 if (FRAME_WINDOW_P (f))
2300 if (XINT (cols) != f->width)
2301 x_set_window_size (f, 1, XINT (cols), f->height);
2302 do_pending_window_change (0);
2304 else
2305 #endif
2306 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2307 return Qnil;
2310 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2311 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2312 (frame, cols, rows)
2313 Lisp_Object frame, cols, rows;
2315 register struct frame *f;
2317 CHECK_LIVE_FRAME (frame, 0);
2318 CHECK_NUMBER (cols, 2);
2319 CHECK_NUMBER (rows, 1);
2320 f = XFRAME (frame);
2322 /* I think this should be done with a hook. */
2323 #ifdef HAVE_WINDOW_SYSTEM
2324 if (FRAME_WINDOW_P (f))
2326 if (XINT (rows) != f->height || XINT (cols) != f->width
2327 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2328 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2329 do_pending_window_change (0);
2331 else
2332 #endif
2333 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2335 return Qnil;
2338 DEFUN ("set-frame-position", Fset_frame_position,
2339 Sset_frame_position, 3, 3, 0,
2340 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2341 This is actually the position of the upper left corner of the frame.\n\
2342 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2343 the rightmost or bottommost possible position (that stays within the screen).")
2344 (frame, xoffset, yoffset)
2345 Lisp_Object frame, xoffset, yoffset;
2347 register struct frame *f;
2349 CHECK_LIVE_FRAME (frame, 0);
2350 CHECK_NUMBER (xoffset, 1);
2351 CHECK_NUMBER (yoffset, 2);
2352 f = XFRAME (frame);
2354 /* I think this should be done with a hook. */
2355 #ifdef HAVE_WINDOW_SYSTEM
2356 if (FRAME_WINDOW_P (f))
2357 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2358 #endif
2360 return Qt;
2364 void
2365 syms_of_frame ()
2367 syms_of_frame_1 ();
2369 staticpro (&Vframe_list);
2371 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2372 "The initial frame-object, which represents Emacs's stdout.");
2374 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2375 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2376 Vemacs_iconified = Qnil;
2378 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
2379 "If non-nil, function applied to the normal result of `mouse-position'.\n\
2380 This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
2381 which need to do mouse handling at the Lisp level.");
2382 Vmouse_position_function = Qnil;
2384 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2385 "Minibufferless frames use this frame's minibuffer.\n\
2387 Emacs cannot create minibufferless frames unless this is set to an\n\
2388 appropriate surrogate.\n\
2390 Emacs consults this variable only when creating minibufferless\n\
2391 frames; once the frame is created, it sticks with its assigned\n\
2392 minibuffer, no matter what this variable is set to. This means that\n\
2393 this variable doesn't necessarily say anything meaningful about the\n\
2394 current set of frames, or where the minibuffer is currently being\n\
2395 displayed.");
2397 defsubr (&Sactive_minibuffer_window);
2398 defsubr (&Sframep);
2399 defsubr (&Sframe_live_p);
2400 defsubr (&Smake_terminal_frame);
2401 defsubr (&Shandle_switch_frame);
2402 defsubr (&Signore_event);
2403 defsubr (&Sselect_frame);
2404 defsubr (&Sselected_frame);
2405 defsubr (&Swindow_frame);
2406 defsubr (&Sframe_root_window);
2407 defsubr (&Sframe_first_window);
2408 defsubr (&Sframe_selected_window);
2409 defsubr (&Sset_frame_selected_window);
2410 defsubr (&Sframe_list);
2411 defsubr (&Snext_frame);
2412 defsubr (&Sprevious_frame);
2413 defsubr (&Sdelete_frame);
2414 defsubr (&Smouse_position);
2415 defsubr (&Smouse_pixel_position);
2416 defsubr (&Sset_mouse_position);
2417 defsubr (&Sset_mouse_pixel_position);
2418 #if 0
2419 defsubr (&Sframe_configuration);
2420 defsubr (&Srestore_frame_configuration);
2421 #endif
2422 defsubr (&Smake_frame_visible);
2423 defsubr (&Smake_frame_invisible);
2424 defsubr (&Siconify_frame);
2425 defsubr (&Sframe_visible_p);
2426 defsubr (&Svisible_frame_list);
2427 defsubr (&Sraise_frame);
2428 defsubr (&Slower_frame);
2429 defsubr (&Sredirect_frame_focus);
2430 defsubr (&Sframe_focus);
2431 defsubr (&Sframe_parameters);
2432 defsubr (&Smodify_frame_parameters);
2433 defsubr (&Sframe_char_height);
2434 defsubr (&Sframe_char_width);
2435 defsubr (&Sframe_pixel_height);
2436 defsubr (&Sframe_pixel_width);
2437 defsubr (&Sset_frame_height);
2438 defsubr (&Sset_frame_width);
2439 defsubr (&Sset_frame_size);
2440 defsubr (&Sset_frame_position);
2443 void
2444 keys_of_frame ()
2446 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2447 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2448 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2449 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");