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