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