(make_frame_without_minibuffer): Don't change the
[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
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
1703 if (EQ (frame, Qnil))
1704 f = selected_frame;
1705 else
1706 {
1707 CHECK_FRAME (frame, 0);
1708 f = XFRAME (frame);
1709 }
1710
1711 if (!FRAME_LIVE_P (f))
1712 return Qnil;
1713
1714 alist = Fcopy_alist (f->param_alist);
1715 store_in_alist (&alist, Qname, f->name);
1716 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
1717 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
1718 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
1719 store_in_alist (&alist, Qminibuffer,
1720 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1721 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1722 : FRAME_MINIBUF_WINDOW (f)));
1723 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
1724
1725 /* I think this should be done with a hook. */
1726 #ifdef HAVE_WINDOW_SYSTEM
1727 if (FRAME_WINDOW_P (f))
1728 x_report_frame_params (f, &alist);
1729 else
1730 #endif
1731 {
1732 /* This ought to be correct in f->param_alist for an X frame. */
1733 Lisp_Object lines;
1734 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
1735 store_in_alist (&alist, Qmenu_bar_lines, lines);
1736 }
1737 return alist;
1738 }
1739
1740 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1741 Smodify_frame_parameters, 2, 2, 0,
1742 "Modify the parameters of frame FRAME according to ALIST.\n\
1743 ALIST is an alist of parameters to change and their new values.\n\
1744 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1745 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1746 (frame, alist)
1747 Lisp_Object frame, alist;
1748 {
1749 FRAME_PTR f;
1750 register Lisp_Object tail, elt, prop, val;
1751
1752 if (EQ (frame, Qnil))
1753 f = selected_frame;
1754 else
1755 {
1756 CHECK_LIVE_FRAME (frame, 0);
1757 f = XFRAME (frame);
1758 }
1759
1760 /* I think this should be done with a hook. */
1761 #ifdef HAVE_WINDOW_SYSTEM
1762 if (FRAME_WINDOW_P (f))
1763 x_set_frame_parameters (f, alist);
1764 else
1765 #endif
1766 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1767 {
1768 elt = Fcar (tail);
1769 prop = Fcar (elt);
1770 val = Fcdr (elt);
1771 store_frame_param (f, prop, val);
1772 }
1773
1774 return Qnil;
1775 }
1776 \f
1777 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1778 0, 1, 0,
1779 "Height in pixels of a line in the font in frame FRAME.\n\
1780 If FRAME is omitted, the selected frame is used.\n\
1781 For a terminal frame, the value is always 1.")
1782 (frame)
1783 Lisp_Object frame;
1784 {
1785 struct frame *f;
1786
1787 if (NILP (frame))
1788 f = selected_frame;
1789 else
1790 {
1791 CHECK_FRAME (frame, 0);
1792 f = XFRAME (frame);
1793 }
1794
1795 #ifdef HAVE_WINDOW_SYSTEM
1796 if (FRAME_WINDOW_P (f))
1797 return make_number (x_char_height (f));
1798 else
1799 #endif
1800 return make_number (1);
1801 }
1802
1803
1804 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1805 0, 1, 0,
1806 "Width in pixels of characters in the font in frame FRAME.\n\
1807 If FRAME is omitted, the selected frame is used.\n\
1808 The width is the same for all characters, because\n\
1809 currently Emacs supports only fixed-width fonts.\n\
1810 For a terminal screen, the value is always 1.")
1811 (frame)
1812 Lisp_Object frame;
1813 {
1814 struct frame *f;
1815
1816 if (NILP (frame))
1817 f = selected_frame;
1818 else
1819 {
1820 CHECK_FRAME (frame, 0);
1821 f = XFRAME (frame);
1822 }
1823
1824 #ifdef HAVE_WINDOW_SYSTEM
1825 if (FRAME_WINDOW_P (f))
1826 return make_number (x_char_width (f));
1827 else
1828 #endif
1829 return make_number (1);
1830 }
1831
1832 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1833 Sframe_pixel_height, 0, 1, 0,
1834 "Return a FRAME's height in pixels.\n\
1835 For a terminal frame, the result really gives the height in characters.\n\
1836 If FRAME is omitted, the selected frame is used.")
1837 (frame)
1838 Lisp_Object frame;
1839 {
1840 struct frame *f;
1841
1842 if (NILP (frame))
1843 f = selected_frame;
1844 else
1845 {
1846 CHECK_FRAME (frame, 0);
1847 f = XFRAME (frame);
1848 }
1849
1850 #ifdef HAVE_WINDOW_SYSTEM
1851 if (FRAME_WINDOW_P (f))
1852 return make_number (x_pixel_height (f));
1853 else
1854 #endif
1855 return make_number (FRAME_HEIGHT (f));
1856 }
1857
1858 DEFUN ("frame-pixel-width", Fframe_pixel_width,
1859 Sframe_pixel_width, 0, 1, 0,
1860 "Return FRAME's width in pixels.\n\
1861 For a terminal frame, the result really gives the width in characters.\n\
1862 If FRAME is omitted, the selected frame is used.")
1863 (frame)
1864 Lisp_Object frame;
1865 {
1866 struct frame *f;
1867
1868 if (NILP (frame))
1869 f = selected_frame;
1870 else
1871 {
1872 CHECK_FRAME (frame, 0);
1873 f = XFRAME (frame);
1874 }
1875
1876 #ifdef HAVE_WINDOW_SYSTEM
1877 if (FRAME_WINDOW_P (f))
1878 return make_number (x_pixel_width (f));
1879 else
1880 #endif
1881 return make_number (FRAME_WIDTH (f));
1882 }
1883 \f
1884 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1885 "Specify that the frame FRAME has LINES lines.\n\
1886 Optional third arg non-nil means that redisplay should use LINES lines\n\
1887 but that the idea of the actual height of the frame should not be changed.")
1888 (frame, lines, pretend)
1889 Lisp_Object frame, lines, pretend;
1890 {
1891 register struct frame *f;
1892
1893 CHECK_NUMBER (lines, 0);
1894 if (NILP (frame))
1895 f = selected_frame;
1896 else
1897 {
1898 CHECK_LIVE_FRAME (frame, 0);
1899 f = XFRAME (frame);
1900 }
1901
1902 /* I think this should be done with a hook. */
1903 #ifdef HAVE_WINDOW_SYSTEM
1904 if (FRAME_WINDOW_P (f))
1905 {
1906 if (XINT (lines) != f->height)
1907 x_set_window_size (f, 1, f->width, XINT (lines));
1908 }
1909 else
1910 #endif
1911 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
1912 return Qnil;
1913 }
1914
1915 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1916 "Specify that the frame FRAME has COLS columns.\n\
1917 Optional third arg non-nil means that redisplay should use COLS columns\n\
1918 but that the idea of the actual width of the frame should not be changed.")
1919 (frame, cols, pretend)
1920 Lisp_Object frame, cols, pretend;
1921 {
1922 register struct frame *f;
1923 CHECK_NUMBER (cols, 0);
1924 if (NILP (frame))
1925 f = selected_frame;
1926 else
1927 {
1928 CHECK_LIVE_FRAME (frame, 0);
1929 f = XFRAME (frame);
1930 }
1931
1932 /* I think this should be done with a hook. */
1933 #ifdef HAVE_WINDOW_SYSTEM
1934 if (FRAME_WINDOW_P (f))
1935 {
1936 if (XINT (cols) != f->width)
1937 x_set_window_size (f, 1, XINT (cols), f->height);
1938 }
1939 else
1940 #endif
1941 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
1942 return Qnil;
1943 }
1944
1945 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1946 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1947 (frame, cols, rows)
1948 Lisp_Object frame, cols, rows;
1949 {
1950 register struct frame *f;
1951 int mask;
1952
1953 CHECK_LIVE_FRAME (frame, 0);
1954 CHECK_NUMBER (cols, 2);
1955 CHECK_NUMBER (rows, 1);
1956 f = XFRAME (frame);
1957
1958 /* I think this should be done with a hook. */
1959 #ifdef HAVE_WINDOW_SYSTEM
1960 if (FRAME_WINDOW_P (f))
1961 {
1962 if (XINT (rows) != f->height || XINT (cols) != f->width
1963 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
1964 x_set_window_size (f, 1, XINT (cols), XINT (rows));
1965 }
1966 else
1967 #endif
1968 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
1969
1970 return Qnil;
1971 }
1972
1973 DEFUN ("set-frame-position", Fset_frame_position,
1974 Sset_frame_position, 3, 3, 0,
1975 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1976 This is actually the position of the upper left corner of the frame.\n\
1977 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
1978 the rightmost or bottommost possible position (that stays within the screen).")
1979 (frame, xoffset, yoffset)
1980 Lisp_Object frame, xoffset, yoffset;
1981 {
1982 register struct frame *f;
1983 int mask;
1984
1985 CHECK_LIVE_FRAME (frame, 0);
1986 CHECK_NUMBER (xoffset, 1);
1987 CHECK_NUMBER (yoffset, 2);
1988 f = XFRAME (frame);
1989
1990 /* I think this should be done with a hook. */
1991 #ifdef HAVE_WINDOW_SYSTEM
1992 if (FRAME_WINDOW_P (f))
1993 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
1994 #endif
1995
1996 return Qt;
1997 }
1998
1999 \f
2000 syms_of_frame ()
2001 {
2002 syms_of_frame_1 ();
2003
2004 staticpro (&Vframe_list);
2005
2006 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2007 "The initial frame-object, which represents Emacs's stdout.");
2008
2009 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2010 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2011 Vemacs_iconified = Qnil;
2012
2013 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2014 "Minibufferless frames use this frame's minibuffer.\n\
2015 \n\
2016 Emacs cannot create minibufferless frames unless this is set to an\n\
2017 appropriate surrogate.\n\
2018 \n\
2019 Emacs consults this variable only when creating minibufferless\n\
2020 frames; once the frame is created, it sticks with its assigned\n\
2021 minibuffer, no matter what this variable is set to. This means that\n\
2022 this variable doesn't necessarily say anything meaningful about the\n\
2023 current set of frames, or where the minibuffer is currently being\n\
2024 displayed.");
2025
2026 defsubr (&Sactive_minibuffer_window);
2027 defsubr (&Sframep);
2028 defsubr (&Sframe_live_p);
2029 defsubr (&Smake_terminal_frame);
2030 defsubr (&Shandle_switch_frame);
2031 defsubr (&Signore_event);
2032 defsubr (&Sselect_frame);
2033 defsubr (&Sselected_frame);
2034 defsubr (&Swindow_frame);
2035 defsubr (&Sframe_root_window);
2036 defsubr (&Sframe_first_window);
2037 defsubr (&Sframe_selected_window);
2038 defsubr (&Sset_frame_selected_window);
2039 defsubr (&Sframe_list);
2040 defsubr (&Snext_frame);
2041 defsubr (&Sprevious_frame);
2042 defsubr (&Sdelete_frame);
2043 defsubr (&Smouse_position);
2044 defsubr (&Smouse_pixel_position);
2045 defsubr (&Sset_mouse_position);
2046 defsubr (&Sset_mouse_pixel_position);
2047 #if 0
2048 defsubr (&Sframe_configuration);
2049 defsubr (&Srestore_frame_configuration);
2050 #endif
2051 defsubr (&Smake_frame_visible);
2052 defsubr (&Smake_frame_invisible);
2053 defsubr (&Siconify_frame);
2054 defsubr (&Sframe_visible_p);
2055 defsubr (&Svisible_frame_list);
2056 defsubr (&Sraise_frame);
2057 defsubr (&Slower_frame);
2058 defsubr (&Sredirect_frame_focus);
2059 defsubr (&Sframe_focus);
2060 defsubr (&Sframe_parameters);
2061 defsubr (&Smodify_frame_parameters);
2062 defsubr (&Sframe_char_height);
2063 defsubr (&Sframe_char_width);
2064 defsubr (&Sframe_pixel_height);
2065 defsubr (&Sframe_pixel_width);
2066 defsubr (&Sset_frame_height);
2067 defsubr (&Sset_frame_width);
2068 defsubr (&Sset_frame_size);
2069 defsubr (&Sset_frame_position);
2070 }
2071
2072 keys_of_frame ()
2073 {
2074 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2075 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2076 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2077 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2078 }
2079 \f
2080 #else /* not MULTI_FRAME */
2081
2082 /* If we're not using multi-frame stuff, we still need to provide some
2083 support functions. */
2084
2085 /* Unless this function is defined, providing set-frame-height and
2086 set-frame-width doesn't help compatibility any, since they both
2087 want this as their first argument. */
2088 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
2089 /* Don't confuse make-docfile by having two doc strings for this function.
2090 make-docfile does not pay attention to #if, for good reason! */
2091 0)
2092 ()
2093 {
2094 /* For your possible information, this code is unfolded into the
2095 second WINDOW_FRAME in frame.h. */
2096 Lisp_Object tem;
2097 XSETFASTINT (tem, 0);
2098 return tem;
2099 }
2100
2101 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
2102 Sactive_minibuffer_window, 0, 0, 0,
2103 /* Don't confuse make-docfile by having two doc strings for this function.
2104 make-docfile does not pay attention to #if, for good reason! */
2105 0)
2106 ()
2107 {
2108 return minibuf_level ? minibuf_window : Qnil;
2109 }
2110
2111 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
2112 /* Don't confuse make-docfile by having two doc strings for this function.
2113 make-docfile does not pay attention to #if, for good reason! */
2114 0)
2115 (window)
2116 Lisp_Object window;
2117 {
2118 /* For your possible information, this code is unfolded into the
2119 second WINDOW_FRAME in frame.h. */
2120 Lisp_Object tem;
2121 XSETFASTINT (tem, 0);
2122 return tem;
2123 }
2124
2125 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
2126 0)
2127 (frame)
2128 Lisp_Object frame;
2129 {
2130 Lisp_Object w;
2131
2132 w = FRAME_ROOT_WINDOW (selected_frame);
2133
2134 while (NILP (XWINDOW (w)->buffer))
2135 {
2136 if (! NILP (XWINDOW (w)->hchild))
2137 w = XWINDOW (w)->hchild;
2138 else if (! NILP (XWINDOW (w)->vchild))
2139 w = XWINDOW (w)->vchild;
2140 else
2141 abort ();
2142 }
2143 return w;
2144 }
2145
2146 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
2147 /* Don't confuse make-docfile by having two doc strings for this function.
2148 make-docfile does not pay attention to #if, for good reason! */
2149 0)
2150 (object)
2151 Lisp_Object object;
2152 {
2153 #ifdef MSDOS
2154 if (FRAME_X_P (object))
2155 return intern ("pc");
2156 #endif
2157 return Qnil;
2158 }
2159
2160 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2161 /* Don't confuse make-docfile by having two doc strings for this function.
2162 make-docfile does not pay attention to #if, for good reason! */
2163 0)
2164 (frame, rows, pretend)
2165 Lisp_Object frame, rows, pretend;
2166 {
2167 CHECK_NUMBER (rows, 0);
2168
2169 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
2170 return Qnil;
2171 }
2172
2173 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2174 /* Don't confuse make-docfile by having two doc strings for this function.
2175 make-docfile does not pay attention to #if, for good reason! */
2176 0)
2177 (frame, cols, pretend)
2178 Lisp_Object frame, cols, pretend;
2179 {
2180 CHECK_NUMBER (cols, 0);
2181
2182 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2183 return Qnil;
2184 }
2185
2186 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2187 /* Don't confuse make-docfile by having two doc strings for this function.
2188 make-docfile does not pay attention to #if, for good reason! */
2189 0)
2190 (frame, cols, rows)
2191 Lisp_Object frame, cols, rows;
2192 {
2193 CHECK_NUMBER (cols, 2);
2194 CHECK_NUMBER (rows, 1);
2195
2196 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
2197
2198 return Qnil;
2199 }
2200 \f
2201 DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
2202 /* Don't confuse make-docfile by having two doc strings for this function.
2203 make-docfile does not pay attention to #if, for good reason! */
2204 0)
2205 (frame)
2206 Lisp_Object frame;
2207 {
2208 return make_number (FRAME_HEIGHT (selected_frame));
2209 }
2210
2211 DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
2212 /* Don't confuse make-docfile by having two doc strings for this function.
2213 make-docfile does not pay attention to #if, for good reason! */
2214 0)
2215 (frame)
2216 Lisp_Object frame;
2217 {
2218 return make_number (FRAME_WIDTH (selected_frame));
2219 }
2220
2221 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2222 0, 1, 0,
2223 /* Don't confuse make-docfile by having two doc strings for this function.
2224 make-docfile does not pay attention to #if, for good reason! */
2225 0)
2226 (frame)
2227 Lisp_Object frame;
2228 {
2229 return make_number (1);
2230 }
2231
2232
2233 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2234 0, 1, 0,
2235 /* Don't confuse make-docfile by having two doc strings for this function.
2236 make-docfile does not pay attention to #if, for good reason! */
2237 0)
2238 (frame)
2239 Lisp_Object frame;
2240 {
2241 return make_number (1);
2242 }
2243
2244 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2245 Sframe_pixel_height, 0, 1, 0,
2246 /* Don't confuse make-docfile by having two doc strings for this function.
2247 make-docfile does not pay attention to #if, for good reason! */
2248 0)
2249 (frame)
2250 Lisp_Object frame;
2251 {
2252 return make_number (FRAME_HEIGHT (f));
2253 }
2254
2255 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2256 Sframe_pixel_width, 0, 1, 0,
2257 /* Don't confuse make-docfile by having two doc strings for this function.
2258 make-docfile does not pay attention to #if, for good reason! */
2259 0)
2260 (frame)
2261 Lisp_Object frame;
2262 {
2263 return make_number (FRAME_WIDTH (f));
2264 }
2265
2266 /* These are for backward compatibility with Emacs 18. */
2267
2268 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
2269 /* Don't confuse make-docfile by having two doc strings for this function.
2270 make-docfile does not pay attention to #if, for good reason! */
2271 0)
2272 (lines, pretend)
2273 Lisp_Object lines, pretend;
2274 {
2275 CHECK_NUMBER (lines, 0);
2276
2277 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
2278 return Qnil;
2279 }
2280
2281 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
2282 /* Don't confuse make-docfile by having two doc strings for this function.
2283 make-docfile does not pay attention to #if, for good reason! */
2284 0)
2285 (cols, pretend)
2286 Lisp_Object cols, pretend;
2287 {
2288 CHECK_NUMBER (cols, 0);
2289
2290 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2291 return Qnil;
2292 }
2293
2294 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
2295 /* Don't confuse make-docfile by having two doc strings for this function.
2296 make-docfile does not pay attention to #if, for good reason! */
2297 0)
2298 ()
2299 {
2300 #ifdef HAVE_MOUSE
2301 if (mouse_position_hook)
2302 {
2303 FRAME_PTR f;
2304 Lisp_Object lispy_dummy;
2305 enum scroll_bar_part party_dummy;
2306 Lisp_Object x, y;
2307 unsigned long long_dummy;
2308
2309 (*mouse_position_hook) (&f, 0,
2310 &lispy_dummy, &party_dummy,
2311 &x, &y,
2312 &long_dummy);
2313 return Fcons (Fselected_frame (), Fcons (x, y));
2314 }
2315 #endif
2316 return Fcons (Qnil, Fcons (Qnil, Qnil));
2317 }
2318 \f
2319 void
2320 store_in_alist (alistptr, prop, val)
2321 Lisp_Object *alistptr, val;
2322 Lisp_Object prop;
2323 {
2324 register Lisp_Object tem;
2325
2326 tem = Fassq (prop, *alistptr);
2327 if (EQ (tem, Qnil))
2328 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2329 else
2330 Fsetcdr (tem, val);
2331 }
2332
2333 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2334 /* Don't confuse make-docfile by having two doc strings for this function.
2335 make-docfile does not pay attention to #if, for good reason! */
2336 0)
2337 (frame)
2338 Lisp_Object frame;
2339 {
2340 Lisp_Object alist;
2341 FRAME_PTR f;
2342
2343 if (EQ (frame, Qnil))
2344 f = selected_frame;
2345 else
2346 {
2347 CHECK_FRAME (frame, 0);
2348 f = XFRAME (frame);
2349 }
2350
2351 if (!FRAME_LIVE_P (f))
2352 return Qnil;
2353
2354 alist = Qnil;
2355 #ifdef MSDOS
2356 if (FRAME_X_P (f))
2357 {
2358 static char *colornames[16] =
2359 {
2360 "black", "blue", "green", "cyan", "red", "magenta", "brown",
2361 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
2362 "lightred", "lightmagenta", "yellow", "white"
2363 };
2364 store_in_alist (&alist, intern ("foreground-color"),
2365 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
2366 store_in_alist (&alist, intern ("background-color"),
2367 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
2368 }
2369 #endif
2370 store_in_alist (&alist, intern ("font"), build_string ("default"));
2371 store_in_alist (&alist, Qname, build_string ("emacs"));
2372 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
2373 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
2374 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2375 store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
2376 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2377 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
2378
2379 return alist;
2380 }
2381
2382 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2383 Smodify_frame_parameters, 2, 2, 0,
2384 /* Don't confuse make-docfile by having two doc strings for this function.
2385 make-docfile does not pay attention to #if, for good reason! */
2386 0)
2387 (frame, alist)
2388 Lisp_Object frame, alist;
2389 {
2390 Lisp_Object tail, elt, prop, val;
2391 FRAME_PTR f;
2392
2393 if (NILP (frame))
2394 f = selected_frame;
2395 else
2396 {
2397 CHECK_LIVE_FRAME (frame, 0);
2398 f = XFRAME (frame);
2399 }
2400
2401 #ifdef MSDOS
2402 if (FRAME_X_P (frame))
2403 IT_set_frame_parameters (XFRAME (frame), alist);
2404 else
2405 #endif
2406 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
2407 {
2408 elt = Fcar (tail);
2409 prop = Fcar (elt);
2410 val = Fcdr (elt);
2411 if (EQ (prop, Qmenu_bar_lines))
2412 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2413 }
2414
2415 return Qnil;
2416 }
2417
2418 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
2419 /* Don't confuse make-docfile by having two doc strings for this function.
2420 make-docfile does not pay attention to #if, for good reason! */
2421 0)
2422 (frame)
2423 Lisp_Object frame;
2424 {
2425 return Qt;
2426 }
2427
2428 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p, 1, 1, 0,
2429 /* Don't confuse make-docfile by having two doc strings for this function.
2430 make-docfile does not pay attention to #if, for good reason! */
2431 0)
2432 (frame)
2433 Lisp_Object frame;
2434 {
2435 return Qt;
2436 }
2437
2438 DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0,
2439 /* Don't confuse make-docfile by having two doc strings for this function.
2440 make-docfile does not pay attention to #if, for good reason! */
2441 0)
2442 ()
2443 {
2444 return Fcons (Fselected_frame (), Qnil);
2445 }
2446 \f
2447 syms_of_frame ()
2448 {
2449 syms_of_frame_1 ();
2450
2451 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2452 /* Don't confuse make-docfile by having two doc strings for this variable.
2453 make-docfile does not pay attention to #if, for good reason! */
2454 0);
2455 XSETFASTINT (Vterminal_frame, 0);
2456
2457 defsubr (&Sselected_frame);
2458 defsubr (&Sactive_minibuffer_window);
2459 defsubr (&Swindow_frame);
2460 defsubr (&Sframe_first_window);
2461 defsubr (&Sframep);
2462 defsubr (&Sframe_char_height);
2463 defsubr (&Sframe_char_width);
2464 defsubr (&Sframe_pixel_height);
2465 defsubr (&Sframe_pixel_width);
2466 defsubr (&Sset_frame_height);
2467 defsubr (&Sset_frame_width);
2468 defsubr (&Sset_frame_size);
2469 defsubr (&Sset_screen_height);
2470 defsubr (&Sset_screen_width);
2471 defsubr (&Sframe_height);
2472 Ffset (intern ("screen-height"), intern ("frame-height"));
2473 defsubr (&Sframe_width);
2474 Ffset (intern ("screen-width"), intern ("frame-width"));
2475 defsubr (&Smouse_position);
2476 Ffset (intern ("mouse-pixel-position"), intern ("mouse-position"));
2477 defsubr (&Sframe_parameters);
2478 defsubr (&Smodify_frame_parameters);
2479 defsubr (&Sframe_live_p);
2480 defsubr (&Sframe_visible_p);
2481 defsubr (&Sframe_list);
2482
2483 #ifdef MSDOS
2484 /* A comment in dispnew.c says the_only_frame is not protected. */
2485 the_only_frame.face_alist = Qnil;
2486 staticpro (&the_only_frame.face_alist);
2487 the_only_frame.menu_bar_items = Qnil;
2488 staticpro (&the_only_frame.menu_bar_items);
2489 the_only_frame.menu_bar_vector = Qnil;
2490 staticpro (&the_only_frame.menu_bar_vector);
2491 the_only_frame.menu_bar_items = menu_bar_items (Qnil);
2492 #endif
2493 }
2494
2495 keys_of_frame ()
2496 {
2497 }
2498
2499 #endif /* not MULTI_FRAME */