]> code.delx.au - gnu-emacs/blob - src/frame.c
(sync_frame_with_window_matrix_rows): Disable frame rows
[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 if (NILP (frame))
1050 frame = selected_frame;
1051
1052 CHECK_LIVE_FRAME (frame, 0);
1053 return next_frame (frame, miniframe);
1054 }
1055
1056 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1057 "Return the previous frame in the frame list before FRAME.\n\
1058 It considers only frames on the same terminal as FRAME.\n\
1059 By default, skip minibuffer-only frames.\n\
1060 If omitted, FRAME defaults to the selected frame.\n\
1061 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
1062 If MINIFRAME is a window, include only its own frame\n\
1063 and any frame now using that window as the minibuffer.\n\
1064 If MINIFRAME is `visible', include all visible frames.\n\
1065 If MINIFRAME is 0, include all visible and iconified frames.\n\
1066 Otherwise, include all frames.")
1067 (frame, miniframe)
1068 Lisp_Object frame, miniframe;
1069 {
1070 if (NILP (frame))
1071 frame = selected_frame;
1072 CHECK_LIVE_FRAME (frame, 0);
1073 return prev_frame (frame, miniframe);
1074 }
1075 \f
1076 /* Return 1 if it is ok to delete frame F;
1077 0 if all frames aside from F are invisible.
1078 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1079
1080 int
1081 other_visible_frames (f)
1082 FRAME_PTR f;
1083 {
1084 /* We know the selected frame is visible,
1085 so if F is some other frame, it can't be the sole visible one. */
1086 if (f == SELECTED_FRAME ())
1087 {
1088 Lisp_Object frames;
1089 int count = 0;
1090
1091 for (frames = Vframe_list;
1092 CONSP (frames);
1093 frames = XCONS (frames)->cdr)
1094 {
1095 Lisp_Object this;
1096
1097 this = XCONS (frames)->car;
1098 /* Verify that the frame's window still exists
1099 and we can still talk to it. And note any recent change
1100 in visibility. */
1101 #ifdef HAVE_WINDOW_SYSTEM
1102 if (FRAME_WINDOW_P (XFRAME (this)))
1103 {
1104 x_sync (XFRAME (this));
1105 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1106 }
1107 #endif
1108
1109 if (FRAME_VISIBLE_P (XFRAME (this))
1110 || FRAME_ICONIFIED_P (XFRAME (this))
1111 /* Allow deleting the terminal frame when at least
1112 one X frame exists! */
1113 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1114 count++;
1115 }
1116 return count > 1;
1117 }
1118 return 1;
1119 }
1120
1121 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1122 "Delete FRAME, permanently eliminating it from use.\n\
1123 If omitted, FRAME defaults to the selected frame.\n\
1124 A frame may not be deleted if its minibuffer is used by other frames.\n\
1125 Normally, you may not delete a frame if all other frames are invisible,\n\
1126 but if the second optional argument FORCE is non-nil, you may do so.")
1127 (frame, force)
1128 Lisp_Object frame, force;
1129 {
1130 struct frame *f;
1131 struct frame *sf = SELECTED_FRAME ();
1132 int minibuffer_selected;
1133
1134 if (EQ (frame, Qnil))
1135 {
1136 f = sf;
1137 XSETFRAME (frame, f);
1138 }
1139 else
1140 {
1141 CHECK_FRAME (frame, 0);
1142 f = XFRAME (frame);
1143 }
1144
1145 if (! FRAME_LIVE_P (f))
1146 return Qnil;
1147
1148 if (NILP (force) && !other_visible_frames (f))
1149 error ("Attempt to delete the sole visible or iconified frame");
1150
1151 #if 0
1152 /* This is a nice idea, but x_connection_closed needs to be able
1153 to delete the last frame, if it is gone. */
1154 if (NILP (XCONS (Vframe_list)->cdr))
1155 error ("Attempt to delete the only frame");
1156 #endif
1157
1158 /* Does this frame have a minibuffer, and is it the surrogate
1159 minibuffer for any other frame? */
1160 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1161 {
1162 Lisp_Object frames;
1163
1164 for (frames = Vframe_list;
1165 CONSP (frames);
1166 frames = XCONS (frames)->cdr)
1167 {
1168 Lisp_Object this;
1169 this = XCONS (frames)->car;
1170
1171 if (! EQ (this, frame)
1172 && EQ (frame,
1173 WINDOW_FRAME (XWINDOW
1174 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1175 error ("Attempt to delete a surrogate minibuffer frame");
1176 }
1177 }
1178
1179 minibuffer_selected = EQ (minibuf_window, selected_window);
1180
1181 /* Don't let the frame remain selected. */
1182 if (f == sf)
1183 {
1184 Lisp_Object tail, frame1;
1185
1186 /* Look for another visible frame on the same terminal. */
1187 frame1 = next_frame (frame, Qvisible);
1188
1189 /* If there is none, find *some* other frame. */
1190 if (NILP (frame1) || EQ (frame1, frame))
1191 {
1192 FOR_EACH_FRAME (tail, frame1)
1193 {
1194 if (! EQ (frame, frame1))
1195 break;
1196 }
1197 }
1198
1199 do_switch_frame (frame1, Qnil, 0);
1200 sf = SELECTED_FRAME ();
1201 }
1202
1203 /* Don't allow minibuf_window to remain on a deleted frame. */
1204 if (EQ (f->minibuffer_window, minibuf_window))
1205 {
1206 Fset_window_buffer (sf->minibuffer_window,
1207 XWINDOW (minibuf_window)->buffer);
1208 minibuf_window = sf->minibuffer_window;
1209
1210 /* If the dying minibuffer window was selected,
1211 select the new one. */
1212 if (minibuffer_selected)
1213 Fselect_window (minibuf_window);
1214 }
1215
1216 /* Clear any X selections for this frame. */
1217 #ifdef HAVE_X_WINDOWS
1218 if (FRAME_X_P (f))
1219 x_clear_frame_selections (f);
1220 #endif
1221
1222 /* Free glyphs.
1223 This function must be called before the window tree of the
1224 frame is deleted because windows contain dynamically allocated
1225 memory. */
1226 free_glyphs (f);
1227
1228 /* Mark all the windows that used to be on FRAME as deleted, and then
1229 remove the reference to them. */
1230 delete_all_subwindows (XWINDOW (f->root_window));
1231 f->root_window = Qnil;
1232
1233 Vframe_list = Fdelq (frame, Vframe_list);
1234 FRAME_SET_VISIBLE (f, 0);
1235
1236 if (f->namebuf)
1237 xfree (f->namebuf);
1238 if (FRAME_INSERT_COST (f))
1239 xfree (FRAME_INSERT_COST (f));
1240 if (FRAME_DELETEN_COST (f))
1241 xfree (FRAME_DELETEN_COST (f));
1242 if (FRAME_INSERTN_COST (f))
1243 xfree (FRAME_INSERTN_COST (f));
1244 if (FRAME_DELETE_COST (f))
1245 xfree (FRAME_DELETE_COST (f));
1246 if (FRAME_MESSAGE_BUF (f))
1247 xfree (FRAME_MESSAGE_BUF (f));
1248
1249 #ifdef HAVE_WINDOW_SYSTEM
1250 /* Free all fontset data. */
1251 free_fontset_data (FRAME_FONTSET_DATA (f));
1252 #endif
1253
1254 /* Since some events are handled at the interrupt level, we may get
1255 an event for f at any time; if we zero out the frame's display
1256 now, then we may trip up the event-handling code. Instead, we'll
1257 promise that the display of the frame must be valid until we have
1258 called the window-system-dependent frame destruction routine. */
1259
1260 /* I think this should be done with a hook. */
1261 #ifdef HAVE_WINDOW_SYSTEM
1262 if (FRAME_WINDOW_P (f))
1263 x_destroy_window (f);
1264 #endif
1265
1266 /* Done by x_destroy_window above already */
1267 #if 0
1268 #ifdef macintosh
1269 if (FRAME_MAC_P (f))
1270 DisposeMacWindow (f->output_data.mac);
1271 #endif
1272 #endif
1273
1274 f->output_data.nothing = 0;
1275
1276 /* If we've deleted the last_nonminibuf_frame, then try to find
1277 another one. */
1278 if (f == last_nonminibuf_frame)
1279 {
1280 Lisp_Object frames;
1281
1282 last_nonminibuf_frame = 0;
1283
1284 for (frames = Vframe_list;
1285 CONSP (frames);
1286 frames = XCONS (frames)->cdr)
1287 {
1288 f = XFRAME (XCONS (frames)->car);
1289 if (!FRAME_MINIBUF_ONLY_P (f))
1290 {
1291 last_nonminibuf_frame = f;
1292 break;
1293 }
1294 }
1295 }
1296
1297 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1298 find another one. Prefer minibuffer-only frames, but also notice
1299 frames with other windows. */
1300 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1301 {
1302 Lisp_Object frames;
1303
1304 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1305 Lisp_Object frame_with_minibuf;
1306 /* Some frame we found on the same kboard, or nil if there are none. */
1307 Lisp_Object frame_on_same_kboard;
1308
1309 frame_on_same_kboard = Qnil;
1310 frame_with_minibuf = Qnil;
1311
1312 for (frames = Vframe_list;
1313 CONSP (frames);
1314 frames = XCONS (frames)->cdr)
1315 {
1316 Lisp_Object this;
1317 struct frame *f1;
1318
1319 this = XCONS (frames)->car;
1320 if (!FRAMEP (this))
1321 abort ();
1322 f1 = XFRAME (this);
1323
1324 /* Consider only frames on the same kboard
1325 and only those with minibuffers. */
1326 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1327 && FRAME_HAS_MINIBUF_P (f1))
1328 {
1329 frame_with_minibuf = this;
1330 if (FRAME_MINIBUF_ONLY_P (f1))
1331 break;
1332 }
1333
1334 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1335 frame_on_same_kboard = this;
1336 }
1337
1338 if (!NILP (frame_on_same_kboard))
1339 {
1340 /* We know that there must be some frame with a minibuffer out
1341 there. If this were not true, all of the frames present
1342 would have to be minibufferless, which implies that at some
1343 point their minibuffer frames must have been deleted, but
1344 that is prohibited at the top; you can't delete surrogate
1345 minibuffer frames. */
1346 if (NILP (frame_with_minibuf))
1347 abort ();
1348
1349 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1350 }
1351 else
1352 /* No frames left on this kboard--say no minibuffer either. */
1353 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1354 }
1355
1356 /* Cause frame titles to update--necessary if we now have just one frame. */
1357 update_mode_lines = 1;
1358
1359 return Qnil;
1360 }
1361 \f
1362 /* Return mouse position in character cell units. */
1363
1364 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1365 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1366 The position is given in character cells, where (0, 0) is the\n\
1367 upper-left corner.\n\
1368 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1369 to read the mouse position, it returns the selected frame for FRAME\n\
1370 and nil for X and Y.")
1371 ()
1372 {
1373 FRAME_PTR f;
1374 Lisp_Object lispy_dummy;
1375 enum scroll_bar_part party_dummy;
1376 Lisp_Object x, y;
1377 int col, row;
1378 unsigned long long_dummy;
1379
1380 f = SELECTED_FRAME ();
1381 x = y = Qnil;
1382
1383 #ifdef HAVE_MOUSE
1384 /* It's okay for the hook to refrain from storing anything. */
1385 if (mouse_position_hook)
1386 (*mouse_position_hook) (&f, -1,
1387 &lispy_dummy, &party_dummy,
1388 &x, &y,
1389 &long_dummy);
1390 if (! NILP (x))
1391 {
1392 col = XINT (x);
1393 row = XINT (y);
1394 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1395 XSETINT (x, col);
1396 XSETINT (y, row);
1397 }
1398 #endif
1399 XSETFRAME (lispy_dummy, f);
1400 return Fcons (lispy_dummy, Fcons (x, y));
1401 }
1402
1403 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1404 Smouse_pixel_position, 0, 0, 0,
1405 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1406 The position is given in pixel units, where (0, 0) is the\n\
1407 upper-left corner.\n\
1408 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1409 to read the mouse position, it returns the selected frame for FRAME\n\
1410 and nil for X and Y.")
1411 ()
1412 {
1413 FRAME_PTR f;
1414 Lisp_Object lispy_dummy;
1415 enum scroll_bar_part party_dummy;
1416 Lisp_Object x, y;
1417 unsigned long long_dummy;
1418
1419 f = SELECTED_FRAME ();
1420 x = y = Qnil;
1421
1422 #ifdef HAVE_MOUSE
1423 /* It's okay for the hook to refrain from storing anything. */
1424 if (mouse_position_hook)
1425 (*mouse_position_hook) (&f, -1,
1426 &lispy_dummy, &party_dummy,
1427 &x, &y,
1428 &long_dummy);
1429 #endif
1430 XSETFRAME (lispy_dummy, f);
1431 return Fcons (lispy_dummy, Fcons (x, y));
1432 }
1433
1434 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1435 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1436 Coordinates are relative to the frame, not a window,\n\
1437 so the coordinates of the top left character in the frame\n\
1438 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1439 \n\
1440 This function is a no-op for an X frame that is not visible.\n\
1441 If you have just created a frame, you must wait for it to become visible\n\
1442 before calling this function on it, like this.\n\
1443 (while (not (frame-visible-p frame)) (sleep-for .5))")
1444 (frame, x, y)
1445 Lisp_Object frame, x, y;
1446 {
1447 CHECK_LIVE_FRAME (frame, 0);
1448 CHECK_NUMBER (x, 2);
1449 CHECK_NUMBER (y, 1);
1450
1451 /* I think this should be done with a hook. */
1452 #ifdef HAVE_WINDOW_SYSTEM
1453 if (FRAME_WINDOW_P (XFRAME (frame)))
1454 /* Warping the mouse will cause enternotify and focus events. */
1455 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1456 #else
1457 #if defined (MSDOS) && defined (HAVE_MOUSE)
1458 if (FRAME_MSDOS_P (XFRAME (frame)))
1459 {
1460 Fselect_frame (frame, Qnil);
1461 mouse_moveto (XINT (x), XINT (y));
1462 }
1463 #endif
1464 #endif
1465
1466 return Qnil;
1467 }
1468
1469 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1470 Sset_mouse_pixel_position, 3, 3, 0,
1471 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1472 Note, this is a no-op for an X frame that is not visible.\n\
1473 If you have just created a frame, you must wait for it to become visible\n\
1474 before calling this function on it, like this.\n\
1475 (while (not (frame-visible-p frame)) (sleep-for .5))")
1476 (frame, x, y)
1477 Lisp_Object frame, x, y;
1478 {
1479 CHECK_LIVE_FRAME (frame, 0);
1480 CHECK_NUMBER (x, 2);
1481 CHECK_NUMBER (y, 1);
1482
1483 /* I think this should be done with a hook. */
1484 #ifdef HAVE_WINDOW_SYSTEM
1485 if (FRAME_WINDOW_P (XFRAME (frame)))
1486 /* Warping the mouse will cause enternotify and focus events. */
1487 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1488 #else
1489 #if defined (MSDOS) && defined (HAVE_MOUSE)
1490 if (FRAME_MSDOS_P (XFRAME (frame)))
1491 {
1492 Fselect_frame (frame, Qnil);
1493 mouse_moveto (XINT (x), XINT (y));
1494 }
1495 #endif
1496 #endif
1497
1498 return Qnil;
1499 }
1500 \f
1501 static void make_frame_visible_1 P_ ((Lisp_Object));
1502
1503 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1504 0, 1, "",
1505 "Make the frame FRAME visible (assuming it is an X-window).\n\
1506 If omitted, FRAME defaults to the currently selected frame.")
1507 (frame)
1508 Lisp_Object frame;
1509 {
1510 if (NILP (frame))
1511 frame = selected_frame;
1512
1513 CHECK_LIVE_FRAME (frame, 0);
1514
1515 /* I think this should be done with a hook. */
1516 #ifdef HAVE_WINDOW_SYSTEM
1517 if (FRAME_WINDOW_P (XFRAME (frame)))
1518 {
1519 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1520 x_make_frame_visible (XFRAME (frame));
1521 }
1522 #endif
1523
1524 make_frame_visible_1 (XFRAME (frame)->root_window);
1525
1526 /* Make menu bar update for the Buffers and Frams menus. */
1527 windows_or_buffers_changed++;
1528
1529 return frame;
1530 }
1531
1532 /* Update the display_time slot of the buffers shown in WINDOW
1533 and all its descendents. */
1534
1535 static void
1536 make_frame_visible_1 (window)
1537 Lisp_Object window;
1538 {
1539 struct window *w;
1540
1541 for (;!NILP (window); window = w->next)
1542 {
1543 w = XWINDOW (window);
1544
1545 if (!NILP (w->buffer))
1546 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1547
1548 if (!NILP (w->vchild))
1549 make_frame_visible_1 (w->vchild);
1550 if (!NILP (w->hchild))
1551 make_frame_visible_1 (w->hchild);
1552 }
1553 }
1554
1555 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1556 0, 2, "",
1557 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1558 If omitted, FRAME defaults to the currently selected frame.\n\
1559 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1560 but if the second optional argument FORCE is non-nil, you may do so.")
1561 (frame, force)
1562 Lisp_Object frame, force;
1563 {
1564 if (NILP (frame))
1565 frame = selected_frame;
1566
1567 CHECK_LIVE_FRAME (frame, 0);
1568
1569 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1570 error ("Attempt to make invisible the sole visible or iconified frame");
1571
1572 #if 0 /* This isn't logically necessary, and it can do GC. */
1573 /* Don't let the frame remain selected. */
1574 if (EQ (frame, selected_frame))
1575 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1576 #endif
1577
1578 /* Don't allow minibuf_window to remain on a deleted frame. */
1579 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1580 {
1581 struct frame *sf = XFRAME (selected_frame);
1582 Fset_window_buffer (sf->minibuffer_window,
1583 XWINDOW (minibuf_window)->buffer);
1584 minibuf_window = sf->minibuffer_window;
1585 }
1586
1587 /* I think this should be done with a hook. */
1588 #ifdef HAVE_WINDOW_SYSTEM
1589 if (FRAME_WINDOW_P (XFRAME (frame)))
1590 x_make_frame_invisible (XFRAME (frame));
1591 #endif
1592
1593 /* Make menu bar update for the Buffers and Frams menus. */
1594 windows_or_buffers_changed++;
1595
1596 return Qnil;
1597 }
1598
1599 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1600 0, 1, "",
1601 "Make the frame FRAME into an icon.\n\
1602 If omitted, FRAME defaults to the currently selected frame.")
1603 (frame)
1604 Lisp_Object frame;
1605 {
1606 if (NILP (frame))
1607 frame = selected_frame;
1608
1609 CHECK_LIVE_FRAME (frame, 0);
1610
1611 #if 0 /* This isn't logically necessary, and it can do GC. */
1612 /* Don't let the frame remain selected. */
1613 if (EQ (frame, selected_frame))
1614 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1615 #endif
1616
1617 /* Don't allow minibuf_window to remain on a deleted frame. */
1618 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1619 {
1620 struct frame *sf = XFRAME (selected_frame);
1621 Fset_window_buffer (sf->minibuffer_window,
1622 XWINDOW (minibuf_window)->buffer);
1623 minibuf_window = sf->minibuffer_window;
1624 }
1625
1626 /* I think this should be done with a hook. */
1627 #ifdef HAVE_WINDOW_SYSTEM
1628 if (FRAME_WINDOW_P (XFRAME (frame)))
1629 x_iconify_frame (XFRAME (frame));
1630 #endif
1631
1632 /* Make menu bar update for the Buffers and Frams menus. */
1633 windows_or_buffers_changed++;
1634
1635 return Qnil;
1636 }
1637
1638 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1639 1, 1, 0,
1640 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1641 A frame that is not \"visible\" is not updated and, if it works through\n\
1642 a window system, it may not show at all.\n\
1643 Return the symbol `icon' if frame is visible only as an icon.")
1644 (frame)
1645 Lisp_Object frame;
1646 {
1647 CHECK_LIVE_FRAME (frame, 0);
1648
1649 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1650
1651 if (FRAME_VISIBLE_P (XFRAME (frame)))
1652 return Qt;
1653 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1654 return Qicon;
1655 return Qnil;
1656 }
1657
1658 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1659 0, 0, 0,
1660 "Return a list of all frames now \"visible\" (being updated).")
1661 ()
1662 {
1663 Lisp_Object tail, frame;
1664 struct frame *f;
1665 Lisp_Object value;
1666
1667 value = Qnil;
1668 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1669 {
1670 frame = XCONS (tail)->car;
1671 if (!FRAMEP (frame))
1672 continue;
1673 f = XFRAME (frame);
1674 if (FRAME_VISIBLE_P (f))
1675 value = Fcons (frame, value);
1676 }
1677 return value;
1678 }
1679
1680
1681 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1682 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1683 If FRAME is invisible, make it visible.\n\
1684 If you don't specify a frame, the selected frame is used.\n\
1685 If Emacs is displaying on an ordinary terminal or some other device which\n\
1686 doesn't support multiple overlapping frames, this function does nothing.")
1687 (frame)
1688 Lisp_Object frame;
1689 {
1690 if (NILP (frame))
1691 frame = selected_frame;
1692
1693 CHECK_LIVE_FRAME (frame, 0);
1694
1695 /* Do like the documentation says. */
1696 Fmake_frame_visible (frame);
1697
1698 if (frame_raise_lower_hook)
1699 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1700
1701 return Qnil;
1702 }
1703
1704 /* Should we have a corresponding function called Flower_Power? */
1705 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1706 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1707 If you don't specify a frame, the selected frame is used.\n\
1708 If Emacs is displaying on an ordinary terminal or some other device which\n\
1709 doesn't support multiple overlapping frames, this function does nothing.")
1710 (frame)
1711 Lisp_Object frame;
1712 {
1713 if (NILP (frame))
1714 frame = selected_frame;
1715
1716 CHECK_LIVE_FRAME (frame, 0);
1717
1718 if (frame_raise_lower_hook)
1719 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1720
1721 return Qnil;
1722 }
1723
1724 \f
1725 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1726 1, 2, 0,
1727 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1728 In other words, switch-frame events caused by events in FRAME will\n\
1729 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1730 FOCUS-FRAME after reading an event typed at FRAME.\n\
1731 \n\
1732 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1733 cancelled, and the frame again receives its own keystrokes.\n\
1734 \n\
1735 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1736 a surrogate minibuffer frame when a frame doesn't have its own\n\
1737 minibuffer window.\n\
1738 \n\
1739 A frame's focus redirection can be changed by select-frame. If frame\n\
1740 FOO is selected, and then a different frame BAR is selected, any\n\
1741 frames redirecting their focus to FOO are shifted to redirect their\n\
1742 focus to BAR. This allows focus redirection to work properly when the\n\
1743 user switches from one frame to another using `select-window'.\n\
1744 \n\
1745 This means that a frame whose focus is redirected to itself is treated\n\
1746 differently from a frame whose focus is redirected to nil; the former\n\
1747 is affected by select-frame, while the latter is not.\n\
1748 \n\
1749 The redirection lasts until `redirect-frame-focus' is called to change it.")
1750 (frame, focus_frame)
1751 Lisp_Object frame, focus_frame;
1752 {
1753 /* Note that we don't check for a live frame here. It's reasonable
1754 to redirect the focus of a frame you're about to delete, if you
1755 know what other frame should receive those keystrokes. */
1756 CHECK_FRAME (frame, 0);
1757
1758 if (! NILP (focus_frame))
1759 CHECK_LIVE_FRAME (focus_frame, 1);
1760
1761 XFRAME (frame)->focus_frame = focus_frame;
1762
1763 if (frame_rehighlight_hook)
1764 (*frame_rehighlight_hook) (XFRAME (frame));
1765
1766 return Qnil;
1767 }
1768
1769
1770 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1771 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1772 This returns nil if FRAME's focus is not redirected.\n\
1773 See `redirect-frame-focus'.")
1774 (frame)
1775 Lisp_Object frame;
1776 {
1777 CHECK_LIVE_FRAME (frame, 0);
1778
1779 return FRAME_FOCUS_FRAME (XFRAME (frame));
1780 }
1781
1782
1783 \f
1784 /* Return the value of frame parameter PROP in frame FRAME. */
1785
1786 Lisp_Object
1787 get_frame_param (frame, prop)
1788 register struct frame *frame;
1789 Lisp_Object prop;
1790 {
1791 register Lisp_Object tem;
1792
1793 tem = Fassq (prop, frame->param_alist);
1794 if (EQ (tem, Qnil))
1795 return tem;
1796 return Fcdr (tem);
1797 }
1798
1799 /* Return the buffer-predicate of the selected frame. */
1800
1801 Lisp_Object
1802 frame_buffer_predicate (frame)
1803 Lisp_Object frame;
1804 {
1805 return XFRAME (frame)->buffer_predicate;
1806 }
1807
1808 /* Return the buffer-list of the selected frame. */
1809
1810 Lisp_Object
1811 frame_buffer_list (frame)
1812 Lisp_Object frame;
1813 {
1814 return XFRAME (frame)->buffer_list;
1815 }
1816
1817 /* Set the buffer-list of the selected frame. */
1818
1819 void
1820 set_frame_buffer_list (frame, list)
1821 Lisp_Object frame, list;
1822 {
1823 XFRAME (frame)->buffer_list = list;
1824 }
1825
1826 /* Discard BUFFER from the buffer-list of each frame. */
1827
1828 void
1829 frames_discard_buffer (buffer)
1830 Lisp_Object buffer;
1831 {
1832 Lisp_Object frame, tail;
1833
1834 FOR_EACH_FRAME (tail, frame)
1835 {
1836 XFRAME (frame)->buffer_list
1837 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1838 }
1839 }
1840
1841 /* Move BUFFER to the end of the buffer-list of each frame. */
1842
1843 void
1844 frames_bury_buffer (buffer)
1845 Lisp_Object buffer;
1846 {
1847 Lisp_Object frame, tail;
1848
1849 FOR_EACH_FRAME (tail, frame)
1850 {
1851 XFRAME (frame)->buffer_list
1852 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1853 Fcons (buffer, Qnil));
1854 }
1855 }
1856
1857 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1858 If the alist already has an element for PROP, we change it. */
1859
1860 void
1861 store_in_alist (alistptr, prop, val)
1862 Lisp_Object *alistptr, val;
1863 Lisp_Object prop;
1864 {
1865 register Lisp_Object tem;
1866
1867 tem = Fassq (prop, *alistptr);
1868 if (EQ (tem, Qnil))
1869 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1870 else
1871 Fsetcdr (tem, val);
1872 }
1873
1874 static int
1875 frame_name_fnn_p (str, len)
1876 char *str;
1877 int len;
1878 {
1879 if (len > 1 && str[0] == 'F')
1880 {
1881 char *end_ptr;
1882
1883 if (end_ptr == str + len)
1884 return 1;
1885 }
1886 return 0;
1887 }
1888
1889 /* Set the name of the terminal frame. Also used by MSDOS frames.
1890 Modeled after x_set_name which is used for WINDOW frames. */
1891
1892 void
1893 set_term_frame_name (f, name)
1894 struct frame *f;
1895 Lisp_Object name;
1896 {
1897 f->explicit_name = ! NILP (name);
1898
1899 /* If NAME is nil, set the name to F<num>. */
1900 if (NILP (name))
1901 {
1902 char namebuf[20];
1903
1904 /* Check for no change needed in this very common case
1905 before we do any consing. */
1906 if (frame_name_fnn_p (XSTRING (f->name)->data,
1907 STRING_BYTES (XSTRING (f->name))))
1908 return;
1909
1910 terminal_frame_count++;
1911 sprintf (namebuf, "F%d", terminal_frame_count);
1912 name = build_string (namebuf);
1913 }
1914 else
1915 {
1916 CHECK_STRING (name, 0);
1917
1918 /* Don't change the name if it's already NAME. */
1919 if (! NILP (Fstring_equal (name, f->name)))
1920 return;
1921
1922 /* Don't allow the user to set the frame name to F<num>, so it
1923 doesn't clash with the names we generate for terminal frames. */
1924 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1925 error ("Frame names of the form F<num> are usurped by Emacs");
1926 }
1927
1928 f->name = name;
1929 update_mode_lines = 1;
1930 }
1931
1932 void
1933 store_frame_param (f, prop, val)
1934 struct frame *f;
1935 Lisp_Object prop, val;
1936 {
1937 register Lisp_Object tem;
1938
1939 if (EQ (prop, Qbuffer_list))
1940 {
1941 f->buffer_list = val;
1942 return;
1943 }
1944
1945 tem = Fassq (prop, f->param_alist);
1946 if (EQ (tem, Qnil))
1947 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1948 else
1949 Fsetcdr (tem, val);
1950
1951 if (EQ (prop, Qbuffer_predicate))
1952 f->buffer_predicate = val;
1953
1954 if (! FRAME_WINDOW_P (f))
1955 {
1956 if (EQ (prop, Qmenu_bar_lines))
1957 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1958 else if (EQ (prop, Qname))
1959 set_term_frame_name (f, val);
1960 }
1961
1962 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1963 {
1964 if (! MINI_WINDOW_P (XWINDOW (val)))
1965 error ("Surrogate minibuffer windows must be minibuffer windows.");
1966
1967 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1968 && !EQ (val, f->minibuffer_window))
1969 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1970
1971 /* Install the chosen minibuffer window, with proper buffer. */
1972 f->minibuffer_window = val;
1973 }
1974 }
1975
1976 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1977 "Return the parameters-alist of frame FRAME.\n\
1978 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1979 The meaningful PARMs depend on the kind of frame.\n\
1980 If FRAME is omitted, return information on the currently selected frame.")
1981 (frame)
1982 Lisp_Object frame;
1983 {
1984 Lisp_Object alist;
1985 FRAME_PTR f;
1986 int height, width;
1987
1988 if (EQ (frame, Qnil))
1989 frame = selected_frame;
1990
1991 CHECK_FRAME (frame, 0);
1992 f = XFRAME (frame);
1993
1994 if (!FRAME_LIVE_P (f))
1995 return Qnil;
1996
1997 alist = Fcopy_alist (f->param_alist);
1998 #ifdef MSDOS
1999 if (FRAME_MSDOS_P (f))
2000 {
2001 int fg = FRAME_FOREGROUND_PIXEL (f);
2002 int bg = FRAME_BACKGROUND_PIXEL (f);
2003 Lisp_Object qreverse = intern ("reverse");
2004 int rv =
2005 !NILP (Fassq (qreverse, alist))
2006 || !NILP (Fassq (qreverse, Vdefault_frame_alist));
2007
2008 store_in_alist (&alist, intern ("foreground-color"),
2009 build_string (msdos_stdcolor_name (rv ? bg : fg)));
2010 store_in_alist (&alist, intern ("background-color"),
2011 build_string (msdos_stdcolor_name (rv ? fg : bg)));
2012 }
2013 store_in_alist (&alist, intern ("font"), build_string ("ms-dos"));
2014 #endif
2015 store_in_alist (&alist, Qname, f->name);
2016 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2017 store_in_alist (&alist, Qheight, make_number (height));
2018 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2019 store_in_alist (&alist, Qwidth, make_number (width));
2020 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2021 store_in_alist (&alist, Qminibuffer,
2022 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2023 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2024 : FRAME_MINIBUF_WINDOW (f)));
2025 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2026 store_in_alist (&alist, Qbuffer_list,
2027 frame_buffer_list (selected_frame));
2028
2029 /* I think this should be done with a hook. */
2030 #ifdef HAVE_WINDOW_SYSTEM
2031 if (FRAME_WINDOW_P (f))
2032 x_report_frame_params (f, &alist);
2033 else
2034 #endif
2035 {
2036 /* This ought to be correct in f->param_alist for an X frame. */
2037 Lisp_Object lines;
2038 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2039 store_in_alist (&alist, Qmenu_bar_lines, lines);
2040 }
2041 return alist;
2042 }
2043
2044 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2045 Smodify_frame_parameters, 2, 2, 0,
2046 "Modify the parameters of frame FRAME according to ALIST.\n\
2047 ALIST is an alist of parameters to change and their new values.\n\
2048 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2049 The meaningful PARMs depend on the kind of frame.\n\
2050 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2051 so that `frame-parameters' will return them.")
2052 (frame, alist)
2053 Lisp_Object frame, alist;
2054 {
2055 FRAME_PTR f;
2056 register Lisp_Object tail, prop, val;
2057
2058 if (EQ (frame, Qnil))
2059 frame = selected_frame;
2060 CHECK_LIVE_FRAME (frame, 0);
2061 f = XFRAME (frame);
2062
2063 /* I think this should be done with a hook. */
2064 #ifdef HAVE_WINDOW_SYSTEM
2065 if (FRAME_WINDOW_P (f))
2066 x_set_frame_parameters (f, alist);
2067 else
2068 #endif
2069 #ifdef MSDOS
2070 if (FRAME_MSDOS_P (f))
2071 IT_set_frame_parameters (f, alist);
2072 else
2073 #endif
2074 #ifdef macintosh
2075 if (FRAME_MAC_P (f))
2076 mac_set_frame_parameters (f, alist);
2077 else
2078 #endif
2079
2080 {
2081 int length = XINT (Flength (alist));
2082 int i;
2083 Lisp_Object *parms
2084 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2085 Lisp_Object *values
2086 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2087
2088 /* Extract parm names and values into those vectors. */
2089
2090 i = 0;
2091 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2092 {
2093 Lisp_Object elt;
2094
2095 elt = Fcar (tail);
2096 parms[i] = Fcar (elt);
2097 values[i] = Fcdr (elt);
2098 i++;
2099 }
2100
2101 /* Now process them in reverse of specified order. */
2102 for (i--; i >= 0; i--)
2103 {
2104 prop = parms[i];
2105 val = values[i];
2106 store_frame_param (f, prop, val);
2107 }
2108 }
2109
2110 return Qnil;
2111 }
2112 \f
2113 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2114 0, 1, 0,
2115 "Height in pixels of a line in the font in frame FRAME.\n\
2116 If FRAME is omitted, the selected frame is used.\n\
2117 For a terminal frame, the value is always 1.")
2118 (frame)
2119 Lisp_Object frame;
2120 {
2121 struct frame *f;
2122
2123 if (NILP (frame))
2124 frame = selected_frame;
2125 CHECK_FRAME (frame, 0);
2126 f = XFRAME (frame);
2127
2128 #ifdef HAVE_WINDOW_SYSTEM
2129 if (FRAME_WINDOW_P (f))
2130 return make_number (x_char_height (f));
2131 else
2132 #endif
2133 return make_number (1);
2134 }
2135
2136
2137 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2138 0, 1, 0,
2139 "Width in pixels of characters in the font in frame FRAME.\n\
2140 If FRAME is omitted, the selected frame is used.\n\
2141 The width is the same for all characters, because\n\
2142 currently Emacs supports only fixed-width fonts.\n\
2143 For a terminal screen, the value is always 1.")
2144 (frame)
2145 Lisp_Object frame;
2146 {
2147 struct frame *f;
2148
2149 if (NILP (frame))
2150 frame = selected_frame;
2151 CHECK_FRAME (frame, 0);
2152 f = XFRAME (frame);
2153
2154 #ifdef HAVE_WINDOW_SYSTEM
2155 if (FRAME_WINDOW_P (f))
2156 return make_number (x_char_width (f));
2157 else
2158 #endif
2159 return make_number (1);
2160 }
2161
2162 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2163 Sframe_pixel_height, 0, 1, 0,
2164 "Return a FRAME's height in pixels.\n\
2165 This counts only the height available for text lines,\n\
2166 not menu bars on window-system Emacs frames.\n\
2167 For a terminal frame, the result really gives the height in characters.\n\
2168 If FRAME is omitted, the selected frame is used.")
2169 (frame)
2170 Lisp_Object frame;
2171 {
2172 struct frame *f;
2173
2174 if (NILP (frame))
2175 frame = selected_frame;
2176 CHECK_FRAME (frame, 0);
2177 f = XFRAME (frame);
2178
2179 #ifdef HAVE_WINDOW_SYSTEM
2180 if (FRAME_WINDOW_P (f))
2181 return make_number (x_pixel_height (f));
2182 else
2183 #endif
2184 return make_number (FRAME_HEIGHT (f));
2185 }
2186
2187 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2188 Sframe_pixel_width, 0, 1, 0,
2189 "Return FRAME's width in pixels.\n\
2190 For a terminal frame, the result really gives the width in characters.\n\
2191 If FRAME is omitted, the selected frame is used.")
2192 (frame)
2193 Lisp_Object frame;
2194 {
2195 struct frame *f;
2196
2197 if (NILP (frame))
2198 frame = selected_frame;
2199 CHECK_FRAME (frame, 0);
2200 f = XFRAME (frame);
2201
2202 #ifdef HAVE_WINDOW_SYSTEM
2203 if (FRAME_WINDOW_P (f))
2204 return make_number (x_pixel_width (f));
2205 else
2206 #endif
2207 return make_number (FRAME_WIDTH (f));
2208 }
2209 \f
2210 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2211 "Specify that the frame FRAME has LINES lines.\n\
2212 Optional third arg non-nil means that redisplay should use LINES lines\n\
2213 but that the idea of the actual height of the frame should not be changed.")
2214 (frame, lines, pretend)
2215 Lisp_Object frame, lines, pretend;
2216 {
2217 register struct frame *f;
2218
2219 CHECK_NUMBER (lines, 0);
2220 if (NILP (frame))
2221 frame = selected_frame;
2222 CHECK_LIVE_FRAME (frame, 0);
2223 f = XFRAME (frame);
2224
2225 /* I think this should be done with a hook. */
2226 #ifdef HAVE_WINDOW_SYSTEM
2227 if (FRAME_WINDOW_P (f))
2228 {
2229 if (XINT (lines) != f->height)
2230 x_set_window_size (f, 1, f->width, XINT (lines));
2231 do_pending_window_change (0);
2232 }
2233 else
2234 #endif
2235 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2236 return Qnil;
2237 }
2238
2239 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2240 "Specify that the frame FRAME has COLS columns.\n\
2241 Optional third arg non-nil means that redisplay should use COLS columns\n\
2242 but that the idea of the actual width of the frame should not be changed.")
2243 (frame, cols, pretend)
2244 Lisp_Object frame, cols, pretend;
2245 {
2246 register struct frame *f;
2247 CHECK_NUMBER (cols, 0);
2248 if (NILP (frame))
2249 frame = selected_frame;
2250 CHECK_LIVE_FRAME (frame, 0);
2251 f = XFRAME (frame);
2252
2253 /* I think this should be done with a hook. */
2254 #ifdef HAVE_WINDOW_SYSTEM
2255 if (FRAME_WINDOW_P (f))
2256 {
2257 if (XINT (cols) != f->width)
2258 x_set_window_size (f, 1, XINT (cols), f->height);
2259 do_pending_window_change (0);
2260 }
2261 else
2262 #endif
2263 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2264 return Qnil;
2265 }
2266
2267 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2268 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2269 (frame, cols, rows)
2270 Lisp_Object frame, cols, rows;
2271 {
2272 register struct frame *f;
2273
2274 CHECK_LIVE_FRAME (frame, 0);
2275 CHECK_NUMBER (cols, 2);
2276 CHECK_NUMBER (rows, 1);
2277 f = XFRAME (frame);
2278
2279 /* I think this should be done with a hook. */
2280 #ifdef HAVE_WINDOW_SYSTEM
2281 if (FRAME_WINDOW_P (f))
2282 {
2283 if (XINT (rows) != f->height || XINT (cols) != f->width
2284 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2285 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2286 do_pending_window_change (0);
2287 }
2288 else
2289 #endif
2290 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2291
2292 return Qnil;
2293 }
2294
2295 DEFUN ("set-frame-position", Fset_frame_position,
2296 Sset_frame_position, 3, 3, 0,
2297 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2298 This is actually the position of the upper left corner of the frame.\n\
2299 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2300 the rightmost or bottommost possible position (that stays within the screen).")
2301 (frame, xoffset, yoffset)
2302 Lisp_Object frame, xoffset, yoffset;
2303 {
2304 register struct frame *f;
2305
2306 CHECK_LIVE_FRAME (frame, 0);
2307 CHECK_NUMBER (xoffset, 1);
2308 CHECK_NUMBER (yoffset, 2);
2309 f = XFRAME (frame);
2310
2311 /* I think this should be done with a hook. */
2312 #ifdef HAVE_WINDOW_SYSTEM
2313 if (FRAME_WINDOW_P (f))
2314 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2315 #endif
2316
2317 return Qt;
2318 }
2319
2320 \f
2321 void
2322 syms_of_frame ()
2323 {
2324 syms_of_frame_1 ();
2325
2326 staticpro (&Vframe_list);
2327
2328 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2329 "The initial frame-object, which represents Emacs's stdout.");
2330
2331 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2332 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2333 Vemacs_iconified = Qnil;
2334
2335 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2336 "Minibufferless frames use this frame's minibuffer.\n\
2337 \n\
2338 Emacs cannot create minibufferless frames unless this is set to an\n\
2339 appropriate surrogate.\n\
2340 \n\
2341 Emacs consults this variable only when creating minibufferless\n\
2342 frames; once the frame is created, it sticks with its assigned\n\
2343 minibuffer, no matter what this variable is set to. This means that\n\
2344 this variable doesn't necessarily say anything meaningful about the\n\
2345 current set of frames, or where the minibuffer is currently being\n\
2346 displayed.");
2347
2348 defsubr (&Sactive_minibuffer_window);
2349 defsubr (&Sframep);
2350 defsubr (&Sframe_live_p);
2351 defsubr (&Smake_terminal_frame);
2352 defsubr (&Shandle_switch_frame);
2353 defsubr (&Signore_event);
2354 defsubr (&Sselect_frame);
2355 defsubr (&Sselected_frame);
2356 defsubr (&Swindow_frame);
2357 defsubr (&Sframe_root_window);
2358 defsubr (&Sframe_first_window);
2359 defsubr (&Sframe_selected_window);
2360 defsubr (&Sset_frame_selected_window);
2361 defsubr (&Sframe_list);
2362 defsubr (&Snext_frame);
2363 defsubr (&Sprevious_frame);
2364 defsubr (&Sdelete_frame);
2365 defsubr (&Smouse_position);
2366 defsubr (&Smouse_pixel_position);
2367 defsubr (&Sset_mouse_position);
2368 defsubr (&Sset_mouse_pixel_position);
2369 #if 0
2370 defsubr (&Sframe_configuration);
2371 defsubr (&Srestore_frame_configuration);
2372 #endif
2373 defsubr (&Smake_frame_visible);
2374 defsubr (&Smake_frame_invisible);
2375 defsubr (&Siconify_frame);
2376 defsubr (&Sframe_visible_p);
2377 defsubr (&Svisible_frame_list);
2378 defsubr (&Sraise_frame);
2379 defsubr (&Slower_frame);
2380 defsubr (&Sredirect_frame_focus);
2381 defsubr (&Sframe_focus);
2382 defsubr (&Sframe_parameters);
2383 defsubr (&Smodify_frame_parameters);
2384 defsubr (&Sframe_char_height);
2385 defsubr (&Sframe_char_width);
2386 defsubr (&Sframe_pixel_height);
2387 defsubr (&Sframe_pixel_width);
2388 defsubr (&Sset_frame_height);
2389 defsubr (&Sset_frame_width);
2390 defsubr (&Sset_frame_size);
2391 defsubr (&Sset_frame_position);
2392 }
2393
2394 void
2395 keys_of_frame ()
2396 {
2397 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2398 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2399 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2400 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2401 }