(do_switch_frame): Remove unused parameter NO_EVENT, add
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001
3 Free Software Foundation.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include <config.h>
23
24 #include <stdio.h>
25 #include "lisp.h"
26 #include "charset.h"
27 #ifdef HAVE_X_WINDOWS
28 #include "xterm.h"
29 #endif
30 #ifdef WINDOWSNT
31 #include "w32term.h"
32 #endif
33 #ifdef macintosh
34 #include "macterm.h"
35 #endif
36 #include "buffer.h"
37 /* These help us bind and responding to switch-frame events. */
38 #include "commands.h"
39 #include "keyboard.h"
40 #include "frame.h"
41 #ifdef HAVE_WINDOW_SYSTEM
42 #include "fontset.h"
43 #endif
44 #include "termhooks.h"
45 #include "dispextern.h"
46 #include "window.h"
47 #ifdef MSDOS
48 #include "msdos.h"
49 #include "dosfns.h"
50 #endif
51
52 Lisp_Object Qframep;
53 Lisp_Object Qframe_live_p;
54 Lisp_Object Qheight;
55 Lisp_Object Qicon;
56 Lisp_Object Qminibuffer;
57 Lisp_Object Qmodeline;
58 Lisp_Object Qname;
59 Lisp_Object Qonly;
60 Lisp_Object Qunsplittable;
61 Lisp_Object Qmenu_bar_lines;
62 Lisp_Object Qtool_bar_lines;
63 Lisp_Object Qwidth;
64 Lisp_Object Qx;
65 Lisp_Object Qw32;
66 Lisp_Object Qpc;
67 Lisp_Object Qmac;
68 Lisp_Object Qvisible;
69 Lisp_Object Qbuffer_predicate;
70 Lisp_Object Qbuffer_list;
71 Lisp_Object Qtitle;
72 Lisp_Object Qdisplay_type;
73 Lisp_Object Qbackground_mode;
74 Lisp_Object Qinhibit_default_face_x_resources;
75
76 Lisp_Object Vterminal_frame;
77 Lisp_Object Vdefault_frame_alist;
78 Lisp_Object Vmouse_position_function;
79 \f
80 static void
81 set_menu_bar_lines_1 (window, n)
82 Lisp_Object window;
83 int n;
84 {
85 struct window *w = XWINDOW (window);
86
87 XSETFASTINT (w->last_modified, 0);
88 XSETFASTINT (w->top, XFASTINT (w->top) + n);
89 XSETFASTINT (w->height, XFASTINT (w->height) - n);
90
91 if (INTEGERP (w->orig_top))
92 XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
93 if (INTEGERP (w->orig_height))
94 XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
95
96 /* Handle just the top child in a vertical split. */
97 if (!NILP (w->vchild))
98 set_menu_bar_lines_1 (w->vchild, n);
99
100 /* Adjust all children in a horizontal split. */
101 for (window = w->hchild; !NILP (window); window = w->next)
102 {
103 w = XWINDOW (window);
104 set_menu_bar_lines_1 (window, n);
105 }
106 }
107
108 void
109 set_menu_bar_lines (f, value, oldval)
110 struct frame *f;
111 Lisp_Object value, oldval;
112 {
113 int nlines;
114 int olines = FRAME_MENU_BAR_LINES (f);
115
116 /* Right now, menu bars don't work properly in minibuf-only frames;
117 most of the commands try to apply themselves to the minibuffer
118 frame itself, and get an error because you can't switch buffers
119 in or split the minibuffer window. */
120 if (FRAME_MINIBUF_ONLY_P (f))
121 return;
122
123 if (INTEGERP (value))
124 nlines = XINT (value);
125 else
126 nlines = 0;
127
128 if (nlines != olines)
129 {
130 windows_or_buffers_changed++;
131 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
132 FRAME_MENU_BAR_LINES (f) = nlines;
133 set_menu_bar_lines_1 (f->root_window, nlines - olines);
134 adjust_glyphs (f);
135 }
136 }
137 \f
138 Lisp_Object Vemacs_iconified;
139 Lisp_Object Vframe_list;
140
141 struct x_output tty_display;
142
143 extern Lisp_Object Vminibuffer_list;
144 extern Lisp_Object get_minibuffer ();
145 extern Lisp_Object Fhandle_switch_frame ();
146 extern Lisp_Object Fredirect_frame_focus ();
147 extern Lisp_Object x_get_focus_frame ();
148 \f
149 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
150 "Return non-nil if OBJECT is a frame.\n\
151 Value is t for a termcap frame (a character-only terminal),\n\
152 `x' for an Emacs frame that is really an X window,\n\
153 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
154 `mac' for an Emacs frame on a Macintosh display,\n\
155 `pc' for a direct-write MS-DOS frame.\n\
156 See also `frame-live-p'.")
157 (object)
158 Lisp_Object object;
159 {
160 if (!FRAMEP (object))
161 return Qnil;
162 switch (XFRAME (object)->output_method)
163 {
164 case output_termcap:
165 return Qt;
166 case output_x_window:
167 return Qx;
168 case output_w32:
169 return Qw32;
170 case output_msdos_raw:
171 return Qpc;
172 case output_mac:
173 return Qmac;
174 default:
175 abort ();
176 }
177 }
178
179 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
180 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
181 Value is nil if OBJECT is not a live frame. If object is a live\n\
182 frame, the return value indicates what sort of output device it is\n\
183 displayed on. Value is t for a termcap frame (a character-only\n\
184 terminal), `x' for an Emacs frame being displayed in an X window.")
185 (object)
186 Lisp_Object object;
187 {
188 return ((FRAMEP (object)
189 && FRAME_LIVE_P (XFRAME (object)))
190 ? Fframep (object)
191 : Qnil);
192 }
193
194 struct frame *
195 make_frame (mini_p)
196 int mini_p;
197 {
198 Lisp_Object frame;
199 register struct frame *f;
200 register Lisp_Object root_window;
201 register Lisp_Object mini_window;
202
203 f = allocate_frame ();
204 XSETFRAME (frame, f);
205
206 f->desired_matrix = 0;
207 f->current_matrix = 0;
208 f->desired_pool = 0;
209 f->current_pool = 0;
210 f->glyphs_initialized_p = 0;
211 f->decode_mode_spec_buffer = 0;
212 f->visible = 0;
213 f->async_visible = 0;
214 f->output_data.nothing = 0;
215 f->iconified = 0;
216 f->async_iconified = 0;
217 f->wants_modeline = 1;
218 f->auto_raise = 0;
219 f->auto_lower = 0;
220 f->no_split = 0;
221 f->garbaged = 1;
222 f->has_minibuffer = mini_p;
223 f->focus_frame = Qnil;
224 f->explicit_name = 0;
225 f->can_have_scroll_bars = 0;
226 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
227 f->param_alist = Qnil;
228 f->scroll_bars = Qnil;
229 f->condemned_scroll_bars = Qnil;
230 f->face_alist = Qnil;
231 f->face_cache = NULL;
232 f->menu_bar_items = Qnil;
233 f->menu_bar_vector = Qnil;
234 f->menu_bar_items_used = 0;
235 f->buffer_predicate = Qnil;
236 f->buffer_list = Qnil;
237 #ifdef MULTI_KBOARD
238 f->kboard = initial_kboard;
239 #endif
240 f->namebuf = 0;
241 f->title = Qnil;
242 f->menu_bar_window = Qnil;
243 f->tool_bar_window = Qnil;
244 f->tool_bar_items = Qnil;
245 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
246 f->n_tool_bar_items = 0;
247
248 root_window = make_window ();
249 if (mini_p)
250 {
251 mini_window = make_window ();
252 XWINDOW (root_window)->next = mini_window;
253 XWINDOW (mini_window)->prev = root_window;
254 XWINDOW (mini_window)->mini_p = Qt;
255 XWINDOW (mini_window)->frame = frame;
256 f->minibuffer_window = mini_window;
257 }
258 else
259 {
260 mini_window = Qnil;
261 XWINDOW (root_window)->next = Qnil;
262 f->minibuffer_window = Qnil;
263 }
264
265 XWINDOW (root_window)->frame = frame;
266
267 /* 10 is arbitrary,
268 just so that there is "something there."
269 Correct size will be set up later with change_frame_size. */
270
271 SET_FRAME_WIDTH (f, 10);
272 f->height = 10;
273
274 XSETFASTINT (XWINDOW (root_window)->width, 10);
275 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
276
277 if (mini_p)
278 {
279 XSETFASTINT (XWINDOW (mini_window)->width, 10);
280 XSETFASTINT (XWINDOW (mini_window)->top, 9);
281 XSETFASTINT (XWINDOW (mini_window)->height, 1);
282 }
283
284 /* Choose a buffer for the frame's root window. */
285 {
286 Lisp_Object buf;
287
288 XWINDOW (root_window)->buffer = Qt;
289 buf = Fcurrent_buffer ();
290 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
291 a space), try to find another one. */
292 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
293 buf = Fother_buffer (buf, Qnil, Qnil);
294
295 /* Use set_window_buffer, not Fset_window_buffer, and don't let
296 hooks be run by it. The reason is that the whole frame/window
297 arrangement is not yet fully intialized at this point. Windows
298 don't have the right size, glyph matrices aren't initialized
299 etc. Running Lisp functions at this point surely ends in a
300 SEGV. */
301 set_window_buffer (root_window, buf, 0);
302 f->buffer_list = Fcons (buf, Qnil);
303 }
304
305 if (mini_p)
306 {
307 XWINDOW (mini_window)->buffer = Qt;
308 set_window_buffer (mini_window,
309 (NILP (Vminibuffer_list)
310 ? get_minibuffer (0)
311 : Fcar (Vminibuffer_list)),
312 0);
313 }
314
315 f->root_window = root_window;
316 f->selected_window = root_window;
317 /* Make sure this window seems more recently used than
318 a newly-created, never-selected window. */
319 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
320
321 return f;
322 }
323 \f
324 #ifdef HAVE_WINDOW_SYSTEM
325 /* Make a frame using a separate minibuffer window on another frame.
326 MINI_WINDOW is the minibuffer window to use. nil means use the
327 default (the global minibuffer). */
328
329 struct frame *
330 make_frame_without_minibuffer (mini_window, kb, display)
331 register Lisp_Object mini_window;
332 KBOARD *kb;
333 Lisp_Object display;
334 {
335 register struct frame *f;
336 struct gcpro gcpro1;
337
338 if (!NILP (mini_window))
339 CHECK_LIVE_WINDOW (mini_window, 0);
340
341 #ifdef MULTI_KBOARD
342 if (!NILP (mini_window)
343 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
344 error ("frame and minibuffer must be on the same display");
345 #endif
346
347 /* Make a frame containing just a root window. */
348 f = make_frame (0);
349
350 if (NILP (mini_window))
351 {
352 /* Use default-minibuffer-frame if possible. */
353 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
354 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
355 {
356 Lisp_Object frame_dummy;
357
358 XSETFRAME (frame_dummy, f);
359 GCPRO1 (frame_dummy);
360 /* If there's no minibuffer frame to use, create one. */
361 kb->Vdefault_minibuffer_frame =
362 call1 (intern ("make-initial-minibuffer-frame"), display);
363 UNGCPRO;
364 }
365
366 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
367 }
368
369 f->minibuffer_window = mini_window;
370
371 /* Make the chosen minibuffer window display the proper minibuffer,
372 unless it is already showing a minibuffer. */
373 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
374 Fset_window_buffer (mini_window,
375 (NILP (Vminibuffer_list)
376 ? get_minibuffer (0)
377 : Fcar (Vminibuffer_list)));
378 return f;
379 }
380
381 /* Make a frame containing only a minibuffer window. */
382
383 struct frame *
384 make_minibuffer_frame ()
385 {
386 /* First make a frame containing just a root window, no minibuffer. */
387
388 register struct frame *f = make_frame (0);
389 register Lisp_Object mini_window;
390 register Lisp_Object frame;
391
392 XSETFRAME (frame, f);
393
394 f->auto_raise = 0;
395 f->auto_lower = 0;
396 f->no_split = 1;
397 f->wants_modeline = 0;
398 f->has_minibuffer = 1;
399
400 /* Now label the root window as also being the minibuffer.
401 Avoid infinite looping on the window chain by marking next pointer
402 as nil. */
403
404 mini_window = f->minibuffer_window = f->root_window;
405 XWINDOW (mini_window)->mini_p = Qt;
406 XWINDOW (mini_window)->next = Qnil;
407 XWINDOW (mini_window)->prev = Qnil;
408 XWINDOW (mini_window)->frame = frame;
409
410 /* Put the proper buffer in that window. */
411
412 Fset_window_buffer (mini_window,
413 (NILP (Vminibuffer_list)
414 ? get_minibuffer (0)
415 : Fcar (Vminibuffer_list)));
416 return f;
417 }
418 #endif /* HAVE_WINDOW_SYSTEM */
419 \f
420 /* Construct a frame that refers to the terminal (stdin and stdout). */
421
422 static int terminal_frame_count;
423
424 struct frame *
425 make_terminal_frame ()
426 {
427 register struct frame *f;
428 Lisp_Object frame;
429 char name[20];
430
431 #ifdef MULTI_KBOARD
432 if (!initial_kboard)
433 {
434 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
435 init_kboard (initial_kboard);
436 initial_kboard->next_kboard = all_kboards;
437 all_kboards = initial_kboard;
438 }
439 #endif
440
441 /* The first call must initialize Vframe_list. */
442 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
443 Vframe_list = Qnil;
444
445 f = make_frame (1);
446
447 XSETFRAME (frame, f);
448 Vframe_list = Fcons (frame, Vframe_list);
449
450 terminal_frame_count++;
451 sprintf (name, "F%d", terminal_frame_count);
452 f->name = build_string (name);
453
454 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
455 f->async_visible = 1; /* Don't let visible be cleared later. */
456 #ifdef MSDOS
457 f->output_data.x = &the_only_x_display;
458 if (!inhibit_window_system
459 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
460 || XFRAME (selected_frame)->output_method == output_msdos_raw))
461 {
462 f->output_method = output_msdos_raw;
463 /* This initialization of foreground and background pixels is
464 only important for the initial frame created in temacs. If
465 we don't do that, we get black background and foreground in
466 the dumped Emacs because the_only_x_display is a static
467 variable, hence it is born all-zeroes, and zero is the code
468 for the black color. Other frames all inherit their pixels
469 from what's already in the_only_x_display. */
470 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
471 && f->output_data.x->background_pixel == 0
472 && f->output_data.x->foreground_pixel == 0)
473 {
474 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
475 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
476 }
477 }
478 else
479 f->output_method = output_termcap;
480 #else
481 #ifdef WINDOWSNT
482 f->output_method = output_termcap;
483 f->output_data.x = &tty_display;
484 #else
485 #ifdef macintosh
486 make_mac_terminal_frame (f);
487 #else
488 f->output_data.x = &tty_display;
489 #endif /* macintosh */
490 #endif /* WINDOWSNT */
491 #endif /* MSDOS */
492
493 if (!noninteractive)
494 init_frame_faces (f);
495
496 return f;
497 }
498
499 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
500 1, 1, 0, "Create an additional terminal frame.\n\
501 You can create multiple frames on a text-only terminal in this way.\n\
502 Only the selected terminal frame is actually displayed.\n\
503 This function takes one argument, an alist specifying frame parameters.\n\
504 In practice, generally you don't need to specify any parameters.\n\
505 Note that changing the size of one terminal frame automatically affects all.")
506 (parms)
507 Lisp_Object parms;
508 {
509 struct frame *f;
510 Lisp_Object frame, tem;
511 struct frame *sf = SELECTED_FRAME ();
512
513 #ifdef MSDOS
514 if (sf->output_method != output_msdos_raw
515 && sf->output_method != output_termcap)
516 abort ();
517 #else /* not MSDOS */
518
519 #ifdef macintosh
520 if (sf->output_method != output_mac)
521 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
522 #else
523 if (sf->output_method != output_termcap)
524 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
525 #endif
526 #endif /* not MSDOS */
527
528 f = make_terminal_frame ();
529
530 change_frame_size (f, FRAME_HEIGHT (sf),
531 FRAME_WIDTH (sf), 0, 0, 0);
532 adjust_glyphs (f);
533 calculate_costs (f);
534 XSETFRAME (frame, f);
535 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
536 Fmodify_frame_parameters (frame, parms);
537
538 /* Make the frame face alist be frame-specific, so that each
539 frame could change its face definitions independently. */
540 f->face_alist = Fcopy_alist (sf->face_alist);
541 /* Simple Fcopy_alist isn't enough, because we need the contents of
542 the vectors which are the CDRs of associations in face_alist to
543 be copied as well. */
544 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
545 XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
546 return frame;
547 }
548
549 \f
550 /* Perform the switch to frame FRAME.
551
552 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
553 FRAME1 as frame.
554
555 If TRACK is non-zero and the frame that currently has the focus
556 redirects its focus to the selected frame, redirect that focused
557 frame's focus to FRAME instead.
558
559 FOR_DELETION non-zero means that the selected frame is being
560 deleted, which includes the possibility that the frame's display
561 is dead. */
562
563 Lisp_Object
564 do_switch_frame (frame, track, for_deletion)
565 Lisp_Object frame;
566 int track, for_deletion;
567 {
568 struct frame *sf = SELECTED_FRAME ();
569
570 /* If FRAME is a switch-frame event, extract the frame we should
571 switch to. */
572 if (CONSP (frame)
573 && EQ (XCAR (frame), Qswitch_frame)
574 && CONSP (XCDR (frame)))
575 frame = XCAR (XCDR (frame));
576
577 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
578 a switch-frame event to arrive after a frame is no longer live,
579 especially when deleting the initial frame during startup. */
580 CHECK_FRAME (frame, 0);
581 if (! FRAME_LIVE_P (XFRAME (frame)))
582 return Qnil;
583
584 if (sf == XFRAME (frame))
585 return frame;
586
587 /* This is too greedy; it causes inappropriate focus redirection
588 that's hard to get rid of. */
589 #if 0
590 /* If a frame's focus has been redirected toward the currently
591 selected frame, we should change the redirection to point to the
592 newly selected frame. This means that if the focus is redirected
593 from a minibufferless frame to a surrogate minibuffer frame, we
594 can use `other-window' to switch between all the frames using
595 that minibuffer frame, and the focus redirection will follow us
596 around. */
597 if (track)
598 {
599 Lisp_Object tail;
600
601 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
602 {
603 Lisp_Object focus;
604
605 if (!FRAMEP (XCAR (tail)))
606 abort ();
607
608 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
609
610 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
611 Fredirect_frame_focus (XCAR (tail), frame);
612 }
613 }
614 #else /* ! 0 */
615 /* Instead, apply it only to the frame we're pointing to. */
616 #ifdef HAVE_WINDOW_SYSTEM
617 if (track && FRAME_WINDOW_P (XFRAME (frame)))
618 {
619 Lisp_Object focus, xfocus;
620
621 xfocus = x_get_focus_frame (XFRAME (frame));
622 if (FRAMEP (xfocus))
623 {
624 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
625 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
626 Fredirect_frame_focus (xfocus, frame);
627 }
628 }
629 #endif /* HAVE_X_WINDOWS */
630 #endif /* ! 0 */
631
632 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
633 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
634
635 selected_frame = frame;
636 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
637 last_nonminibuf_frame = XFRAME (selected_frame);
638
639 Fselect_window (XFRAME (frame)->selected_window);
640
641 /* We want to make sure that the next event generates a frame-switch
642 event to the appropriate frame. This seems kludgy to me, but
643 before you take it out, make sure that evaluating something like
644 (select-window (frame-root-window (new-frame))) doesn't end up
645 with your typing being interpreted in the new frame instead of
646 the one you're actually typing in. */
647 internal_last_event_frame = Qnil;
648
649 return frame;
650 }
651
652 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
653 "Select the frame FRAME.\n\
654 Subsequent editing commands apply to its selected window.\n\
655 The selection of FRAME lasts until the next time the user does\n\
656 something to select a different frame, or until the next time this\n\
657 function is called.")
658 (frame, no_enter)
659 Lisp_Object frame, no_enter;
660 {
661 return do_switch_frame (frame, 1, 0);
662 }
663
664
665 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
666 "Handle a switch-frame event EVENT.\n\
667 Switch-frame events are usually bound to this function.\n\
668 A switch-frame event tells Emacs that the window manager has requested\n\
669 that the user's events be directed to the frame mentioned in the event.\n\
670 This function selects the selected window of the frame of EVENT.\n\
671 \n\
672 If EVENT is frame object, handle it as if it were a switch-frame event\n\
673 to that frame.")
674 (event, no_enter)
675 Lisp_Object event, no_enter;
676 {
677 /* Preserve prefix arg that the command loop just cleared. */
678 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
679 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
680 return do_switch_frame (event, 0, 0);
681 }
682
683 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
684 "Do nothing, but preserve any prefix argument already specified.\n\
685 This is a suitable binding for iconify-frame and make-frame-visible.")
686 ()
687 {
688 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
689 return Qnil;
690 }
691
692 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
693 "Return the frame that is now selected.")
694 ()
695 {
696 return selected_frame;
697 }
698 \f
699 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
700 "Return the frame object that window WINDOW is on.")
701 (window)
702 Lisp_Object window;
703 {
704 CHECK_LIVE_WINDOW (window, 0);
705 return XWINDOW (window)->frame;
706 }
707
708 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
709 "Returns the topmost, leftmost window of FRAME.\n\
710 If omitted, FRAME defaults to the currently selected frame.")
711 (frame)
712 Lisp_Object frame;
713 {
714 Lisp_Object w;
715
716 if (NILP (frame))
717 w = SELECTED_FRAME ()->root_window;
718 else
719 {
720 CHECK_LIVE_FRAME (frame, 0);
721 w = XFRAME (frame)->root_window;
722 }
723 while (NILP (XWINDOW (w)->buffer))
724 {
725 if (! NILP (XWINDOW (w)->hchild))
726 w = XWINDOW (w)->hchild;
727 else if (! NILP (XWINDOW (w)->vchild))
728 w = XWINDOW (w)->vchild;
729 else
730 abort ();
731 }
732 return w;
733 }
734
735 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
736 Sactive_minibuffer_window, 0, 0, 0,
737 "Return the currently active minibuffer window, or nil if none.")
738 ()
739 {
740 return minibuf_level ? minibuf_window : Qnil;
741 }
742
743 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
744 "Returns the root-window of FRAME.\n\
745 If omitted, FRAME defaults to the currently selected frame.")
746 (frame)
747 Lisp_Object frame;
748 {
749 Lisp_Object window;
750
751 if (NILP (frame))
752 window = SELECTED_FRAME ()->root_window;
753 else
754 {
755 CHECK_LIVE_FRAME (frame, 0);
756 window = XFRAME (frame)->root_window;
757 }
758
759 return window;
760 }
761
762 DEFUN ("frame-selected-window", Fframe_selected_window,
763 Sframe_selected_window, 0, 1, 0,
764 "Return the selected window of frame object FRAME.\n\
765 If omitted, FRAME defaults to the currently selected frame.")
766 (frame)
767 Lisp_Object frame;
768 {
769 Lisp_Object window;
770
771 if (NILP (frame))
772 window = SELECTED_FRAME ()->selected_window;
773 else
774 {
775 CHECK_LIVE_FRAME (frame, 0);
776 window = XFRAME (frame)->selected_window;
777 }
778
779 return window;
780 }
781
782 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
783 Sset_frame_selected_window, 2, 2, 0,
784 "Set the selected window of frame object FRAME to WINDOW.\n\
785 If FRAME is nil, the selected frame is used.\n\
786 If FRAME is the selected frame, this makes WINDOW the selected window.")
787 (frame, window)
788 Lisp_Object frame, window;
789 {
790 if (NILP (frame))
791 frame = selected_frame;
792
793 CHECK_LIVE_FRAME (frame, 0);
794 CHECK_LIVE_WINDOW (window, 1);
795
796 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
797 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
798
799 if (EQ (frame, selected_frame))
800 return Fselect_window (window);
801
802 return XFRAME (frame)->selected_window = window;
803 }
804 \f
805 DEFUN ("frame-list", Fframe_list, Sframe_list,
806 0, 0, 0,
807 "Return a list of all frames.")
808 ()
809 {
810 return Fcopy_sequence (Vframe_list);
811 }
812
813 /* Return the next frame in the frame list after FRAME.
814 If MINIBUF is nil, exclude minibuffer-only frames.
815 If MINIBUF is a window, include only its own frame
816 and any frame now using that window as the minibuffer.
817 If MINIBUF is `visible', include all visible frames.
818 If MINIBUF is 0, include all visible and iconified frames.
819 Otherwise, include all frames. */
820
821 Lisp_Object
822 next_frame (frame, minibuf)
823 Lisp_Object frame;
824 Lisp_Object minibuf;
825 {
826 Lisp_Object tail;
827 int passed = 0;
828
829 /* There must always be at least one frame in Vframe_list. */
830 if (! CONSP (Vframe_list))
831 abort ();
832
833 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
834 forever. Forestall that. */
835 CHECK_LIVE_FRAME (frame, 0);
836
837 while (1)
838 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
839 {
840 Lisp_Object f;
841
842 f = XCAR (tail);
843
844 if (passed
845 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
846 {
847 /* Decide whether this frame is eligible to be returned. */
848
849 /* If we've looped all the way around without finding any
850 eligible frames, return the original frame. */
851 if (EQ (f, frame))
852 return f;
853
854 /* Let minibuf decide if this frame is acceptable. */
855 if (NILP (minibuf))
856 {
857 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
858 return f;
859 }
860 else if (EQ (minibuf, Qvisible))
861 {
862 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
863 if (FRAME_VISIBLE_P (XFRAME (f)))
864 return f;
865 }
866 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
867 {
868 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
869 if (FRAME_VISIBLE_P (XFRAME (f))
870 || FRAME_ICONIFIED_P (XFRAME (f)))
871 return f;
872 }
873 else if (WINDOWP (minibuf))
874 {
875 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
876 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
877 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
878 FRAME_FOCUS_FRAME (XFRAME (f))))
879 return f;
880 }
881 else
882 return f;
883 }
884
885 if (EQ (frame, f))
886 passed++;
887 }
888 }
889
890 /* Return the previous frame in the frame list before FRAME.
891 If MINIBUF is nil, exclude minibuffer-only frames.
892 If MINIBUF is a window, include only its own frame
893 and any frame now using that window as the minibuffer.
894 If MINIBUF is `visible', include all visible frames.
895 If MINIBUF is 0, include all visible and iconified frames.
896 Otherwise, include all frames. */
897
898 Lisp_Object
899 prev_frame (frame, minibuf)
900 Lisp_Object frame;
901 Lisp_Object minibuf;
902 {
903 Lisp_Object tail;
904 Lisp_Object prev;
905
906 /* There must always be at least one frame in Vframe_list. */
907 if (! CONSP (Vframe_list))
908 abort ();
909
910 prev = Qnil;
911 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
912 {
913 Lisp_Object f;
914
915 f = XCAR (tail);
916 if (!FRAMEP (f))
917 abort ();
918
919 if (EQ (frame, f) && !NILP (prev))
920 return prev;
921
922 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
923 {
924 /* Decide whether this frame is eligible to be returned,
925 according to minibuf. */
926 if (NILP (minibuf))
927 {
928 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
929 prev = f;
930 }
931 else if (WINDOWP (minibuf))
932 {
933 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
934 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
935 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
936 FRAME_FOCUS_FRAME (XFRAME (f))))
937 prev = f;
938 }
939 else if (EQ (minibuf, Qvisible))
940 {
941 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
942 if (FRAME_VISIBLE_P (XFRAME (f)))
943 prev = f;
944 }
945 else if (XFASTINT (minibuf) == 0)
946 {
947 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
948 if (FRAME_VISIBLE_P (XFRAME (f))
949 || FRAME_ICONIFIED_P (XFRAME (f)))
950 prev = f;
951 }
952 else
953 prev = f;
954 }
955 }
956
957 /* We've scanned the entire list. */
958 if (NILP (prev))
959 /* We went through the whole frame list without finding a single
960 acceptable frame. Return the original frame. */
961 return frame;
962 else
963 /* There were no acceptable frames in the list before FRAME; otherwise,
964 we would have returned directly from the loop. Since PREV is the last
965 acceptable frame in the list, return it. */
966 return prev;
967 }
968
969
970 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
971 "Return the next frame in the frame list after FRAME.\n\
972 It considers only frames on the same terminal as FRAME.\n\
973 By default, skip minibuffer-only frames.\n\
974 If omitted, FRAME defaults to the selected frame.\n\
975 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
976 If MINIFRAME is a window, include only its own frame\n\
977 and any frame now using that window as the minibuffer.\n\
978 If MINIFRAME is `visible', include all visible frames.\n\
979 If MINIFRAME is 0, include all visible and iconified frames.\n\
980 Otherwise, include all frames.")
981 (frame, miniframe)
982 Lisp_Object frame, miniframe;
983 {
984 if (NILP (frame))
985 frame = selected_frame;
986
987 CHECK_LIVE_FRAME (frame, 0);
988 return next_frame (frame, miniframe);
989 }
990
991 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
992 "Return the previous frame in the frame list before FRAME.\n\
993 It considers only frames on the same terminal as FRAME.\n\
994 By default, skip minibuffer-only frames.\n\
995 If omitted, FRAME defaults to the selected frame.\n\
996 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
997 If MINIFRAME is a window, include only its own frame\n\
998 and any frame now using that window as the minibuffer.\n\
999 If MINIFRAME is `visible', include all visible frames.\n\
1000 If MINIFRAME is 0, include all visible and iconified frames.\n\
1001 Otherwise, include all frames.")
1002 (frame, miniframe)
1003 Lisp_Object frame, miniframe;
1004 {
1005 if (NILP (frame))
1006 frame = selected_frame;
1007 CHECK_LIVE_FRAME (frame, 0);
1008 return prev_frame (frame, miniframe);
1009 }
1010 \f
1011 /* Return 1 if it is ok to delete frame F;
1012 0 if all frames aside from F are invisible.
1013 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1014
1015 int
1016 other_visible_frames (f)
1017 FRAME_PTR f;
1018 {
1019 /* We know the selected frame is visible,
1020 so if F is some other frame, it can't be the sole visible one. */
1021 if (f == SELECTED_FRAME ())
1022 {
1023 Lisp_Object frames;
1024 int count = 0;
1025
1026 for (frames = Vframe_list;
1027 CONSP (frames);
1028 frames = XCDR (frames))
1029 {
1030 Lisp_Object this;
1031
1032 this = XCAR (frames);
1033 /* Verify that the frame's window still exists
1034 and we can still talk to it. And note any recent change
1035 in visibility. */
1036 #ifdef HAVE_WINDOW_SYSTEM
1037 if (FRAME_WINDOW_P (XFRAME (this)))
1038 {
1039 x_sync (XFRAME (this));
1040 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1041 }
1042 #endif
1043
1044 if (FRAME_VISIBLE_P (XFRAME (this))
1045 || FRAME_ICONIFIED_P (XFRAME (this))
1046 /* Allow deleting the terminal frame when at least
1047 one X frame exists! */
1048 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1049 count++;
1050 }
1051 return count > 1;
1052 }
1053 return 1;
1054 }
1055
1056 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1057 "Delete FRAME, permanently eliminating it from use.\n\
1058 If omitted, FRAME defaults to the selected frame.\n\
1059 A frame may not be deleted if its minibuffer is used by other frames.\n\
1060 Normally, you may not delete a frame if all other frames are invisible,\n\
1061 but if the second optional argument FORCE is non-nil, you may do so.\n\
1062 \n\
1063 This function runs `delete-frame-hook' before actually deleting the\n\
1064 frame. The hook is called with one argument FRAME.")
1065 (frame, force)
1066 Lisp_Object frame, force;
1067 {
1068 struct frame *f;
1069 struct frame *sf = SELECTED_FRAME ();
1070 int minibuffer_selected;
1071
1072 if (EQ (frame, Qnil))
1073 {
1074 f = sf;
1075 XSETFRAME (frame, f);
1076 }
1077 else
1078 {
1079 CHECK_FRAME (frame, 0);
1080 f = XFRAME (frame);
1081 }
1082
1083 if (! FRAME_LIVE_P (f))
1084 return Qnil;
1085
1086 if (NILP (force) && !other_visible_frames (f)
1087 #ifdef macintosh
1088 /* Terminal frame deleted before any other visible frames are
1089 created. */
1090 && strcmp (XSTRING (f->name)->data, "F1") != 0
1091 #endif
1092 )
1093 error ("Attempt to delete the sole visible or iconified frame");
1094
1095 #if 0
1096 /* This is a nice idea, but x_connection_closed needs to be able
1097 to delete the last frame, if it is gone. */
1098 if (NILP (XCDR (Vframe_list)))
1099 error ("Attempt to delete the only frame");
1100 #endif
1101
1102 /* Does this frame have a minibuffer, and is it the surrogate
1103 minibuffer for any other frame? */
1104 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1105 {
1106 Lisp_Object frames;
1107
1108 for (frames = Vframe_list;
1109 CONSP (frames);
1110 frames = XCDR (frames))
1111 {
1112 Lisp_Object this;
1113 this = XCAR (frames);
1114
1115 if (! EQ (this, frame)
1116 && EQ (frame,
1117 WINDOW_FRAME (XWINDOW
1118 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1119 error ("Attempt to delete a surrogate minibuffer frame");
1120 }
1121 }
1122
1123 /* Run `delete-frame-hook'. */
1124 if (!NILP (Vrun_hooks))
1125 {
1126 Lisp_Object args[2];
1127 args[0] = intern ("delete-frame-hook");
1128 args[1] = frame;
1129 Frun_hook_with_args (2, args);
1130 }
1131
1132 minibuffer_selected = EQ (minibuf_window, selected_window);
1133
1134 /* Don't let the frame remain selected. */
1135 if (f == sf)
1136 {
1137 Lisp_Object tail, frame1;
1138
1139 /* Look for another visible frame on the same terminal. */
1140 frame1 = next_frame (frame, Qvisible);
1141
1142 /* If there is none, find *some* other frame. */
1143 if (NILP (frame1) || EQ (frame1, frame))
1144 {
1145 FOR_EACH_FRAME (tail, frame1)
1146 {
1147 if (! EQ (frame, frame1))
1148 break;
1149 }
1150 }
1151
1152 do_switch_frame (frame1, 0, 1);
1153 sf = SELECTED_FRAME ();
1154 }
1155
1156 /* Don't allow minibuf_window to remain on a deleted frame. */
1157 if (EQ (f->minibuffer_window, minibuf_window))
1158 {
1159 Fset_window_buffer (sf->minibuffer_window,
1160 XWINDOW (minibuf_window)->buffer);
1161 minibuf_window = sf->minibuffer_window;
1162
1163 /* If the dying minibuffer window was selected,
1164 select the new one. */
1165 if (minibuffer_selected)
1166 Fselect_window (minibuf_window);
1167 }
1168
1169 /* Don't let echo_area_window to remain on a deleted frame. */
1170 if (EQ (f->minibuffer_window, echo_area_window))
1171 echo_area_window = sf->minibuffer_window;
1172
1173 /* Clear any X selections for this frame. */
1174 #ifdef HAVE_X_WINDOWS
1175 if (FRAME_X_P (f))
1176 x_clear_frame_selections (f);
1177 #endif
1178
1179 /* Free glyphs.
1180 This function must be called before the window tree of the
1181 frame is deleted because windows contain dynamically allocated
1182 memory. */
1183 free_glyphs (f);
1184
1185 /* Mark all the windows that used to be on FRAME as deleted, and then
1186 remove the reference to them. */
1187 delete_all_subwindows (XWINDOW (f->root_window));
1188 f->root_window = Qnil;
1189
1190 Vframe_list = Fdelq (frame, Vframe_list);
1191 FRAME_SET_VISIBLE (f, 0);
1192
1193 if (f->namebuf)
1194 xfree (f->namebuf);
1195 if (FRAME_INSERT_COST (f))
1196 xfree (FRAME_INSERT_COST (f));
1197 if (FRAME_DELETEN_COST (f))
1198 xfree (FRAME_DELETEN_COST (f));
1199 if (FRAME_INSERTN_COST (f))
1200 xfree (FRAME_INSERTN_COST (f));
1201 if (FRAME_DELETE_COST (f))
1202 xfree (FRAME_DELETE_COST (f));
1203 if (FRAME_MESSAGE_BUF (f))
1204 xfree (FRAME_MESSAGE_BUF (f));
1205
1206 /* Since some events are handled at the interrupt level, we may get
1207 an event for f at any time; if we zero out the frame's display
1208 now, then we may trip up the event-handling code. Instead, we'll
1209 promise that the display of the frame must be valid until we have
1210 called the window-system-dependent frame destruction routine. */
1211
1212 /* I think this should be done with a hook. */
1213 #ifdef HAVE_WINDOW_SYSTEM
1214 if (FRAME_WINDOW_P (f))
1215 x_destroy_window (f);
1216 #endif
1217
1218 f->output_data.nothing = 0;
1219
1220 /* If we've deleted the last_nonminibuf_frame, then try to find
1221 another one. */
1222 if (f == last_nonminibuf_frame)
1223 {
1224 Lisp_Object frames;
1225
1226 last_nonminibuf_frame = 0;
1227
1228 for (frames = Vframe_list;
1229 CONSP (frames);
1230 frames = XCDR (frames))
1231 {
1232 f = XFRAME (XCAR (frames));
1233 if (!FRAME_MINIBUF_ONLY_P (f))
1234 {
1235 last_nonminibuf_frame = f;
1236 break;
1237 }
1238 }
1239 }
1240
1241 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1242 find another one. Prefer minibuffer-only frames, but also notice
1243 frames with other windows. */
1244 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1245 {
1246 Lisp_Object frames;
1247
1248 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1249 Lisp_Object frame_with_minibuf;
1250 /* Some frame we found on the same kboard, or nil if there are none. */
1251 Lisp_Object frame_on_same_kboard;
1252
1253 frame_on_same_kboard = Qnil;
1254 frame_with_minibuf = Qnil;
1255
1256 for (frames = Vframe_list;
1257 CONSP (frames);
1258 frames = XCDR (frames))
1259 {
1260 Lisp_Object this;
1261 struct frame *f1;
1262
1263 this = XCAR (frames);
1264 if (!FRAMEP (this))
1265 abort ();
1266 f1 = XFRAME (this);
1267
1268 /* Consider only frames on the same kboard
1269 and only those with minibuffers. */
1270 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1271 && FRAME_HAS_MINIBUF_P (f1))
1272 {
1273 frame_with_minibuf = this;
1274 if (FRAME_MINIBUF_ONLY_P (f1))
1275 break;
1276 }
1277
1278 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1279 frame_on_same_kboard = this;
1280 }
1281
1282 if (!NILP (frame_on_same_kboard))
1283 {
1284 /* We know that there must be some frame with a minibuffer out
1285 there. If this were not true, all of the frames present
1286 would have to be minibufferless, which implies that at some
1287 point their minibuffer frames must have been deleted, but
1288 that is prohibited at the top; you can't delete surrogate
1289 minibuffer frames. */
1290 if (NILP (frame_with_minibuf))
1291 abort ();
1292
1293 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1294 }
1295 else
1296 /* No frames left on this kboard--say no minibuffer either. */
1297 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1298 }
1299
1300 /* Cause frame titles to update--necessary if we now have just one frame. */
1301 update_mode_lines = 1;
1302
1303 return Qnil;
1304 }
1305 \f
1306 /* Return mouse position in character cell units. */
1307
1308 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1309 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1310 The position is given in character cells, where (0, 0) is the\n\
1311 upper-left corner.\n\
1312 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1313 to read the mouse position, it returns the selected frame for FRAME\n\
1314 and nil for X and Y.\n\
1315 Runs the abnormal hook `mouse-position-function' with the normal return\n\
1316 value as argument.")
1317 ()
1318 {
1319 FRAME_PTR f;
1320 Lisp_Object lispy_dummy;
1321 enum scroll_bar_part party_dummy;
1322 Lisp_Object x, y, retval;
1323 int col, row;
1324 unsigned long long_dummy;
1325 struct gcpro gcpro1;
1326
1327 f = SELECTED_FRAME ();
1328 x = y = Qnil;
1329
1330 #ifdef HAVE_MOUSE
1331 /* It's okay for the hook to refrain from storing anything. */
1332 if (mouse_position_hook)
1333 (*mouse_position_hook) (&f, -1,
1334 &lispy_dummy, &party_dummy,
1335 &x, &y,
1336 &long_dummy);
1337 if (! NILP (x))
1338 {
1339 col = XINT (x);
1340 row = XINT (y);
1341 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1342 XSETINT (x, col);
1343 XSETINT (y, row);
1344 }
1345 #endif
1346 XSETFRAME (lispy_dummy, f);
1347 retval = Fcons (lispy_dummy, Fcons (x, y));
1348 GCPRO1 (retval);
1349 if (!NILP (Vmouse_position_function))
1350 retval = call1 (Vmouse_position_function, retval);
1351 RETURN_UNGCPRO (retval);
1352 }
1353
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.")
1362 ()
1363 {
1364 FRAME_PTR f;
1365 Lisp_Object lispy_dummy;
1366 enum scroll_bar_part party_dummy;
1367 Lisp_Object x, y;
1368 unsigned long long_dummy;
1369
1370 f = SELECTED_FRAME ();
1371 x = y = Qnil;
1372
1373 #ifdef HAVE_MOUSE
1374 /* It's okay for the hook to refrain from storing anything. */
1375 if (mouse_position_hook)
1376 (*mouse_position_hook) (&f, -1,
1377 &lispy_dummy, &party_dummy,
1378 &x, &y,
1379 &long_dummy);
1380 #endif
1381 XSETFRAME (lispy_dummy, f);
1382 return Fcons (lispy_dummy, Fcons (x, y));
1383 }
1384
1385 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1386 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1387 Coordinates are relative to the frame, not a window,\n\
1388 so the coordinates of the top left character in the frame\n\
1389 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1390 \n\
1391 This function is a no-op for an X frame that is not visible.\n\
1392 If you have just created a frame, you must wait for it to become visible\n\
1393 before calling this function on it, like this.\n\
1394 (while (not (frame-visible-p frame)) (sleep-for .5))")
1395 (frame, x, y)
1396 Lisp_Object frame, x, y;
1397 {
1398 CHECK_LIVE_FRAME (frame, 0);
1399 CHECK_NUMBER (x, 2);
1400 CHECK_NUMBER (y, 1);
1401
1402 /* I think this should be done with a hook. */
1403 #ifdef HAVE_WINDOW_SYSTEM
1404 if (FRAME_WINDOW_P (XFRAME (frame)))
1405 /* Warping the mouse will cause enternotify and focus events. */
1406 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1407 #else
1408 #if defined (MSDOS) && defined (HAVE_MOUSE)
1409 if (FRAME_MSDOS_P (XFRAME (frame)))
1410 {
1411 Fselect_frame (frame, Qnil);
1412 mouse_moveto (XINT (x), XINT (y));
1413 }
1414 #endif
1415 #endif
1416
1417 return Qnil;
1418 }
1419
1420 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1421 Sset_mouse_pixel_position, 3, 3, 0,
1422 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1423 Note, this is a no-op for an X frame that is not visible.\n\
1424 If you have just created a frame, you must wait for it to become visible\n\
1425 before calling this function on it, like this.\n\
1426 (while (not (frame-visible-p frame)) (sleep-for .5))")
1427 (frame, x, y)
1428 Lisp_Object frame, x, y;
1429 {
1430 CHECK_LIVE_FRAME (frame, 0);
1431 CHECK_NUMBER (x, 2);
1432 CHECK_NUMBER (y, 1);
1433
1434 /* I think this should be done with a hook. */
1435 #ifdef HAVE_WINDOW_SYSTEM
1436 if (FRAME_WINDOW_P (XFRAME (frame)))
1437 /* Warping the mouse will cause enternotify and focus events. */
1438 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1439 #else
1440 #if defined (MSDOS) && defined (HAVE_MOUSE)
1441 if (FRAME_MSDOS_P (XFRAME (frame)))
1442 {
1443 Fselect_frame (frame, Qnil);
1444 mouse_moveto (XINT (x), XINT (y));
1445 }
1446 #endif
1447 #endif
1448
1449 return Qnil;
1450 }
1451 \f
1452 static void make_frame_visible_1 P_ ((Lisp_Object));
1453
1454 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1455 0, 1, "",
1456 "Make the frame FRAME visible (assuming it is an X-window).\n\
1457 If omitted, FRAME defaults to the currently selected frame.")
1458 (frame)
1459 Lisp_Object frame;
1460 {
1461 if (NILP (frame))
1462 frame = selected_frame;
1463
1464 CHECK_LIVE_FRAME (frame, 0);
1465
1466 /* I think this should be done with a hook. */
1467 #ifdef HAVE_WINDOW_SYSTEM
1468 if (FRAME_WINDOW_P (XFRAME (frame)))
1469 {
1470 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1471 x_make_frame_visible (XFRAME (frame));
1472 }
1473 #endif
1474
1475 make_frame_visible_1 (XFRAME (frame)->root_window);
1476
1477 /* Make menu bar update for the Buffers and Frams menus. */
1478 windows_or_buffers_changed++;
1479
1480 return frame;
1481 }
1482
1483 /* Update the display_time slot of the buffers shown in WINDOW
1484 and all its descendents. */
1485
1486 static void
1487 make_frame_visible_1 (window)
1488 Lisp_Object window;
1489 {
1490 struct window *w;
1491
1492 for (;!NILP (window); window = w->next)
1493 {
1494 w = XWINDOW (window);
1495
1496 if (!NILP (w->buffer))
1497 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1498
1499 if (!NILP (w->vchild))
1500 make_frame_visible_1 (w->vchild);
1501 if (!NILP (w->hchild))
1502 make_frame_visible_1 (w->hchild);
1503 }
1504 }
1505
1506 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1507 0, 2, "",
1508 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1509 If omitted, FRAME defaults to the currently selected frame.\n\
1510 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1511 but if the second optional argument FORCE is non-nil, you may do so.")
1512 (frame, force)
1513 Lisp_Object frame, force;
1514 {
1515 if (NILP (frame))
1516 frame = selected_frame;
1517
1518 CHECK_LIVE_FRAME (frame, 0);
1519
1520 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1521 error ("Attempt to make invisible the sole visible or iconified frame");
1522
1523 #if 0 /* This isn't logically necessary, and it can do GC. */
1524 /* Don't let the frame remain selected. */
1525 if (EQ (frame, selected_frame))
1526 do_switch_frame (next_frame (frame, Qt), 0, 0)
1527 #endif
1528
1529 /* Don't allow minibuf_window to remain on a deleted frame. */
1530 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1531 {
1532 struct frame *sf = XFRAME (selected_frame);
1533 Fset_window_buffer (sf->minibuffer_window,
1534 XWINDOW (minibuf_window)->buffer);
1535 minibuf_window = sf->minibuffer_window;
1536 }
1537
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
1543
1544 /* Make menu bar update for the Buffers and Frams menus. */
1545 windows_or_buffers_changed++;
1546
1547 return Qnil;
1548 }
1549
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;
1556 {
1557 if (NILP (frame))
1558 frame = selected_frame;
1559
1560 CHECK_LIVE_FRAME (frame, 0);
1561
1562 #if 0 /* This isn't logically necessary, and it can do GC. */
1563 /* Don't let the frame remain selected. */
1564 if (EQ (frame, selected_frame))
1565 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1566 #endif
1567
1568 /* Don't allow minibuf_window to remain on a deleted frame. */
1569 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1570 {
1571 struct frame *sf = XFRAME (selected_frame);
1572 Fset_window_buffer (sf->minibuffer_window,
1573 XWINDOW (minibuf_window)->buffer);
1574 minibuf_window = sf->minibuffer_window;
1575 }
1576
1577 /* I think this should be done with a hook. */
1578 #ifdef HAVE_WINDOW_SYSTEM
1579 if (FRAME_WINDOW_P (XFRAME (frame)))
1580 x_iconify_frame (XFRAME (frame));
1581 #endif
1582
1583 /* Make menu bar update for the Buffers and Frams menus. */
1584 windows_or_buffers_changed++;
1585
1586 return Qnil;
1587 }
1588
1589 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1590 1, 1, 0,
1591 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1592 A frame that is not \"visible\" is not updated and, if it works through\n\
1593 a window system, it may not show at all.\n\
1594 Return the symbol `icon' if frame is visible only as an icon.")
1595 (frame)
1596 Lisp_Object frame;
1597 {
1598 CHECK_LIVE_FRAME (frame, 0);
1599
1600 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1601
1602 if (FRAME_VISIBLE_P (XFRAME (frame)))
1603 return Qt;
1604 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1605 return Qicon;
1606 return Qnil;
1607 }
1608
1609 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1610 0, 0, 0,
1611 "Return a list of all frames now \"visible\" (being updated).")
1612 ()
1613 {
1614 Lisp_Object tail, frame;
1615 struct frame *f;
1616 Lisp_Object value;
1617
1618 value = Qnil;
1619 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1620 {
1621 frame = XCAR (tail);
1622 if (!FRAMEP (frame))
1623 continue;
1624 f = XFRAME (frame);
1625 if (FRAME_VISIBLE_P (f))
1626 value = Fcons (frame, value);
1627 }
1628 return value;
1629 }
1630
1631
1632 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1633 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1634 If FRAME is invisible, make it visible.\n\
1635 If you don't specify a frame, the selected frame is used.\n\
1636 If Emacs is displaying on an ordinary terminal or some other device which\n\
1637 doesn't support multiple overlapping frames, this function does nothing.")
1638 (frame)
1639 Lisp_Object frame;
1640 {
1641 if (NILP (frame))
1642 frame = selected_frame;
1643
1644 CHECK_LIVE_FRAME (frame, 0);
1645
1646 /* Do like the documentation says. */
1647 Fmake_frame_visible (frame);
1648
1649 if (frame_raise_lower_hook)
1650 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1651
1652 return Qnil;
1653 }
1654
1655 /* Should we have a corresponding function called Flower_Power? */
1656 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1657 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1658 If you don't specify a frame, the selected frame is used.\n\
1659 If Emacs is displaying on an ordinary terminal or some other device which\n\
1660 doesn't support multiple overlapping frames, this function does nothing.")
1661 (frame)
1662 Lisp_Object frame;
1663 {
1664 if (NILP (frame))
1665 frame = selected_frame;
1666
1667 CHECK_LIVE_FRAME (frame, 0);
1668
1669 if (frame_raise_lower_hook)
1670 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1671
1672 return Qnil;
1673 }
1674
1675 \f
1676 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1677 1, 2, 0,
1678 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1679 In other words, switch-frame events caused by events in FRAME will\n\
1680 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1681 FOCUS-FRAME after reading an event typed at FRAME.\n\
1682 \n\
1683 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1684 cancelled, and the frame again receives its own keystrokes.\n\
1685 \n\
1686 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1687 a surrogate minibuffer frame when a frame doesn't have its own\n\
1688 minibuffer window.\n\
1689 \n\
1690 A frame's focus redirection can be changed by select-frame. If frame\n\
1691 FOO is selected, and then a different frame BAR is selected, any\n\
1692 frames redirecting their focus to FOO are shifted to redirect their\n\
1693 focus to BAR. This allows focus redirection to work properly when the\n\
1694 user switches from one frame to another using `select-window'.\n\
1695 \n\
1696 This means that a frame whose focus is redirected to itself is treated\n\
1697 differently from a frame whose focus is redirected to nil; the former\n\
1698 is affected by select-frame, while the latter is not.\n\
1699 \n\
1700 The redirection lasts until `redirect-frame-focus' is called to change it.")
1701 (frame, focus_frame)
1702 Lisp_Object frame, focus_frame;
1703 {
1704 /* Note that we don't check for a live frame here. It's reasonable
1705 to redirect the focus of a frame you're about to delete, if you
1706 know what other frame should receive those keystrokes. */
1707 CHECK_FRAME (frame, 0);
1708
1709 if (! NILP (focus_frame))
1710 CHECK_LIVE_FRAME (focus_frame, 1);
1711
1712 XFRAME (frame)->focus_frame = focus_frame;
1713
1714 if (frame_rehighlight_hook)
1715 (*frame_rehighlight_hook) (XFRAME (frame));
1716
1717 return Qnil;
1718 }
1719
1720
1721 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1722 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1723 This returns nil if FRAME's focus is not redirected.\n\
1724 See `redirect-frame-focus'.")
1725 (frame)
1726 Lisp_Object frame;
1727 {
1728 CHECK_LIVE_FRAME (frame, 0);
1729
1730 return FRAME_FOCUS_FRAME (XFRAME (frame));
1731 }
1732
1733
1734 \f
1735 /* Return the value of frame parameter PROP in frame FRAME. */
1736
1737 Lisp_Object
1738 get_frame_param (frame, prop)
1739 register struct frame *frame;
1740 Lisp_Object prop;
1741 {
1742 register Lisp_Object tem;
1743
1744 tem = Fassq (prop, frame->param_alist);
1745 if (EQ (tem, Qnil))
1746 return tem;
1747 return Fcdr (tem);
1748 }
1749
1750 /* Return the buffer-predicate of the selected frame. */
1751
1752 Lisp_Object
1753 frame_buffer_predicate (frame)
1754 Lisp_Object frame;
1755 {
1756 return XFRAME (frame)->buffer_predicate;
1757 }
1758
1759 /* Return the buffer-list of the selected frame. */
1760
1761 Lisp_Object
1762 frame_buffer_list (frame)
1763 Lisp_Object frame;
1764 {
1765 return XFRAME (frame)->buffer_list;
1766 }
1767
1768 /* Set the buffer-list of the selected frame. */
1769
1770 void
1771 set_frame_buffer_list (frame, list)
1772 Lisp_Object frame, list;
1773 {
1774 XFRAME (frame)->buffer_list = list;
1775 }
1776
1777 /* Discard BUFFER from the buffer-list of each frame. */
1778
1779 void
1780 frames_discard_buffer (buffer)
1781 Lisp_Object buffer;
1782 {
1783 Lisp_Object frame, tail;
1784
1785 FOR_EACH_FRAME (tail, frame)
1786 {
1787 XFRAME (frame)->buffer_list
1788 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1789 }
1790 }
1791
1792 /* Move BUFFER to the end of the buffer-list of each frame. */
1793
1794 void
1795 frames_bury_buffer (buffer)
1796 Lisp_Object buffer;
1797 {
1798 Lisp_Object frame, tail;
1799
1800 FOR_EACH_FRAME (tail, frame)
1801 {
1802 struct frame *f = XFRAME (frame);
1803 Lisp_Object found;
1804
1805 found = Fmemq (buffer, f->buffer_list);
1806 if (!NILP (found))
1807 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1808 Fcons (buffer, Qnil));
1809 }
1810 }
1811
1812 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1813 If the alist already has an element for PROP, we change it. */
1814
1815 void
1816 store_in_alist (alistptr, prop, val)
1817 Lisp_Object *alistptr, val;
1818 Lisp_Object prop;
1819 {
1820 register Lisp_Object tem;
1821
1822 tem = Fassq (prop, *alistptr);
1823 if (EQ (tem, Qnil))
1824 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1825 else
1826 Fsetcdr (tem, val);
1827 }
1828
1829 static int
1830 frame_name_fnn_p (str, len)
1831 char *str;
1832 int len;
1833 {
1834 if (len > 1 && str[0] == 'F')
1835 {
1836 char *end_ptr;
1837
1838 strtol (str + 1, &end_ptr, 10);
1839
1840 if (end_ptr == str + len)
1841 return 1;
1842 }
1843 return 0;
1844 }
1845
1846 /* Set the name of the terminal frame. Also used by MSDOS frames.
1847 Modeled after x_set_name which is used for WINDOW frames. */
1848
1849 void
1850 set_term_frame_name (f, name)
1851 struct frame *f;
1852 Lisp_Object name;
1853 {
1854 f->explicit_name = ! NILP (name);
1855
1856 /* If NAME is nil, set the name to F<num>. */
1857 if (NILP (name))
1858 {
1859 char namebuf[20];
1860
1861 /* Check for no change needed in this very common case
1862 before we do any consing. */
1863 if (frame_name_fnn_p (XSTRING (f->name)->data,
1864 STRING_BYTES (XSTRING (f->name))))
1865 return;
1866
1867 terminal_frame_count++;
1868 sprintf (namebuf, "F%d", terminal_frame_count);
1869 name = build_string (namebuf);
1870 }
1871 else
1872 {
1873 CHECK_STRING (name, 0);
1874
1875 /* Don't change the name if it's already NAME. */
1876 if (! NILP (Fstring_equal (name, f->name)))
1877 return;
1878
1879 /* Don't allow the user to set the frame name to F<num>, so it
1880 doesn't clash with the names we generate for terminal frames. */
1881 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1882 error ("Frame names of the form F<num> are usurped by Emacs");
1883 }
1884
1885 f->name = name;
1886 update_mode_lines = 1;
1887 }
1888
1889 void
1890 store_frame_param (f, prop, val)
1891 struct frame *f;
1892 Lisp_Object prop, val;
1893 {
1894 register Lisp_Object old_alist_elt;
1895
1896 /* The buffer-alist parameter is stored in a special place and is
1897 not in the alist. */
1898 if (EQ (prop, Qbuffer_list))
1899 {
1900 f->buffer_list = val;
1901 return;
1902 }
1903
1904 /* If PROP is a symbol which is supposed to have frame-local values,
1905 and it is set up based on this frame, switch to the global
1906 binding. That way, we can create or alter the frame-local binding
1907 without messing up the symbol's status. */
1908 if (SYMBOLP (prop))
1909 {
1910 Lisp_Object valcontents;
1911 valcontents = XSYMBOL (prop)->value;
1912 if ((BUFFER_LOCAL_VALUEP (valcontents)
1913 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1914 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1915 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1916 swap_in_global_binding (prop);
1917 }
1918
1919 /* Update the frame parameter alist. */
1920 old_alist_elt = Fassq (prop, f->param_alist);
1921 if (EQ (old_alist_elt, Qnil))
1922 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1923 else
1924 Fsetcdr (old_alist_elt, val);
1925
1926 /* Update some other special parameters in their special places
1927 in addition to the alist. */
1928
1929 if (EQ (prop, Qbuffer_predicate))
1930 f->buffer_predicate = val;
1931
1932 if (! FRAME_WINDOW_P (f))
1933 {
1934 if (EQ (prop, Qmenu_bar_lines))
1935 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1936 else if (EQ (prop, Qname))
1937 set_term_frame_name (f, val);
1938 }
1939
1940 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1941 {
1942 if (! MINI_WINDOW_P (XWINDOW (val)))
1943 error ("Surrogate minibuffer windows must be minibuffer windows.");
1944
1945 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1946 && !EQ (val, f->minibuffer_window))
1947 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1948
1949 /* Install the chosen minibuffer window, with proper buffer. */
1950 f->minibuffer_window = val;
1951 }
1952 }
1953
1954 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1955 "Return the parameters-alist of frame FRAME.\n\
1956 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1957 The meaningful PARMs depend on the kind of frame.\n\
1958 If FRAME is omitted, return information on the currently selected frame.")
1959 (frame)
1960 Lisp_Object frame;
1961 {
1962 Lisp_Object alist;
1963 FRAME_PTR f;
1964 int height, width;
1965 struct gcpro gcpro1;
1966
1967 if (NILP (frame))
1968 frame = selected_frame;
1969
1970 CHECK_FRAME (frame, 0);
1971 f = XFRAME (frame);
1972
1973 if (!FRAME_LIVE_P (f))
1974 return Qnil;
1975
1976 alist = Fcopy_alist (f->param_alist);
1977 GCPRO1 (alist);
1978
1979 if (!FRAME_WINDOW_P (f))
1980 {
1981 int fg = FRAME_FOREGROUND_PIXEL (f);
1982 int bg = FRAME_BACKGROUND_PIXEL (f);
1983 Lisp_Object elt;
1984
1985 /* If the frame's parameter alist says the colors are
1986 unspecified and reversed, take the frame's background pixel
1987 for foreground and vice versa. */
1988 elt = Fassq (Qforeground_color, alist);
1989 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
1990 {
1991 if (strncmp (XSTRING (XCDR (elt))->data,
1992 unspecified_bg,
1993 XSTRING (XCDR (elt))->size) == 0)
1994 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
1995 else if (strncmp (XSTRING (XCDR (elt))->data,
1996 unspecified_fg,
1997 XSTRING (XCDR (elt))->size) == 0)
1998 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
1999 }
2000 else
2001 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2002 elt = Fassq (Qbackground_color, alist);
2003 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2004 {
2005 if (strncmp (XSTRING (XCDR (elt))->data,
2006 unspecified_fg,
2007 XSTRING (XCDR (elt))->size) == 0)
2008 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2009 else if (strncmp (XSTRING (XCDR (elt))->data,
2010 unspecified_bg,
2011 XSTRING (XCDR (elt))->size) == 0)
2012 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2013 }
2014 else
2015 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2016 store_in_alist (&alist, intern ("font"),
2017 build_string (FRAME_MSDOS_P (f)
2018 ? "ms-dos"
2019 : FRAME_W32_P (f) ? "w32term"
2020 :"tty"));
2021 }
2022 store_in_alist (&alist, Qname, f->name);
2023 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2024 store_in_alist (&alist, Qheight, make_number (height));
2025 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2026 store_in_alist (&alist, Qwidth, make_number (width));
2027 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2028 store_in_alist (&alist, Qminibuffer,
2029 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2030 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2031 : FRAME_MINIBUF_WINDOW (f)));
2032 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2033 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
2034
2035 /* I think this should be done with a hook. */
2036 #ifdef HAVE_WINDOW_SYSTEM
2037 if (FRAME_WINDOW_P (f))
2038 x_report_frame_params (f, &alist);
2039 else
2040 #endif
2041 {
2042 /* This ought to be correct in f->param_alist for an X frame. */
2043 Lisp_Object lines;
2044 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2045 store_in_alist (&alist, Qmenu_bar_lines, lines);
2046 }
2047
2048 UNGCPRO;
2049 return alist;
2050 }
2051
2052
2053 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2054 "Return FRAME's value for parameter PARAMETER.\n\
2055 If FRAME is nil, describe the currently selected frame.")
2056 (frame, parameter)
2057 Lisp_Object frame, parameter;
2058 {
2059 struct frame *f;
2060 Lisp_Object value;
2061
2062 if (NILP (frame))
2063 frame = selected_frame;
2064 else
2065 CHECK_FRAME (frame, 0);
2066 CHECK_SYMBOL (parameter, 1);
2067
2068 f = XFRAME (frame);
2069 value = Qnil;
2070
2071 if (FRAME_LIVE_P (f))
2072 {
2073 if (EQ (parameter, Qname))
2074 value = f->name;
2075 #ifdef HAVE_X_WINDOWS
2076 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2077 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2078 #endif /* HAVE_X_WINDOWS */
2079 else
2080 {
2081 value = Fassq (parameter, f->param_alist);
2082 if (CONSP (value))
2083 {
2084 value = XCDR (value);
2085 /* Fframe_parameters puts the actual fg/bg color names,
2086 even if f->param_alist says otherwise. This is
2087 important when param_alist's notion of colors is
2088 "unspecified". We need to do the same here. */
2089 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2090 {
2091 char *color_name;
2092 EMACS_INT csz;
2093
2094 if (EQ (parameter, Qbackground_color))
2095 {
2096 color_name = XSTRING (value)->data;
2097 csz = XSTRING (value)->size;
2098 if (strncmp (color_name, unspecified_bg, csz) == 0)
2099 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2100 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2101 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2102 }
2103 else if (EQ (parameter, Qforeground_color))
2104 {
2105 color_name = XSTRING (value)->data;
2106 csz = XSTRING (value)->size;
2107 if (strncmp (color_name, unspecified_fg, csz) == 0)
2108 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2109 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2110 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2111 }
2112 }
2113 }
2114 else if (EQ (parameter, Qdisplay_type)
2115 || EQ (parameter, Qbackground_mode))
2116 /* Avoid consing in frequent cases. */
2117 value = Qnil;
2118 else
2119 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2120 }
2121 }
2122
2123 return value;
2124 }
2125
2126
2127 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2128 Smodify_frame_parameters, 2, 2, 0,
2129 "Modify the parameters of frame FRAME according to ALIST.\n\
2130 If FRAME is nil, it defaults to the selected frame.\n\
2131 ALIST is an alist of parameters to change and their new values.\n\
2132 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2133 The meaningful PARMs depend on the kind of frame.\n\
2134 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2135 so that `frame-parameters' will return them.\n\
2136 \n\
2137 The value of frame parameter FOO can also be accessed\n\
2138 as a frame-local binding for the variable FOO, if you have\n\
2139 enabled such bindings for that variable with `make-variable-frame-local'.")
2140 (frame, alist)
2141 Lisp_Object frame, alist;
2142 {
2143 FRAME_PTR f;
2144 register Lisp_Object tail, prop, val;
2145 int count = BINDING_STACK_SIZE ();
2146
2147 /* Bind this to t to inhibit initialization of the default face from
2148 X resources in face-set-after-frame-default. If we don't inhibit
2149 this, modifying the `font' frame parameter, for example, while
2150 there is a `default.attributeFont' X resource, won't work,
2151 because `default's font is reset to the value of the X resource
2152 and that resets the `font' frame parameter. */
2153 specbind (Qinhibit_default_face_x_resources, Qt);
2154
2155 if (EQ (frame, Qnil))
2156 frame = selected_frame;
2157 CHECK_LIVE_FRAME (frame, 0);
2158 f = XFRAME (frame);
2159
2160 /* I think this should be done with a hook. */
2161 #ifdef HAVE_WINDOW_SYSTEM
2162 if (FRAME_WINDOW_P (f))
2163 x_set_frame_parameters (f, alist);
2164 else
2165 #endif
2166 #ifdef MSDOS
2167 if (FRAME_MSDOS_P (f))
2168 IT_set_frame_parameters (f, alist);
2169 else
2170 #endif
2171
2172 {
2173 int length = XINT (Flength (alist));
2174 int i;
2175 Lisp_Object *parms
2176 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2177 Lisp_Object *values
2178 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2179
2180 /* Extract parm names and values into those vectors. */
2181
2182 i = 0;
2183 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2184 {
2185 Lisp_Object elt;
2186
2187 elt = Fcar (tail);
2188 parms[i] = Fcar (elt);
2189 values[i] = Fcdr (elt);
2190 i++;
2191 }
2192
2193 /* Now process them in reverse of specified order. */
2194 for (i--; i >= 0; i--)
2195 {
2196 prop = parms[i];
2197 val = values[i];
2198 store_frame_param (f, prop, val);
2199 }
2200 }
2201
2202 return unbind_to (count, Qnil);
2203 }
2204 \f
2205 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2206 0, 1, 0,
2207 "Height in pixels of a line in the font in frame FRAME.\n\
2208 If FRAME is omitted, the selected frame is used.\n\
2209 For a terminal frame, the value is always 1.")
2210 (frame)
2211 Lisp_Object frame;
2212 {
2213 struct frame *f;
2214
2215 if (NILP (frame))
2216 frame = selected_frame;
2217 CHECK_FRAME (frame, 0);
2218 f = XFRAME (frame);
2219
2220 #ifdef HAVE_WINDOW_SYSTEM
2221 if (FRAME_WINDOW_P (f))
2222 return make_number (x_char_height (f));
2223 else
2224 #endif
2225 return make_number (1);
2226 }
2227
2228
2229 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2230 0, 1, 0,
2231 "Width in pixels of characters in the font in frame FRAME.\n\
2232 If FRAME is omitted, the selected frame is used.\n\
2233 The width is the same for all characters, because\n\
2234 currently Emacs supports only fixed-width fonts.\n\
2235 For a terminal screen, the value is always 1.")
2236 (frame)
2237 Lisp_Object frame;
2238 {
2239 struct frame *f;
2240
2241 if (NILP (frame))
2242 frame = selected_frame;
2243 CHECK_FRAME (frame, 0);
2244 f = XFRAME (frame);
2245
2246 #ifdef HAVE_WINDOW_SYSTEM
2247 if (FRAME_WINDOW_P (f))
2248 return make_number (x_char_width (f));
2249 else
2250 #endif
2251 return make_number (1);
2252 }
2253
2254 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2255 Sframe_pixel_height, 0, 1, 0,
2256 "Return a FRAME's height in pixels.\n\
2257 This counts only the height available for text lines,\n\
2258 not menu bars on window-system Emacs frames.\n\
2259 For a terminal frame, the result really gives the height in characters.\n\
2260 If FRAME is omitted, the selected frame is used.")
2261 (frame)
2262 Lisp_Object frame;
2263 {
2264 struct frame *f;
2265
2266 if (NILP (frame))
2267 frame = selected_frame;
2268 CHECK_FRAME (frame, 0);
2269 f = XFRAME (frame);
2270
2271 #ifdef HAVE_WINDOW_SYSTEM
2272 if (FRAME_WINDOW_P (f))
2273 return make_number (x_pixel_height (f));
2274 else
2275 #endif
2276 return make_number (FRAME_HEIGHT (f));
2277 }
2278
2279 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2280 Sframe_pixel_width, 0, 1, 0,
2281 "Return FRAME's width in pixels.\n\
2282 For a terminal frame, the result really gives the width in characters.\n\
2283 If FRAME is omitted, the selected frame is used.")
2284 (frame)
2285 Lisp_Object frame;
2286 {
2287 struct frame *f;
2288
2289 if (NILP (frame))
2290 frame = selected_frame;
2291 CHECK_FRAME (frame, 0);
2292 f = XFRAME (frame);
2293
2294 #ifdef HAVE_WINDOW_SYSTEM
2295 if (FRAME_WINDOW_P (f))
2296 return make_number (x_pixel_width (f));
2297 else
2298 #endif
2299 return make_number (FRAME_WIDTH (f));
2300 }
2301 \f
2302 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2303 "Specify that the frame FRAME has LINES lines.\n\
2304 Optional third arg non-nil means that redisplay should use LINES lines\n\
2305 but that the idea of the actual height of the frame should not be changed.")
2306 (frame, lines, pretend)
2307 Lisp_Object frame, lines, pretend;
2308 {
2309 register struct frame *f;
2310
2311 CHECK_NUMBER (lines, 0);
2312 if (NILP (frame))
2313 frame = selected_frame;
2314 CHECK_LIVE_FRAME (frame, 0);
2315 f = XFRAME (frame);
2316
2317 /* I think this should be done with a hook. */
2318 #ifdef HAVE_WINDOW_SYSTEM
2319 if (FRAME_WINDOW_P (f))
2320 {
2321 if (XINT (lines) != f->height)
2322 x_set_window_size (f, 1, f->width, XINT (lines));
2323 do_pending_window_change (0);
2324 }
2325 else
2326 #endif
2327 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2328 return Qnil;
2329 }
2330
2331 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2332 "Specify that the frame FRAME has COLS columns.\n\
2333 Optional third arg non-nil means that redisplay should use COLS columns\n\
2334 but that the idea of the actual width of the frame should not be changed.")
2335 (frame, cols, pretend)
2336 Lisp_Object frame, cols, pretend;
2337 {
2338 register struct frame *f;
2339 CHECK_NUMBER (cols, 0);
2340 if (NILP (frame))
2341 frame = selected_frame;
2342 CHECK_LIVE_FRAME (frame, 0);
2343 f = XFRAME (frame);
2344
2345 /* I think this should be done with a hook. */
2346 #ifdef HAVE_WINDOW_SYSTEM
2347 if (FRAME_WINDOW_P (f))
2348 {
2349 if (XINT (cols) != f->width)
2350 x_set_window_size (f, 1, XINT (cols), f->height);
2351 do_pending_window_change (0);
2352 }
2353 else
2354 #endif
2355 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2356 return Qnil;
2357 }
2358
2359 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2360 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2361 (frame, cols, rows)
2362 Lisp_Object frame, cols, rows;
2363 {
2364 register struct frame *f;
2365
2366 CHECK_LIVE_FRAME (frame, 0);
2367 CHECK_NUMBER (cols, 2);
2368 CHECK_NUMBER (rows, 1);
2369 f = XFRAME (frame);
2370
2371 /* I think this should be done with a hook. */
2372 #ifdef HAVE_WINDOW_SYSTEM
2373 if (FRAME_WINDOW_P (f))
2374 {
2375 if (XINT (rows) != f->height || XINT (cols) != f->width
2376 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2377 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2378 do_pending_window_change (0);
2379 }
2380 else
2381 #endif
2382 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2383
2384 return Qnil;
2385 }
2386
2387 DEFUN ("set-frame-position", Fset_frame_position,
2388 Sset_frame_position, 3, 3, 0,
2389 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2390 This is actually the position of the upper left corner of the frame.\n\
2391 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2392 the rightmost or bottommost possible position (that stays within the screen).")
2393 (frame, xoffset, yoffset)
2394 Lisp_Object frame, xoffset, yoffset;
2395 {
2396 register struct frame *f;
2397
2398 CHECK_LIVE_FRAME (frame, 0);
2399 CHECK_NUMBER (xoffset, 1);
2400 CHECK_NUMBER (yoffset, 2);
2401 f = XFRAME (frame);
2402
2403 /* I think this should be done with a hook. */
2404 #ifdef HAVE_WINDOW_SYSTEM
2405 if (FRAME_WINDOW_P (f))
2406 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2407 #endif
2408
2409 return Qt;
2410 }
2411
2412 \f
2413 void
2414 syms_of_frame ()
2415 {
2416 Qframep = intern ("framep");
2417 staticpro (&Qframep);
2418 Qframe_live_p = intern ("frame-live-p");
2419 staticpro (&Qframe_live_p);
2420 Qheight = intern ("height");
2421 staticpro (&Qheight);
2422 Qicon = intern ("icon");
2423 staticpro (&Qicon);
2424 Qminibuffer = intern ("minibuffer");
2425 staticpro (&Qminibuffer);
2426 Qmodeline = intern ("modeline");
2427 staticpro (&Qmodeline);
2428 Qname = intern ("name");
2429 staticpro (&Qname);
2430 Qonly = intern ("only");
2431 staticpro (&Qonly);
2432 Qunsplittable = intern ("unsplittable");
2433 staticpro (&Qunsplittable);
2434 Qmenu_bar_lines = intern ("menu-bar-lines");
2435 staticpro (&Qmenu_bar_lines);
2436 Qtool_bar_lines = intern ("tool-bar-lines");
2437 staticpro (&Qtool_bar_lines);
2438 Qwidth = intern ("width");
2439 staticpro (&Qwidth);
2440 Qx = intern ("x");
2441 staticpro (&Qx);
2442 Qw32 = intern ("w32");
2443 staticpro (&Qw32);
2444 Qpc = intern ("pc");
2445 staticpro (&Qpc);
2446 Qmac = intern ("mac");
2447 staticpro (&Qmac);
2448 Qvisible = intern ("visible");
2449 staticpro (&Qvisible);
2450 Qbuffer_predicate = intern ("buffer-predicate");
2451 staticpro (&Qbuffer_predicate);
2452 Qbuffer_list = intern ("buffer-list");
2453 staticpro (&Qbuffer_list);
2454 Qtitle = intern ("title");
2455 staticpro (&Qtitle);
2456 Qdisplay_type = intern ("display-type");
2457 staticpro (&Qdisplay_type);
2458 Qbackground_mode = intern ("background-mode");
2459 staticpro (&Qbackground_mode);
2460
2461 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
2462 "Alist of default values for frame creation.\n\
2463 These may be set in your init file, like this:\n\
2464 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
2465 These override values given in window system configuration data,\n\
2466 including X Windows' defaults database.\n\
2467 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
2468 For values specific to the separate minibuffer frame, see\n\
2469 `minibuffer-frame-alist'.\n\
2470 The `menu-bar-lines' element of the list controls whether new frames\n\
2471 have menu bars; `menu-bar-mode' works by altering this element.");
2472 Vdefault_frame_alist = Qnil;
2473
2474 Qinhibit_default_face_x_resources
2475 = intern ("inhibit-default-face-x-resources");
2476 staticpro (&Qinhibit_default_face_x_resources);
2477
2478 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2479 "The initial frame-object, which represents Emacs's stdout.");
2480
2481 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2482 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2483 Vemacs_iconified = Qnil;
2484
2485 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
2486 "If non-nil, function applied to the normal result of `mouse-position'.\n\
2487 This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
2488 which need to do mouse handling at the Lisp level.");
2489 Vmouse_position_function = Qnil;
2490
2491 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2492 "Minibufferless frames use this frame's minibuffer.\n\
2493 \n\
2494 Emacs cannot create minibufferless frames unless this is set to an\n\
2495 appropriate surrogate.\n\
2496 \n\
2497 Emacs consults this variable only when creating minibufferless\n\
2498 frames; once the frame is created, it sticks with its assigned\n\
2499 minibuffer, no matter what this variable is set to. This means that\n\
2500 this variable doesn't necessarily say anything meaningful about the\n\
2501 current set of frames, or where the minibuffer is currently being\n\
2502 displayed.");
2503
2504 staticpro (&Vframe_list);
2505
2506 defsubr (&Sactive_minibuffer_window);
2507 defsubr (&Sframep);
2508 defsubr (&Sframe_live_p);
2509 defsubr (&Smake_terminal_frame);
2510 defsubr (&Shandle_switch_frame);
2511 defsubr (&Signore_event);
2512 defsubr (&Sselect_frame);
2513 defsubr (&Sselected_frame);
2514 defsubr (&Swindow_frame);
2515 defsubr (&Sframe_root_window);
2516 defsubr (&Sframe_first_window);
2517 defsubr (&Sframe_selected_window);
2518 defsubr (&Sset_frame_selected_window);
2519 defsubr (&Sframe_list);
2520 defsubr (&Snext_frame);
2521 defsubr (&Sprevious_frame);
2522 defsubr (&Sdelete_frame);
2523 defsubr (&Smouse_position);
2524 defsubr (&Smouse_pixel_position);
2525 defsubr (&Sset_mouse_position);
2526 defsubr (&Sset_mouse_pixel_position);
2527 #if 0
2528 defsubr (&Sframe_configuration);
2529 defsubr (&Srestore_frame_configuration);
2530 #endif
2531 defsubr (&Smake_frame_visible);
2532 defsubr (&Smake_frame_invisible);
2533 defsubr (&Siconify_frame);
2534 defsubr (&Sframe_visible_p);
2535 defsubr (&Svisible_frame_list);
2536 defsubr (&Sraise_frame);
2537 defsubr (&Slower_frame);
2538 defsubr (&Sredirect_frame_focus);
2539 defsubr (&Sframe_focus);
2540 defsubr (&Sframe_parameters);
2541 defsubr (&Sframe_parameter);
2542 defsubr (&Smodify_frame_parameters);
2543 defsubr (&Sframe_char_height);
2544 defsubr (&Sframe_char_width);
2545 defsubr (&Sframe_pixel_height);
2546 defsubr (&Sframe_pixel_width);
2547 defsubr (&Sset_frame_height);
2548 defsubr (&Sset_frame_width);
2549 defsubr (&Sset_frame_size);
2550 defsubr (&Sset_frame_position);
2551 }
2552
2553 void
2554 keys_of_frame ()
2555 {
2556 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2557 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2558 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2559 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2560 }