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