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