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