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