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