]> code.delx.au - gnu-emacs/blob - src/frame.c
Declare Fuser_full_name as Lisp_Object in advance to
[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 if (terminal_frame_count == 1)
506 {
507 f->name = build_string ("Emacs");
508 }
509 else
510 {
511 sprintf (name, "Emacs-%d", terminal_frame_count);
512 f->name = build_string (name);
513 }
514
515 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
516 f->async_visible = 1; /* Don't let visible be cleared later. */
517 #ifdef MSDOS
518 f->output_data.x = &the_only_x_display;
519 f->output_method = output_msdos_raw;
520 init_frame_faces (f);
521 #else /* not MSDOS */
522 f->output_data.nothing = 1; /* Nonzero means frame isn't deleted. */
523 #endif
524 return f;
525 }
526
527 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
528 1, 1, 0, "Create an additional terminal frame.\n\
529 You can create multiple frames on a text-only terminal in this way.\n\
530 Only the selected terminal frame is actually displayed.\n\
531 This function takes one argument, an alist specifying frame parameters.\n\
532 In practice, generally you don't need to specify any parameters.\n\
533 Note that changing the size of one terminal frame automatically affects all.")
534 (parms)
535 Lisp_Object parms;
536 {
537 struct frame *f;
538 Lisp_Object frame;
539
540 #ifdef MSDOS
541 if (selected_frame->output_method != output_msdos_raw)
542 abort ();
543 #else
544 if (selected_frame->output_method != output_termcap)
545 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
546 #endif
547
548 f = make_terminal_frame ();
549 change_frame_size (f, FRAME_HEIGHT (selected_frame),
550 FRAME_WIDTH (selected_frame), 0, 0);
551 remake_frame_glyphs (f);
552 calculate_costs (f);
553 XSETFRAME (frame, f);
554 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
555 Fmodify_frame_parameters (frame, parms);
556 f->face_alist = selected_frame->face_alist;
557 return frame;
558 }
559 \f
560 Lisp_Object
561 do_switch_frame (frame, no_enter, track)
562 Lisp_Object frame, no_enter;
563 int track;
564 {
565 /* If FRAME is a switch-frame event, extract the frame we should
566 switch to. */
567 if (CONSP (frame)
568 && EQ (XCONS (frame)->car, Qswitch_frame)
569 && CONSP (XCONS (frame)->cdr))
570 frame = XCONS (XCONS (frame)->cdr)->car;
571
572 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
573 a switch-frame event to arrive after a frame is no longer live,
574 especially when deleting the initial frame during startup. */
575 CHECK_FRAME (frame, 0);
576 if (! FRAME_LIVE_P (XFRAME (frame)))
577 return Qnil;
578
579 if (selected_frame == XFRAME (frame))
580 return frame;
581
582 /* This is too greedy; it causes inappropriate focus redirection
583 that's hard to get rid of. */
584 #if 0
585 /* If a frame's focus has been redirected toward the currently
586 selected frame, we should change the redirection to point to the
587 newly selected frame. This means that if the focus is redirected
588 from a minibufferless frame to a surrogate minibuffer frame, we
589 can use `other-window' to switch between all the frames using
590 that minibuffer frame, and the focus redirection will follow us
591 around. */
592 if (track)
593 {
594 Lisp_Object tail;
595
596 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
597 {
598 Lisp_Object focus;
599
600 if (!FRAMEP (XCONS (tail)->car))
601 abort ();
602
603 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
604
605 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
606 Fredirect_frame_focus (XCONS (tail)->car, frame);
607 }
608 }
609 #else /* ! 0 */
610 /* Instead, apply it only to the frame we're pointing to. */
611 #ifdef HAVE_WINDOW_SYSTEM
612 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
613 {
614 Lisp_Object focus, xfocus;
615
616 xfocus = x_get_focus_frame (XFRAME (frame));
617 if (FRAMEP (xfocus))
618 {
619 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
620 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
621 Fredirect_frame_focus (xfocus, frame);
622 }
623 }
624 #endif /* HAVE_X_WINDOWS */
625 #endif /* ! 0 */
626
627 selected_frame = XFRAME (frame);
628 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
629 last_nonminibuf_frame = selected_frame;
630
631 Fselect_window (XFRAME (frame)->selected_window);
632
633 /* We want to make sure that the next event generates a frame-switch
634 event to the appropriate frame. This seems kludgy to me, but
635 before you take it out, make sure that evaluating something like
636 (select-window (frame-root-window (new-frame))) doesn't end up
637 with your typing being interpreted in the new frame instead of
638 the one you're actually typing in. */
639 internal_last_event_frame = Qnil;
640
641 return frame;
642 }
643
644 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
645 "Select the frame FRAME.\n\
646 Subsequent editing commands apply to its selected window.\n\
647 The selection of FRAME lasts until the next time the user does\n\
648 something to select a different frame, or until the next time this\n\
649 function is called.")
650 (frame, no_enter)
651 Lisp_Object frame, no_enter;
652 {
653 return do_switch_frame (frame, no_enter, 1);
654 }
655
656
657 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
658 "Handle a switch-frame event EVENT.\n\
659 Switch-frame events are usually bound to this function.\n\
660 A switch-frame event tells Emacs that the window manager has requested\n\
661 that the user's events be directed to the frame mentioned in the event.\n\
662 This function selects the selected window of the frame of EVENT.\n\
663 \n\
664 If EVENT is frame object, handle it as if it were a switch-frame event\n\
665 to that frame.")
666 (event, no_enter)
667 Lisp_Object event, no_enter;
668 {
669 /* Preserve prefix arg that the command loop just cleared. */
670 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
671 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
672 return do_switch_frame (event, no_enter, 0);
673 }
674
675 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
676 "Do nothing, but preserve any prefix argument already specified.\n\
677 This is a suitable binding for iconify-frame and make-frame-visible.")
678 ()
679 {
680 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
681 return Qnil;
682 }
683
684 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
685 "Return the frame that is now selected.")
686 ()
687 {
688 Lisp_Object tem;
689 XSETFRAME (tem, selected_frame);
690 return tem;
691 }
692 \f
693 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
694 "Return the frame object that window WINDOW is on.")
695 (window)
696 Lisp_Object window;
697 {
698 CHECK_LIVE_WINDOW (window, 0);
699 return XWINDOW (window)->frame;
700 }
701
702 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
703 "Returns the topmost, leftmost window of FRAME.\n\
704 If omitted, FRAME defaults to the currently selected frame.")
705 (frame)
706 Lisp_Object frame;
707 {
708 Lisp_Object w;
709
710 if (NILP (frame))
711 w = selected_frame->root_window;
712 else
713 {
714 CHECK_LIVE_FRAME (frame, 0);
715 w = XFRAME (frame)->root_window;
716 }
717 while (NILP (XWINDOW (w)->buffer))
718 {
719 if (! NILP (XWINDOW (w)->hchild))
720 w = XWINDOW (w)->hchild;
721 else if (! NILP (XWINDOW (w)->vchild))
722 w = XWINDOW (w)->vchild;
723 else
724 abort ();
725 }
726 return w;
727 }
728
729 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
730 Sactive_minibuffer_window, 0, 0, 0,
731 "Return the currently active minibuffer window, or nil if none.")
732 ()
733 {
734 return minibuf_level ? minibuf_window : Qnil;
735 }
736
737 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
738 "Returns the root-window of FRAME.\n\
739 If omitted, FRAME defaults to the currently selected frame.")
740 (frame)
741 Lisp_Object frame;
742 {
743 if (NILP (frame))
744 XSETFRAME (frame, selected_frame);
745 else
746 CHECK_LIVE_FRAME (frame, 0);
747
748 return XFRAME (frame)->root_window;
749 }
750
751 DEFUN ("frame-selected-window", Fframe_selected_window,
752 Sframe_selected_window, 0, 1, 0,
753 "Return the selected window of frame object FRAME.\n\
754 If omitted, FRAME defaults to the currently selected frame.")
755 (frame)
756 Lisp_Object frame;
757 {
758 if (NILP (frame))
759 XSETFRAME (frame, selected_frame);
760 else
761 CHECK_LIVE_FRAME (frame, 0);
762
763 return XFRAME (frame)->selected_window;
764 }
765
766 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
767 Sset_frame_selected_window, 2, 2, 0,
768 "Set the selected window of frame object FRAME to WINDOW.\n\
769 If FRAME is nil, the selected frame is used.\n\
770 If FRAME is the selected frame, this makes WINDOW the selected window.")
771 (frame, window)
772 Lisp_Object frame, window;
773 {
774 if (NILP (frame))
775 XSETFRAME (frame, selected_frame);
776 else
777 CHECK_LIVE_FRAME (frame, 0);
778
779 CHECK_LIVE_WINDOW (window, 1);
780
781 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
782 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
783
784 if (XFRAME (frame) == selected_frame)
785 return Fselect_window (window);
786
787 return XFRAME (frame)->selected_window = window;
788 }
789 \f
790 DEFUN ("frame-list", Fframe_list, Sframe_list,
791 0, 0, 0,
792 "Return a list of all frames.")
793 ()
794 {
795 return Fcopy_sequence (Vframe_list);
796 }
797
798 /* Return the next frame in the frame list after FRAME.
799 If MINIBUF is nil, exclude minibuffer-only frames.
800 If MINIBUF is a window, include only its own frame
801 and any frame now using that window as the minibuffer.
802 If MINIBUF is `visible', include all visible frames.
803 If MINIBUF is 0, include all visible and iconified frames.
804 Otherwise, include all frames. */
805
806 Lisp_Object
807 next_frame (frame, minibuf)
808 Lisp_Object frame;
809 Lisp_Object minibuf;
810 {
811 Lisp_Object tail;
812 int passed = 0;
813
814 /* There must always be at least one frame in Vframe_list. */
815 if (! CONSP (Vframe_list))
816 abort ();
817
818 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
819 forever. Forestall that. */
820 CHECK_LIVE_FRAME (frame, 0);
821
822 while (1)
823 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
824 {
825 Lisp_Object f;
826
827 f = XCONS (tail)->car;
828
829 if (passed
830 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
831 {
832 /* Decide whether this frame is eligible to be returned. */
833
834 /* If we've looped all the way around without finding any
835 eligible frames, return the original frame. */
836 if (EQ (f, frame))
837 return f;
838
839 /* Let minibuf decide if this frame is acceptable. */
840 if (NILP (minibuf))
841 {
842 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
843 return f;
844 }
845 else if (EQ (minibuf, Qvisible))
846 {
847 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
848 if (FRAME_VISIBLE_P (XFRAME (f)))
849 return f;
850 }
851 else if (XFASTINT (minibuf) == 0)
852 {
853 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
854 if (FRAME_VISIBLE_P (XFRAME (f))
855 || FRAME_ICONIFIED_P (XFRAME (f)))
856 return f;
857 }
858 else if (WINDOWP (minibuf))
859 {
860 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
861 /* Check that F either is, or has forwarded its focus to,
862 MINIBUF's frame. */
863 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
864 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
865 FRAME_FOCUS_FRAME (XFRAME (f)))))
866 return f;
867 }
868 else
869 return f;
870 }
871
872 if (EQ (frame, f))
873 passed++;
874 }
875 }
876
877 /* Return the previous frame in the frame list before FRAME.
878 If MINIBUF is nil, exclude minibuffer-only frames.
879 If MINIBUF is a window, include only its own frame
880 and any frame now using that window as the minibuffer.
881 If MINIBUF is `visible', include all visible frames.
882 If MINIBUF is 0, include all visible and iconified frames.
883 Otherwise, include all frames. */
884
885 Lisp_Object
886 prev_frame (frame, minibuf)
887 Lisp_Object frame;
888 Lisp_Object minibuf;
889 {
890 Lisp_Object tail;
891 Lisp_Object prev;
892
893 /* There must always be at least one frame in Vframe_list. */
894 if (! CONSP (Vframe_list))
895 abort ();
896
897 prev = Qnil;
898 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
899 {
900 Lisp_Object f;
901
902 f = XCONS (tail)->car;
903 if (!FRAMEP (f))
904 abort ();
905
906 if (EQ (frame, f) && !NILP (prev))
907 return prev;
908
909 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
910 {
911 /* Decide whether this frame is eligible to be returned,
912 according to minibuf. */
913 if (NILP (minibuf))
914 {
915 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
916 prev = f;
917 }
918 else if (WINDOWP (minibuf))
919 {
920 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
921 /* Check that F either is, or has forwarded its focus to,
922 MINIBUF's frame. */
923 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
924 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
925 FRAME_FOCUS_FRAME (XFRAME (f)))))
926 prev = f;
927 }
928 else if (EQ (minibuf, Qvisible))
929 {
930 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
931 if (FRAME_VISIBLE_P (XFRAME (f)))
932 prev = f;
933 }
934 else if (XFASTINT (minibuf) == 0)
935 {
936 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
937 if (FRAME_VISIBLE_P (XFRAME (f))
938 || FRAME_ICONIFIED_P (XFRAME (f)))
939 prev = f;
940 }
941 else
942 prev = f;
943 }
944 }
945
946 /* We've scanned the entire list. */
947 if (NILP (prev))
948 /* We went through the whole frame list without finding a single
949 acceptable frame. Return the original frame. */
950 return frame;
951 else
952 /* There were no acceptable frames in the list before FRAME; otherwise,
953 we would have returned directly from the loop. Since PREV is the last
954 acceptable frame in the list, return it. */
955 return prev;
956 }
957
958
959 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
960 "Return the next frame in the frame list after FRAME.\n\
961 It considers only frames on the same terminal as FRAME.\n\
962 By default, skip minibuffer-only frames.\n\
963 If omitted, FRAME defaults to the selected frame.\n\
964 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
965 If MINIFRAME is a window, include only its own frame\n\
966 and any frame now using that window as the minibuffer.\n\
967 If MINIFRAME is `visible', include all visible frames.\n\
968 If MINIFRAME is 0, include all visible and iconified frames.\n\
969 Otherwise, include all frames.")
970 (frame, miniframe)
971 Lisp_Object frame, miniframe;
972 {
973 Lisp_Object tail;
974
975 if (NILP (frame))
976 XSETFRAME (frame, selected_frame);
977 else
978 CHECK_LIVE_FRAME (frame, 0);
979
980 return next_frame (frame, miniframe);
981 }
982
983 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
984 "Return the previous frame in the frame list before FRAME.\n\
985 It considers only frames on the same terminal as FRAME.\n\
986 By default, skip minibuffer-only frames.\n\
987 If omitted, FRAME defaults to the selected frame.\n\
988 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
989 If MINIFRAME is a window, include only its own frame\n\
990 and any frame now using that window as the minibuffer.\n\
991 If MINIFRAME is `visible', include all visible frames.\n\
992 If MINIFRAME is 0, include all visible and iconified frames.\n\
993 Otherwise, include all frames.")
994 (frame, miniframe)
995 Lisp_Object frame, miniframe;
996 {
997 Lisp_Object tail;
998
999 if (NILP (frame))
1000 XSETFRAME (frame, selected_frame);
1001 else
1002 CHECK_LIVE_FRAME (frame, 0);
1003
1004 return prev_frame (frame, miniframe);
1005 }
1006 \f
1007 /* Return 1 if it is ok to delete frame F;
1008 0 if all frames aside from F are invisible.
1009 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1010
1011 int
1012 other_visible_frames (f)
1013 FRAME_PTR f;
1014 {
1015 /* We know the selected frame is visible,
1016 so if F is some other frame, it can't be the sole visible one. */
1017 if (f == selected_frame)
1018 {
1019 Lisp_Object frames;
1020 int count = 0;
1021
1022 for (frames = Vframe_list;
1023 CONSP (frames);
1024 frames = XCONS (frames)->cdr)
1025 {
1026 Lisp_Object this;
1027
1028 this = XCONS (frames)->car;
1029 /* Verify that the frame's window still exists
1030 and we can still talk to it. And note any recent change
1031 in visibility. */
1032 #ifdef HAVE_WINDOW_SYSTEM
1033 if (FRAME_WINDOW_P (XFRAME (this)))
1034 {
1035 x_sync (XFRAME (this));
1036 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1037 }
1038 #endif
1039
1040 if (FRAME_VISIBLE_P (XFRAME (this))
1041 || FRAME_ICONIFIED_P (XFRAME (this))
1042 /* Allow deleting the terminal frame when at least
1043 one X frame exists! */
1044 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1045 count++;
1046 }
1047 return count > 1;
1048 }
1049 return 1;
1050 }
1051
1052 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1053 "Delete FRAME, permanently eliminating it from use.\n\
1054 If omitted, FRAME defaults to the selected frame.\n\
1055 A frame may not be deleted if its minibuffer is used by other frames.\n\
1056 Normally, you may not delete a frame if all other frames are invisible,\n\
1057 but if the second optional argument FORCE is non-nil, you may do so.")
1058 (frame, force)
1059 Lisp_Object frame, force;
1060 {
1061 struct frame *f;
1062 int minibuffer_selected;
1063
1064 if (EQ (frame, Qnil))
1065 {
1066 f = selected_frame;
1067 XSETFRAME (frame, f);
1068 }
1069 else
1070 {
1071 CHECK_FRAME (frame, 0);
1072 f = XFRAME (frame);
1073 }
1074
1075 if (! FRAME_LIVE_P (f))
1076 return Qnil;
1077
1078 if (NILP (force) && !other_visible_frames (f))
1079 error ("Attempt to delete the sole visible or iconified frame");
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 (f->namebuf)
1153 free (f->namebuf);
1154 if (FRAME_CURRENT_GLYPHS (f))
1155 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
1156 if (FRAME_DESIRED_GLYPHS (f))
1157 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
1158 if (FRAME_TEMP_GLYPHS (f))
1159 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
1160 if (FRAME_INSERT_COST (f))
1161 free (FRAME_INSERT_COST (f));
1162 if (FRAME_DELETEN_COST (f))
1163 free (FRAME_DELETEN_COST (f));
1164 if (FRAME_INSERTN_COST (f))
1165 free (FRAME_INSERTN_COST (f));
1166 if (FRAME_DELETE_COST (f))
1167 free (FRAME_DELETE_COST (f));
1168 if (FRAME_MESSAGE_BUF (f))
1169 free (FRAME_MESSAGE_BUF (f));
1170
1171 #ifdef HAVE_WINDOW_SYSTEM
1172 /* Free all fontset data. */
1173 free_fontset_data (FRAME_FONTSET_DATA (f));
1174 #endif
1175
1176 /* Since some events are handled at the interrupt level, we may get
1177 an event for f at any time; if we zero out the frame's display
1178 now, then we may trip up the event-handling code. Instead, we'll
1179 promise that the display of the frame must be valid until we have
1180 called the window-system-dependent frame destruction routine. */
1181
1182 /* I think this should be done with a hook. */
1183 #ifdef HAVE_WINDOW_SYSTEM
1184 if (FRAME_WINDOW_P (f))
1185 x_destroy_window (f);
1186 #endif
1187
1188 f->output_data.nothing = 0;
1189
1190 /* If we've deleted the last_nonminibuf_frame, then try to find
1191 another one. */
1192 if (f == last_nonminibuf_frame)
1193 {
1194 Lisp_Object frames;
1195
1196 last_nonminibuf_frame = 0;
1197
1198 for (frames = Vframe_list;
1199 CONSP (frames);
1200 frames = XCONS (frames)->cdr)
1201 {
1202 f = XFRAME (XCONS (frames)->car);
1203 if (!FRAME_MINIBUF_ONLY_P (f))
1204 {
1205 last_nonminibuf_frame = f;
1206 break;
1207 }
1208 }
1209 }
1210
1211 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1212 find another one. Prefer minibuffer-only frames, but also notice
1213 frames with other windows. */
1214 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1215 {
1216 Lisp_Object frames;
1217
1218 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1219 Lisp_Object frame_with_minibuf;
1220 /* Some frame we found on the same kboard, or nil if there are none. */
1221 Lisp_Object frame_on_same_kboard;
1222
1223 frame_on_same_kboard = Qnil;
1224 frame_with_minibuf = Qnil;
1225
1226 for (frames = Vframe_list;
1227 CONSP (frames);
1228 frames = XCONS (frames)->cdr)
1229 {
1230 Lisp_Object this;
1231 struct frame *f1;
1232
1233 this = XCONS (frames)->car;
1234 if (!FRAMEP (this))
1235 abort ();
1236 f1 = XFRAME (this);
1237
1238 /* Consider only frames on the same kboard
1239 and only those with minibuffers. */
1240 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1241 && FRAME_HAS_MINIBUF_P (f1))
1242 {
1243 frame_with_minibuf = this;
1244 if (FRAME_MINIBUF_ONLY_P (f1))
1245 break;
1246 }
1247
1248 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1249 frame_on_same_kboard = this;
1250 }
1251
1252 if (!NILP (frame_on_same_kboard))
1253 {
1254 /* We know that there must be some frame with a minibuffer out
1255 there. If this were not true, all of the frames present
1256 would have to be minibufferless, which implies that at some
1257 point their minibuffer frames must have been deleted, but
1258 that is prohibited at the top; you can't delete surrogate
1259 minibuffer frames. */
1260 if (NILP (frame_with_minibuf))
1261 abort ();
1262
1263 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1264 }
1265 else
1266 /* No frames left on this kboard--say no minibuffer either. */
1267 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1268 }
1269
1270 /* Cause frame titles to update--necessary if we now have just one frame. */
1271 update_mode_lines = 1;
1272
1273 return Qnil;
1274 }
1275 \f
1276 /* Return mouse position in character cell units. */
1277
1278 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1279 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1280 The position is given in character cells, where (0, 0) is the\n\
1281 upper-left corner.\n\
1282 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1283 to read the mouse position, it returns the selected frame for FRAME\n\
1284 and nil for X and Y.")
1285 ()
1286 {
1287 FRAME_PTR f;
1288 Lisp_Object lispy_dummy;
1289 enum scroll_bar_part party_dummy;
1290 Lisp_Object x, y;
1291 int col, row;
1292 unsigned long long_dummy;
1293
1294 f = selected_frame;
1295 x = y = Qnil;
1296
1297 #ifdef HAVE_MOUSE
1298 /* It's okay for the hook to refrain from storing anything. */
1299 if (mouse_position_hook)
1300 (*mouse_position_hook) (&f, 0,
1301 &lispy_dummy, &party_dummy,
1302 &x, &y,
1303 &long_dummy);
1304 if (! NILP (x))
1305 {
1306 col = XINT (x);
1307 row = XINT (y);
1308 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1309 XSETINT (x, col);
1310 XSETINT (y, row);
1311 }
1312 #endif
1313 XSETFRAME (lispy_dummy, f);
1314 return Fcons (lispy_dummy, Fcons (x, y));
1315 }
1316
1317 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1318 Smouse_pixel_position, 0, 0, 0,
1319 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1320 The position is given in pixel units, where (0, 0) is the\n\
1321 upper-left corner.\n\
1322 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1323 to read the mouse position, it returns the selected frame for FRAME\n\
1324 and nil for X and Y.")
1325 ()
1326 {
1327 FRAME_PTR f;
1328 Lisp_Object lispy_dummy;
1329 enum scroll_bar_part party_dummy;
1330 Lisp_Object x, y;
1331 int col, row;
1332 unsigned long long_dummy;
1333
1334 f = selected_frame;
1335 x = y = Qnil;
1336
1337 #ifdef HAVE_MOUSE
1338 /* It's okay for the hook to refrain from storing anything. */
1339 if (mouse_position_hook)
1340 (*mouse_position_hook) (&f, 0,
1341 &lispy_dummy, &party_dummy,
1342 &x, &y,
1343 &long_dummy);
1344 #endif
1345 XSETFRAME (lispy_dummy, f);
1346 return Fcons (lispy_dummy, Fcons (x, y));
1347 }
1348
1349 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1350 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1351 Note, this is a no-op for an X frame that is not visible.\n\
1352 If you have just created a frame, you must wait for it to become visible\n\
1353 before calling this function on it, like this.\n\
1354 (while (not (frame-visible-p frame)) (sleep-for .5))")
1355 (frame, x, y)
1356 Lisp_Object frame, x, y;
1357 {
1358 CHECK_LIVE_FRAME (frame, 0);
1359 CHECK_NUMBER (x, 2);
1360 CHECK_NUMBER (y, 1);
1361
1362 /* I think this should be done with a hook. */
1363 #ifdef HAVE_WINDOW_SYSTEM
1364 if (FRAME_WINDOW_P (XFRAME (frame)))
1365 /* Warping the mouse will cause enternotify and focus events. */
1366 x_set_mouse_position (XFRAME (frame), x, y);
1367 #else
1368 #if defined (MSDOS) && defined (HAVE_MOUSE)
1369 if (FRAME_MSDOS_P (XFRAME (frame)))
1370 {
1371 Fselect_frame (frame, Qnil);
1372 mouse_moveto (XINT (x), XINT (y));
1373 }
1374 #endif
1375 #endif
1376
1377 return Qnil;
1378 }
1379
1380 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1381 Sset_mouse_pixel_position, 3, 3, 0,
1382 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1383 Note, this is a no-op for an X frame that is not visible.\n\
1384 If you have just created a frame, you must wait for it to become visible\n\
1385 before calling this function on it, like this.\n\
1386 (while (not (frame-visible-p frame)) (sleep-for .5))")
1387 (frame, x, y)
1388 Lisp_Object frame, x, y;
1389 {
1390 CHECK_LIVE_FRAME (frame, 0);
1391 CHECK_NUMBER (x, 2);
1392 CHECK_NUMBER (y, 1);
1393
1394 /* I think this should be done with a hook. */
1395 #ifdef HAVE_WINDOW_SYSTEM
1396 if (FRAME_WINDOW_P (XFRAME (frame)))
1397 /* Warping the mouse will cause enternotify and focus events. */
1398 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1399 #else
1400 #if defined (MSDOS) && defined (HAVE_MOUSE)
1401 if (FRAME_MSDOS_P (XFRAME (frame)))
1402 {
1403 Fselect_frame (frame, Qnil);
1404 mouse_moveto (XINT (x), XINT (y));
1405 }
1406 #endif
1407 #endif
1408
1409 return Qnil;
1410 }
1411 \f
1412 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1413 0, 1, "",
1414 "Make the frame FRAME visible (assuming it is an X-window).\n\
1415 If omitted, FRAME defaults to the currently selected frame.")
1416 (frame)
1417 Lisp_Object frame;
1418 {
1419 if (NILP (frame))
1420 XSETFRAME (frame, selected_frame);
1421
1422 CHECK_LIVE_FRAME (frame, 0);
1423
1424 /* I think this should be done with a hook. */
1425 #ifdef HAVE_WINDOW_SYSTEM
1426 if (FRAME_WINDOW_P (XFRAME (frame)))
1427 {
1428 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1429 x_make_frame_visible (XFRAME (frame));
1430 }
1431 #endif
1432
1433 /* Make menu bar update for the Buffers and Frams menus. */
1434 windows_or_buffers_changed++;
1435
1436 return frame;
1437 }
1438
1439 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1440 0, 2, "",
1441 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1442 If omitted, FRAME defaults to the currently selected frame.\n\
1443 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1444 but if the second optional argument FORCE is non-nil, you may do so.")
1445 (frame, force)
1446 Lisp_Object frame, force;
1447 {
1448 if (NILP (frame))
1449 XSETFRAME (frame, selected_frame);
1450
1451 CHECK_LIVE_FRAME (frame, 0);
1452
1453 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1454 error ("Attempt to make invisible the sole visible or iconified frame");
1455
1456 #if 0 /* This isn't logically necessary, and it can do GC. */
1457 /* Don't let the frame remain selected. */
1458 if (XFRAME (frame) == selected_frame)
1459 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1460 #endif
1461
1462 /* Don't allow minibuf_window to remain on a deleted frame. */
1463 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1464 {
1465 Fset_window_buffer (selected_frame->minibuffer_window,
1466 XWINDOW (minibuf_window)->buffer);
1467 minibuf_window = selected_frame->minibuffer_window;
1468 }
1469
1470 /* I think this should be done with a hook. */
1471 #ifdef HAVE_WINDOW_SYSTEM
1472 if (FRAME_WINDOW_P (XFRAME (frame)))
1473 x_make_frame_invisible (XFRAME (frame));
1474 #endif
1475
1476 /* Make menu bar update for the Buffers and Frams menus. */
1477 windows_or_buffers_changed++;
1478
1479 return Qnil;
1480 }
1481
1482 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1483 0, 1, "",
1484 "Make the frame FRAME into an icon.\n\
1485 If omitted, FRAME defaults to the currently selected frame.")
1486 (frame)
1487 Lisp_Object frame;
1488 {
1489 if (NILP (frame))
1490 XSETFRAME (frame, selected_frame);
1491
1492 CHECK_LIVE_FRAME (frame, 0);
1493
1494 #if 0 /* This isn't logically necessary, and it can do GC. */
1495 /* Don't let the frame remain selected. */
1496 if (XFRAME (frame) == selected_frame)
1497 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1498 #endif
1499
1500 /* Don't allow minibuf_window to remain on a deleted frame. */
1501 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1502 {
1503 Fset_window_buffer (selected_frame->minibuffer_window,
1504 XWINDOW (minibuf_window)->buffer);
1505 minibuf_window = selected_frame->minibuffer_window;
1506 }
1507
1508 /* I think this should be done with a hook. */
1509 #ifdef HAVE_WINDOW_SYSTEM
1510 if (FRAME_WINDOW_P (XFRAME (frame)))
1511 x_iconify_frame (XFRAME (frame));
1512 #endif
1513
1514 /* Make menu bar update for the Buffers and Frams menus. */
1515 windows_or_buffers_changed++;
1516
1517 return Qnil;
1518 }
1519
1520 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1521 1, 1, 0,
1522 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1523 A frame that is not \"visible\" is not updated and, if it works through\n\
1524 a window system, it may not show at all.\n\
1525 Return the symbol `icon' if frame is visible only as an icon.")
1526 (frame)
1527 Lisp_Object frame;
1528 {
1529 CHECK_LIVE_FRAME (frame, 0);
1530
1531 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1532
1533 if (FRAME_VISIBLE_P (XFRAME (frame)))
1534 return Qt;
1535 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1536 return Qicon;
1537 return Qnil;
1538 }
1539
1540 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1541 0, 0, 0,
1542 "Return a list of all frames now \"visible\" (being updated).")
1543 ()
1544 {
1545 Lisp_Object tail, frame;
1546 struct frame *f;
1547 Lisp_Object value;
1548
1549 value = Qnil;
1550 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1551 {
1552 frame = XCONS (tail)->car;
1553 if (!FRAMEP (frame))
1554 continue;
1555 f = XFRAME (frame);
1556 if (FRAME_VISIBLE_P (f))
1557 value = Fcons (frame, value);
1558 }
1559 return value;
1560 }
1561
1562
1563 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1564 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1565 If FRAME is invisible, make it visible.\n\
1566 If you don't specify a frame, the selected frame is used.\n\
1567 If Emacs is displaying on an ordinary terminal or some other device which\n\
1568 doesn't support multiple overlapping frames, this function does nothing.")
1569 (frame)
1570 Lisp_Object frame;
1571 {
1572 if (NILP (frame))
1573 XSETFRAME (frame, selected_frame);
1574
1575 CHECK_LIVE_FRAME (frame, 0);
1576
1577 /* Do like the documentation says. */
1578 Fmake_frame_visible (frame);
1579
1580 if (frame_raise_lower_hook)
1581 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1582
1583 return Qnil;
1584 }
1585
1586 /* Should we have a corresponding function called Flower_Power? */
1587 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1588 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1589 If you don't specify a frame, the selected frame is used.\n\
1590 If Emacs is displaying on an ordinary terminal or some other device which\n\
1591 doesn't support multiple overlapping frames, this function does nothing.")
1592 (frame)
1593 Lisp_Object frame;
1594 {
1595 if (NILP (frame))
1596 XSETFRAME (frame, selected_frame);
1597
1598 CHECK_LIVE_FRAME (frame, 0);
1599
1600 if (frame_raise_lower_hook)
1601 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1602
1603 return Qnil;
1604 }
1605
1606 \f
1607 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1608 1, 2, 0,
1609 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1610 In other words, switch-frame events caused by events in FRAME will\n\
1611 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1612 FOCUS-FRAME after reading an event typed at FRAME.\n\
1613 \n\
1614 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1615 cancelled, and the frame again receives its own keystrokes.\n\
1616 \n\
1617 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1618 a surrogate minibuffer frame when a frame doesn't have its own\n\
1619 minibuffer window.\n\
1620 \n\
1621 A frame's focus redirection can be changed by select-frame. If frame\n\
1622 FOO is selected, and then a different frame BAR is selected, any\n\
1623 frames redirecting their focus to FOO are shifted to redirect their\n\
1624 focus to BAR. This allows focus redirection to work properly when the\n\
1625 user switches from one frame to another using `select-window'.\n\
1626 \n\
1627 This means that a frame whose focus is redirected to itself is treated\n\
1628 differently from a frame whose focus is redirected to nil; the former\n\
1629 is affected by select-frame, while the latter is not.\n\
1630 \n\
1631 The redirection lasts until `redirect-frame-focus' is called to change it.")
1632 (frame, focus_frame)
1633 Lisp_Object frame, focus_frame;
1634 {
1635 /* Note that we don't check for a live frame here. It's reasonable
1636 to redirect the focus of a frame you're about to delete, if you
1637 know what other frame should receive those keystrokes. */
1638 CHECK_FRAME (frame, 0);
1639
1640 if (! NILP (focus_frame))
1641 CHECK_LIVE_FRAME (focus_frame, 1);
1642
1643 XFRAME (frame)->focus_frame = focus_frame;
1644
1645 if (frame_rehighlight_hook)
1646 (*frame_rehighlight_hook) (XFRAME (frame));
1647
1648 return Qnil;
1649 }
1650
1651
1652 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1653 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1654 This returns nil if FRAME's focus is not redirected.\n\
1655 See `redirect-frame-focus'.")
1656 (frame)
1657 Lisp_Object frame;
1658 {
1659 CHECK_LIVE_FRAME (frame, 0);
1660
1661 return FRAME_FOCUS_FRAME (XFRAME (frame));
1662 }
1663
1664
1665 \f
1666 /* Return the value of frame parameter PROP in frame FRAME. */
1667
1668 Lisp_Object
1669 get_frame_param (frame, prop)
1670 register struct frame *frame;
1671 Lisp_Object prop;
1672 {
1673 register Lisp_Object tem;
1674
1675 tem = Fassq (prop, frame->param_alist);
1676 if (EQ (tem, Qnil))
1677 return tem;
1678 return Fcdr (tem);
1679 }
1680
1681 /* Return the buffer-predicate of the selected frame. */
1682
1683 Lisp_Object
1684 frame_buffer_predicate ()
1685 {
1686 return selected_frame->buffer_predicate;
1687 }
1688
1689 /* Return the buffer-list of the selected frame. */
1690
1691 Lisp_Object
1692 frame_buffer_list ()
1693 {
1694 return selected_frame->buffer_list;
1695 }
1696
1697 /* Set the buffer-list of the selected frame. */
1698
1699 void
1700 set_frame_buffer_list (list)
1701 Lisp_Object list;
1702 {
1703 selected_frame->buffer_list = list;
1704 }
1705
1706 /* Discard BUFFER from the buffer-list of each frame. */
1707
1708 void
1709 frames_discard_buffer (buffer)
1710 Lisp_Object buffer;
1711 {
1712 Lisp_Object frame, tail;
1713
1714 FOR_EACH_FRAME (tail, frame)
1715 {
1716 XFRAME (frame)->buffer_list
1717 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1718 }
1719 }
1720
1721 /* Move BUFFER to the end of the buffer-list of each frame. */
1722
1723 void
1724 frames_bury_buffer (buffer)
1725 Lisp_Object buffer;
1726 {
1727 Lisp_Object frame, tail;
1728
1729 FOR_EACH_FRAME (tail, frame)
1730 {
1731 XFRAME (frame)->buffer_list
1732 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1733 Fcons (buffer, Qnil));
1734 }
1735 }
1736
1737 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1738 If the alist already has an element for PROP, we change it. */
1739
1740 void
1741 store_in_alist (alistptr, prop, val)
1742 Lisp_Object *alistptr, val;
1743 Lisp_Object prop;
1744 {
1745 register Lisp_Object tem;
1746
1747 tem = Fassq (prop, *alistptr);
1748 if (EQ (tem, Qnil))
1749 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1750 else
1751 Fsetcdr (tem, val);
1752 }
1753
1754 void
1755 store_frame_param (f, prop, val)
1756 struct frame *f;
1757 Lisp_Object prop, val;
1758 {
1759 register Lisp_Object tem;
1760
1761 if (EQ (prop, Qbuffer_list))
1762 {
1763 f->buffer_list = val;
1764 return;
1765 }
1766
1767 tem = Fassq (prop, f->param_alist);
1768 if (EQ (tem, Qnil))
1769 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1770 else
1771 Fsetcdr (tem, val);
1772
1773 if (EQ (prop, Qbuffer_predicate))
1774 f->buffer_predicate = val;
1775
1776 if (! FRAME_WINDOW_P (f))
1777 if (EQ (prop, Qmenu_bar_lines))
1778 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1779
1780 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1781 {
1782 if (! MINI_WINDOW_P (XWINDOW (val)))
1783 error ("Surrogate minibuffer windows must be minibuffer windows.");
1784
1785 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1786 && !EQ (val, f->minibuffer_window))
1787 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1788
1789 /* Install the chosen minibuffer window, with proper buffer. */
1790 f->minibuffer_window = val;
1791 }
1792 }
1793
1794 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1795 "Return the parameters-alist of frame FRAME.\n\
1796 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1797 The meaningful PARMs depend on the kind of frame.\n\
1798 If FRAME is omitted, return information on the currently selected frame.")
1799 (frame)
1800 Lisp_Object frame;
1801 {
1802 Lisp_Object alist;
1803 FRAME_PTR f;
1804 int height, width;
1805
1806 if (EQ (frame, Qnil))
1807 f = selected_frame;
1808 else
1809 {
1810 CHECK_FRAME (frame, 0);
1811 f = XFRAME (frame);
1812 }
1813
1814 if (!FRAME_LIVE_P (f))
1815 return Qnil;
1816
1817 alist = Fcopy_alist (f->param_alist);
1818 #ifdef MSDOS
1819 if (FRAME_MSDOS_P (f))
1820 {
1821 static char *colornames[16] =
1822 {
1823 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1824 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1825 "lightred", "lightmagenta", "yellow", "white"
1826 };
1827 store_in_alist (&alist, intern ("foreground-color"),
1828 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
1829 store_in_alist (&alist, intern ("background-color"),
1830 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
1831 }
1832 store_in_alist (&alist, intern ("font"), build_string ("default"));
1833 #endif
1834 store_in_alist (&alist, Qname, f->name);
1835 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
1836 store_in_alist (&alist, Qheight, make_number (height));
1837 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
1838 store_in_alist (&alist, Qwidth, make_number (width));
1839 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
1840 store_in_alist (&alist, Qminibuffer,
1841 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1842 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1843 : FRAME_MINIBUF_WINDOW (f)));
1844 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
1845 store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
1846
1847 /* I think this should be done with a hook. */
1848 #ifdef HAVE_WINDOW_SYSTEM
1849 if (FRAME_WINDOW_P (f))
1850 x_report_frame_params (f, &alist);
1851 else
1852 #endif
1853 {
1854 /* This ought to be correct in f->param_alist for an X frame. */
1855 Lisp_Object lines;
1856 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
1857 store_in_alist (&alist, Qmenu_bar_lines, lines);
1858 }
1859 return alist;
1860 }
1861
1862 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1863 Smodify_frame_parameters, 2, 2, 0,
1864 "Modify the parameters of frame FRAME according to ALIST.\n\
1865 ALIST is an alist of parameters to change and their new values.\n\
1866 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1867 The meaningful PARMs depend on the kind of frame.\n\
1868 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1869 so that `frame-parameters' will return them.")
1870 (frame, alist)
1871 Lisp_Object frame, alist;
1872 {
1873 FRAME_PTR f;
1874 register Lisp_Object tail, elt, prop, val;
1875
1876 if (EQ (frame, Qnil))
1877 f = selected_frame;
1878 else
1879 {
1880 CHECK_LIVE_FRAME (frame, 0);
1881 f = XFRAME (frame);
1882 }
1883
1884 /* I think this should be done with a hook. */
1885 #ifdef HAVE_WINDOW_SYSTEM
1886 if (FRAME_WINDOW_P (f))
1887 x_set_frame_parameters (f, alist);
1888 else
1889 #endif
1890 #ifdef MSDOS
1891 if (FRAME_MSDOS_P (f))
1892 IT_set_frame_parameters (f, alist);
1893 else
1894 #endif
1895 {
1896 int length = XINT (Flength (alist));
1897 int i;
1898 Lisp_Object *parms
1899 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1900 Lisp_Object *values
1901 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1902
1903 /* Extract parm names and values into those vectors. */
1904
1905 i = 0;
1906 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
1907 {
1908 Lisp_Object elt, prop, val;
1909
1910 elt = Fcar (tail);
1911 parms[i] = Fcar (elt);
1912 values[i] = Fcdr (elt);
1913 i++;
1914 }
1915
1916 /* Now process them in reverse of specified order. */
1917 for (i--; i >= 0; i--)
1918 {
1919 prop = parms[i];
1920 val = values[i];
1921 store_frame_param (f, prop, val);
1922 }
1923 }
1924
1925 return Qnil;
1926 }
1927 \f
1928 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1929 0, 1, 0,
1930 "Height in pixels of a line in the font in frame FRAME.\n\
1931 If FRAME is omitted, the selected frame is used.\n\
1932 For a terminal frame, the value is always 1.")
1933 (frame)
1934 Lisp_Object frame;
1935 {
1936 struct frame *f;
1937
1938 if (NILP (frame))
1939 f = selected_frame;
1940 else
1941 {
1942 CHECK_FRAME (frame, 0);
1943 f = XFRAME (frame);
1944 }
1945
1946 #ifdef HAVE_WINDOW_SYSTEM
1947 if (FRAME_WINDOW_P (f))
1948 return make_number (x_char_height (f));
1949 else
1950 #endif
1951 return make_number (1);
1952 }
1953
1954
1955 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1956 0, 1, 0,
1957 "Width in pixels of characters in the font in frame FRAME.\n\
1958 If FRAME is omitted, the selected frame is used.\n\
1959 The width is the same for all characters, because\n\
1960 currently Emacs supports only fixed-width fonts.\n\
1961 For a terminal screen, the value is always 1.")
1962 (frame)
1963 Lisp_Object frame;
1964 {
1965 struct frame *f;
1966
1967 if (NILP (frame))
1968 f = selected_frame;
1969 else
1970 {
1971 CHECK_FRAME (frame, 0);
1972 f = XFRAME (frame);
1973 }
1974
1975 #ifdef HAVE_WINDOW_SYSTEM
1976 if (FRAME_WINDOW_P (f))
1977 return make_number (x_char_width (f));
1978 else
1979 #endif
1980 return make_number (1);
1981 }
1982
1983 DEFUN ("frame-pixel-height", Fframe_pixel_height,
1984 Sframe_pixel_height, 0, 1, 0,
1985 "Return a FRAME's height in pixels.\n\
1986 For a terminal frame, the result really gives the height in characters.\n\
1987 If FRAME is omitted, the selected frame is used.")
1988 (frame)
1989 Lisp_Object frame;
1990 {
1991 struct frame *f;
1992
1993 if (NILP (frame))
1994 f = selected_frame;
1995 else
1996 {
1997 CHECK_FRAME (frame, 0);
1998 f = XFRAME (frame);
1999 }
2000
2001 #ifdef HAVE_WINDOW_SYSTEM
2002 if (FRAME_WINDOW_P (f))
2003 return make_number (x_pixel_height (f));
2004 else
2005 #endif
2006 return make_number (FRAME_HEIGHT (f));
2007 }
2008
2009 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2010 Sframe_pixel_width, 0, 1, 0,
2011 "Return FRAME's width in pixels.\n\
2012 For a terminal frame, the result really gives the width in characters.\n\
2013 If FRAME is omitted, the selected frame is used.")
2014 (frame)
2015 Lisp_Object frame;
2016 {
2017 struct frame *f;
2018
2019 if (NILP (frame))
2020 f = selected_frame;
2021 else
2022 {
2023 CHECK_FRAME (frame, 0);
2024 f = XFRAME (frame);
2025 }
2026
2027 #ifdef HAVE_WINDOW_SYSTEM
2028 if (FRAME_WINDOW_P (f))
2029 return make_number (x_pixel_width (f));
2030 else
2031 #endif
2032 return make_number (FRAME_WIDTH (f));
2033 }
2034 \f
2035 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2036 "Specify that the frame FRAME has LINES lines.\n\
2037 Optional third arg non-nil means that redisplay should use LINES lines\n\
2038 but that the idea of the actual height of the frame should not be changed.")
2039 (frame, lines, pretend)
2040 Lisp_Object frame, lines, pretend;
2041 {
2042 register struct frame *f;
2043
2044 CHECK_NUMBER (lines, 0);
2045 if (NILP (frame))
2046 f = selected_frame;
2047 else
2048 {
2049 CHECK_LIVE_FRAME (frame, 0);
2050 f = XFRAME (frame);
2051 }
2052
2053 /* I think this should be done with a hook. */
2054 #ifdef HAVE_WINDOW_SYSTEM
2055 if (FRAME_WINDOW_P (f))
2056 {
2057 if (XINT (lines) != f->height)
2058 x_set_window_size (f, 1, f->width, XINT (lines));
2059 }
2060 else
2061 #endif
2062 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
2063 return Qnil;
2064 }
2065
2066 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2067 "Specify that the frame FRAME has COLS columns.\n\
2068 Optional third arg non-nil means that redisplay should use COLS columns\n\
2069 but that the idea of the actual width of the frame should not be changed.")
2070 (frame, cols, pretend)
2071 Lisp_Object frame, cols, pretend;
2072 {
2073 register struct frame *f;
2074 CHECK_NUMBER (cols, 0);
2075 if (NILP (frame))
2076 f = selected_frame;
2077 else
2078 {
2079 CHECK_LIVE_FRAME (frame, 0);
2080 f = XFRAME (frame);
2081 }
2082
2083 /* I think this should be done with a hook. */
2084 #ifdef HAVE_WINDOW_SYSTEM
2085 if (FRAME_WINDOW_P (f))
2086 {
2087 if (XINT (cols) != f->width)
2088 x_set_window_size (f, 1, XINT (cols), f->height);
2089 }
2090 else
2091 #endif
2092 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
2093 return Qnil;
2094 }
2095
2096 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2097 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2098 (frame, cols, rows)
2099 Lisp_Object frame, cols, rows;
2100 {
2101 register struct frame *f;
2102 int mask;
2103
2104 CHECK_LIVE_FRAME (frame, 0);
2105 CHECK_NUMBER (cols, 2);
2106 CHECK_NUMBER (rows, 1);
2107 f = XFRAME (frame);
2108
2109 /* I think this should be done with a hook. */
2110 #ifdef HAVE_WINDOW_SYSTEM
2111 if (FRAME_WINDOW_P (f))
2112 {
2113 if (XINT (rows) != f->height || XINT (cols) != f->width
2114 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2115 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2116 }
2117 else
2118 #endif
2119 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
2120
2121 return Qnil;
2122 }
2123
2124 DEFUN ("set-frame-position", Fset_frame_position,
2125 Sset_frame_position, 3, 3, 0,
2126 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2127 This is actually the position of the upper left corner of the frame.\n\
2128 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2129 the rightmost or bottommost possible position (that stays within the screen).")
2130 (frame, xoffset, yoffset)
2131 Lisp_Object frame, xoffset, yoffset;
2132 {
2133 register struct frame *f;
2134 int mask;
2135
2136 CHECK_LIVE_FRAME (frame, 0);
2137 CHECK_NUMBER (xoffset, 1);
2138 CHECK_NUMBER (yoffset, 2);
2139 f = XFRAME (frame);
2140
2141 /* I think this should be done with a hook. */
2142 #ifdef HAVE_WINDOW_SYSTEM
2143 if (FRAME_WINDOW_P (f))
2144 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2145 #endif
2146
2147 return Qt;
2148 }
2149
2150 \f
2151 syms_of_frame ()
2152 {
2153 syms_of_frame_1 ();
2154
2155 staticpro (&Vframe_list);
2156
2157 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2158 "The initial frame-object, which represents Emacs's stdout.");
2159
2160 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2161 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2162 Vemacs_iconified = Qnil;
2163
2164 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2165 "Minibufferless frames use this frame's minibuffer.\n\
2166 \n\
2167 Emacs cannot create minibufferless frames unless this is set to an\n\
2168 appropriate surrogate.\n\
2169 \n\
2170 Emacs consults this variable only when creating minibufferless\n\
2171 frames; once the frame is created, it sticks with its assigned\n\
2172 minibuffer, no matter what this variable is set to. This means that\n\
2173 this variable doesn't necessarily say anything meaningful about the\n\
2174 current set of frames, or where the minibuffer is currently being\n\
2175 displayed.");
2176
2177 defsubr (&Sactive_minibuffer_window);
2178 defsubr (&Sframep);
2179 defsubr (&Sframe_live_p);
2180 defsubr (&Smake_terminal_frame);
2181 defsubr (&Shandle_switch_frame);
2182 defsubr (&Signore_event);
2183 defsubr (&Sselect_frame);
2184 defsubr (&Sselected_frame);
2185 defsubr (&Swindow_frame);
2186 defsubr (&Sframe_root_window);
2187 defsubr (&Sframe_first_window);
2188 defsubr (&Sframe_selected_window);
2189 defsubr (&Sset_frame_selected_window);
2190 defsubr (&Sframe_list);
2191 defsubr (&Snext_frame);
2192 defsubr (&Sprevious_frame);
2193 defsubr (&Sdelete_frame);
2194 defsubr (&Smouse_position);
2195 defsubr (&Smouse_pixel_position);
2196 defsubr (&Sset_mouse_position);
2197 defsubr (&Sset_mouse_pixel_position);
2198 #if 0
2199 defsubr (&Sframe_configuration);
2200 defsubr (&Srestore_frame_configuration);
2201 #endif
2202 defsubr (&Smake_frame_visible);
2203 defsubr (&Smake_frame_invisible);
2204 defsubr (&Siconify_frame);
2205 defsubr (&Sframe_visible_p);
2206 defsubr (&Svisible_frame_list);
2207 defsubr (&Sraise_frame);
2208 defsubr (&Slower_frame);
2209 defsubr (&Sredirect_frame_focus);
2210 defsubr (&Sframe_focus);
2211 defsubr (&Sframe_parameters);
2212 defsubr (&Smodify_frame_parameters);
2213 defsubr (&Sframe_char_height);
2214 defsubr (&Sframe_char_width);
2215 defsubr (&Sframe_pixel_height);
2216 defsubr (&Sframe_pixel_width);
2217 defsubr (&Sset_frame_height);
2218 defsubr (&Sset_frame_width);
2219 defsubr (&Sset_frame_size);
2220 defsubr (&Sset_frame_position);
2221 }
2222
2223 keys_of_frame ()
2224 {
2225 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2226 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2227 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2228 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2229 }