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