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