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