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