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