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