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