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