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