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