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