Fix -Wimplicit warnings.
[bpt/emacs.git] / 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 #include "xterm.h"
32 #endif
33 #include "frame.h"
34 #include "termhooks.h"
35 #include "dispextern.h"
36 #include "window.h"
37 #ifdef MSDOS
38 #include "msdos.h"
39 #endif
40
41 /* Evaluate this expression to rebuild the section of syms_of_frame
42 that initializes and staticpros the symbols declared below. Note
43 that Emacs 18 has a bug that keeps C-x C-e from being able to
44 evaluate this expression.
45
46 (progn
47 ;; Accumulate a list of the symbols we want to initialize from the
48 ;; declarations at the top of the file.
49 (goto-char (point-min))
50 (search-forward "/\*&&& symbols declared here &&&*\/\n")
51 (let (symbol-list)
52 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
53 (setq symbol-list
54 (cons (buffer-substring (match-beginning 1) (match-end 1))
55 symbol-list))
56 (forward-line 1))
57 (setq symbol-list (nreverse symbol-list))
58 ;; Delete the section of syms_of_... where we initialize the symbols.
59 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
60 (let ((start (point)))
61 (while (looking-at "^ Q")
62 (forward-line 2))
63 (kill-region start (point)))
64 ;; Write a new symbol initialization section.
65 (while symbol-list
66 (insert (format " %s = intern (\"" (car symbol-list)))
67 (let ((start (point)))
68 (insert (substring (car symbol-list) 1))
69 (subst-char-in-region start (point) ?_ ?-))
70 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
71 (setq symbol-list (cdr symbol-list)))))
72 */
73
74 /*&&& symbols declared here &&&*/
75 Lisp_Object Qframep;
76 Lisp_Object Qframe_live_p;
77 Lisp_Object Qheight;
78 Lisp_Object Qicon;
79 Lisp_Object Qminibuffer;
80 Lisp_Object Qmodeline;
81 Lisp_Object Qname;
82 Lisp_Object Qonly;
83 Lisp_Object Qunsplittable;
84 Lisp_Object Qmenu_bar_lines;
85 Lisp_Object Qwidth;
86 Lisp_Object Qx;
87 Lisp_Object Qw32;
88 Lisp_Object Qpc;
89 Lisp_Object Qvisible;
90 Lisp_Object Qbuffer_predicate;
91 Lisp_Object Qbuffer_list;
92 Lisp_Object Qtitle;
93
94 Lisp_Object Vterminal_frame;
95 Lisp_Object Vdefault_frame_alist;
96
97 static void
98 syms_of_frame_1 ()
99 {
100 /*&&& init symbols here &&&*/
101 Qframep = intern ("framep");
102 staticpro (&Qframep);
103 Qframe_live_p = intern ("frame-live-p");
104 staticpro (&Qframe_live_p);
105 Qheight = intern ("height");
106 staticpro (&Qheight);
107 Qicon = intern ("icon");
108 staticpro (&Qicon);
109 Qminibuffer = intern ("minibuffer");
110 staticpro (&Qminibuffer);
111 Qmodeline = intern ("modeline");
112 staticpro (&Qmodeline);
113 Qname = intern ("name");
114 staticpro (&Qname);
115 Qonly = intern ("only");
116 staticpro (&Qonly);
117 Qunsplittable = intern ("unsplittable");
118 staticpro (&Qunsplittable);
119 Qmenu_bar_lines = intern ("menu-bar-lines");
120 staticpro (&Qmenu_bar_lines);
121 Qwidth = intern ("width");
122 staticpro (&Qwidth);
123 Qx = intern ("x");
124 staticpro (&Qx);
125 Qw32 = intern ("w32");
126 staticpro (&Qw32);
127 Qpc = intern ("pc");
128 staticpro (&Qpc);
129 Qvisible = intern ("visible");
130 staticpro (&Qvisible);
131 Qbuffer_predicate = intern ("buffer-predicate");
132 staticpro (&Qbuffer_predicate);
133 Qbuffer_list = intern ("buffer-list");
134 staticpro (&Qbuffer_list);
135 Qtitle = intern ("title");
136 staticpro (&Qtitle);
137
138 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
139 "Alist of default values for frame creation.\n\
140 These may be set in your init file, like this:\n\
141 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
142 These override values given in window system configuration data,\n\
143 including X Windows' defaults database.\n\
144 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
145 For values specific to the separate minibuffer frame, see\n\
146 `minibuffer-frame-alist'.\n\
147 The `menu-bar-lines' element of the list controls whether new frames\n\
148 have menu bars; `menu-bar-mode' works by altering this element.");
149 Vdefault_frame_alist = Qnil;
150 }
151 \f
152 static void
153 set_menu_bar_lines_1 (window, n)
154 Lisp_Object window;
155 int n;
156 {
157 struct window *w = XWINDOW (window);
158
159 XSETFASTINT (w->last_modified, 0);
160 XSETFASTINT (w->top, XFASTINT (w->top) + n);
161 XSETFASTINT (w->height, XFASTINT (w->height) - n);
162
163 /* Handle just the top child in a vertical split. */
164 if (!NILP (w->vchild))
165 set_menu_bar_lines_1 (w->vchild, n);
166
167 /* Adjust all children in a horizontal split. */
168 for (window = w->hchild; !NILP (window); window = w->next)
169 {
170 w = XWINDOW (window);
171 set_menu_bar_lines_1 (window, n);
172 }
173 }
174
175 void
176 set_menu_bar_lines (f, value, oldval)
177 struct frame *f;
178 Lisp_Object value, oldval;
179 {
180 int nlines;
181 int olines = FRAME_MENU_BAR_LINES (f);
182
183 /* Right now, menu bars don't work properly in minibuf-only frames;
184 most of the commands try to apply themselves to the minibuffer
185 frame itself, and get an error because you can't switch buffers
186 in or split the minibuffer window. */
187 if (FRAME_MINIBUF_ONLY_P (f))
188 return;
189
190 if (INTEGERP (value))
191 nlines = XINT (value);
192 else
193 nlines = 0;
194
195 if (nlines != olines)
196 {
197 windows_or_buffers_changed++;
198 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
199 FRAME_MENU_BAR_LINES (f) = nlines;
200 set_menu_bar_lines_1 (f->root_window, nlines - olines);
201 }
202 }
203 \f
204 #include "buffer.h"
205
206 /* These help us bind and responding to switch-frame events. */
207 #include "commands.h"
208 #include "keyboard.h"
209
210 Lisp_Object Vemacs_iconified;
211 Lisp_Object Vframe_list;
212
213 extern Lisp_Object Vminibuffer_list;
214 extern Lisp_Object get_minibuffer ();
215 extern Lisp_Object Fhandle_switch_frame ();
216 extern Lisp_Object Fredirect_frame_focus ();
217 extern Lisp_Object x_get_focus_frame ();
218 \f
219 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
220 "Return non-nil if OBJECT is a frame.\n\
221 Value is t for a termcap frame (a character-only terminal),\n\
222 `x' for an Emacs frame that is really an X window,\n\
223 `pc' for a direct-write MS-DOS frame.\n\
224 See also `frame-live-p'.")
225 (object)
226 Lisp_Object object;
227 {
228 if (!FRAMEP (object))
229 return Qnil;
230 switch (XFRAME (object)->output_method)
231 {
232 case output_termcap:
233 return Qt;
234 case output_x_window:
235 return Qx;
236 case output_w32:
237 return Qw32;
238 case output_msdos_raw:
239 return Qpc;
240 default:
241 abort ();
242 }
243 }
244
245 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
246 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
247 Value is nil if OBJECT is not a live frame. If object is a live\n\
248 frame, the return value indicates what sort of output device it is\n\
249 displayed on. Value is t for a termcap frame (a character-only\n\
250 terminal), `x' for an Emacs frame being displayed in an X window.")
251 (object)
252 Lisp_Object object;
253 {
254 return ((FRAMEP (object)
255 && FRAME_LIVE_P (XFRAME (object)))
256 ? Fframep (object)
257 : Qnil);
258 }
259
260 struct frame *
261 make_frame (mini_p)
262 int mini_p;
263 {
264 Lisp_Object frame;
265 register struct frame *f;
266 register Lisp_Object root_window;
267 register Lisp_Object mini_window;
268 register struct Lisp_Vector *vec;
269 int i;
270
271 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
272 for (i = 0; i < VECSIZE (struct frame); i++)
273 XSETFASTINT (vec->contents[i], 0);
274 vec->size = VECSIZE (struct frame);
275 f = (struct frame *)vec;
276 XSETFRAME (frame, f);
277
278 f->cursor_x = 0;
279 f->cursor_y = 0;
280 f->current_glyphs = 0;
281 f->desired_glyphs = 0;
282 f->visible = 0;
283 f->async_visible = 0;
284 f->output_data.nothing = 0;
285 f->iconified = 0;
286 f->async_iconified = 0;
287 f->wants_modeline = 1;
288 f->auto_raise = 0;
289 f->auto_lower = 0;
290 f->no_split = 0;
291 f->garbaged = 0;
292 f->has_minibuffer = mini_p;
293 f->focus_frame = Qnil;
294 f->explicit_name = 0;
295 f->can_have_scroll_bars = 0;
296 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
297 f->param_alist = Qnil;
298 f->scroll_bars = Qnil;
299 f->condemned_scroll_bars = Qnil;
300 f->face_alist = Qnil;
301 f->menu_bar_items = Qnil;
302 f->menu_bar_vector = Qnil;
303 f->menu_bar_items_used = 0;
304 f->buffer_predicate = Qnil;
305 f->buffer_list = Qnil;
306 #ifdef MULTI_KBOARD
307 f->kboard = initial_kboard;
308 #endif
309 f->namebuf = 0;
310 f->title = Qnil;
311
312 root_window = make_window ();
313 if (mini_p)
314 {
315 mini_window = make_window ();
316 XWINDOW (root_window)->next = mini_window;
317 XWINDOW (mini_window)->prev = root_window;
318 XWINDOW (mini_window)->mini_p = Qt;
319 XWINDOW (mini_window)->frame = frame;
320 f->minibuffer_window = mini_window;
321 }
322 else
323 {
324 mini_window = Qnil;
325 XWINDOW (root_window)->next = Qnil;
326 f->minibuffer_window = Qnil;
327 }
328
329 XWINDOW (root_window)->frame = frame;
330
331 /* 10 is arbitrary,
332 just so that there is "something there."
333 Correct size will be set up later with change_frame_size. */
334
335 SET_FRAME_WIDTH (f, 10);
336 f->height = 10;
337
338 XSETFASTINT (XWINDOW (root_window)->width, 10);
339 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
340
341 if (mini_p)
342 {
343 XSETFASTINT (XWINDOW (mini_window)->width, 10);
344 XSETFASTINT (XWINDOW (mini_window)->top, 9);
345 XSETFASTINT (XWINDOW (mini_window)->height, 1);
346 }
347
348 /* Choose a buffer for the frame's root window. */
349 {
350 Lisp_Object buf;
351
352 XWINDOW (root_window)->buffer = Qt;
353 buf = Fcurrent_buffer ();
354 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
355 a space), try to find another one. */
356 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
357 buf = Fother_buffer (buf, Qnil);
358 Fset_window_buffer (root_window, buf);
359
360 f->buffer_list = Fcons (buf, Qnil);
361 }
362
363 if (mini_p)
364 {
365 XWINDOW (mini_window)->buffer = Qt;
366 Fset_window_buffer (mini_window,
367 (NILP (Vminibuffer_list)
368 ? get_minibuffer (0)
369 : Fcar (Vminibuffer_list)));
370 }
371
372 f->root_window = root_window;
373 f->selected_window = root_window;
374 /* Make sure this window seems more recently used than
375 a newly-created, never-selected window. */
376 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
377
378 #ifdef HAVE_WINDOW_SYSTEM
379 f->fontset_data = alloc_fontset_data ();
380 #endif
381
382 return f;
383 }
384 \f
385 #ifdef HAVE_WINDOW_SYSTEM
386 /* Make a frame using a separate minibuffer window on another frame.
387 MINI_WINDOW is the minibuffer window to use. nil means use the
388 default (the global minibuffer). */
389
390 struct frame *
391 make_frame_without_minibuffer (mini_window, kb, display)
392 register Lisp_Object mini_window;
393 KBOARD *kb;
394 Lisp_Object display;
395 {
396 register struct frame *f;
397 struct gcpro gcpro1;
398
399 if (!NILP (mini_window))
400 CHECK_LIVE_WINDOW (mini_window, 0);
401
402 #ifdef MULTI_KBOARD
403 if (!NILP (mini_window)
404 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
405 error ("frame and minibuffer must be on the same display");
406 #endif
407
408 /* Make a frame containing just a root window. */
409 f = make_frame (0);
410
411 if (NILP (mini_window))
412 {
413 /* Use default-minibuffer-frame if possible. */
414 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
415 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
416 {
417 Lisp_Object frame_dummy;
418
419 XSETFRAME (frame_dummy, f);
420 GCPRO1 (frame_dummy);
421 /* If there's no minibuffer frame to use, create one. */
422 kb->Vdefault_minibuffer_frame =
423 call1 (intern ("make-initial-minibuffer-frame"), display);
424 UNGCPRO;
425 }
426
427 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
428 }
429
430 f->minibuffer_window = mini_window;
431
432 /* Make the chosen minibuffer window display the proper minibuffer,
433 unless it is already showing a minibuffer. */
434 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
435 Fset_window_buffer (mini_window,
436 (NILP (Vminibuffer_list)
437 ? get_minibuffer (0)
438 : Fcar (Vminibuffer_list)));
439 return f;
440 }
441
442 /* Make a frame containing only a minibuffer window. */
443
444 struct frame *
445 make_minibuffer_frame ()
446 {
447 /* First make a frame containing just a root window, no minibuffer. */
448
449 register struct frame *f = make_frame (0);
450 register Lisp_Object mini_window;
451 register Lisp_Object frame;
452
453 XSETFRAME (frame, f);
454
455 f->auto_raise = 0;
456 f->auto_lower = 0;
457 f->no_split = 1;
458 f->wants_modeline = 0;
459 f->has_minibuffer = 1;
460
461 /* Now label the root window as also being the minibuffer.
462 Avoid infinite looping on the window chain by marking next pointer
463 as nil. */
464
465 mini_window = f->minibuffer_window = f->root_window;
466 XWINDOW (mini_window)->mini_p = Qt;
467 XWINDOW (mini_window)->next = Qnil;
468 XWINDOW (mini_window)->prev = Qnil;
469 XWINDOW (mini_window)->frame = frame;
470
471 /* Put the proper buffer in that window. */
472
473 Fset_window_buffer (mini_window,
474 (NILP (Vminibuffer_list)
475 ? get_minibuffer (0)
476 : Fcar (Vminibuffer_list)));
477 return f;
478 }
479 #endif /* HAVE_WINDOW_SYSTEM */
480 \f
481 /* Construct a frame that refers to the terminal (stdin and stdout). */
482
483 static int terminal_frame_count;
484
485 struct frame *
486 make_terminal_frame ()
487 {
488 register struct frame *f;
489 Lisp_Object frame;
490 char name[20];
491
492 #ifdef MULTI_KBOARD
493 if (!initial_kboard)
494 {
495 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
496 init_kboard (initial_kboard);
497 initial_kboard->next_kboard = all_kboards;
498 all_kboards = initial_kboard;
499 }
500 #endif
501
502 /* The first call must initialize Vframe_list. */
503 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
504 Vframe_list = Qnil;
505
506 f = make_frame (1);
507
508 XSETFRAME (frame, f);
509 Vframe_list = Fcons (frame, Vframe_list);
510
511 terminal_frame_count++;
512 sprintf (name, "F%d", terminal_frame_count);
513 f->name = build_string (name);
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 #if 0
1082 /* This is a nice idea, but x_connection_closed needs to be able
1083 to delete the last frame, if it is gone. */
1084 if (NILP (XCONS (Vframe_list)->cdr))
1085 error ("Attempt to delete the only frame");
1086 #endif
1087
1088 /* Does this frame have a minibuffer, and is it the surrogate
1089 minibuffer for any other frame? */
1090 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1091 {
1092 Lisp_Object frames;
1093
1094 for (frames = Vframe_list;
1095 CONSP (frames);
1096 frames = XCONS (frames)->cdr)
1097 {
1098 Lisp_Object this;
1099 this = XCONS (frames)->car;
1100
1101 if (! EQ (this, frame)
1102 && EQ (frame,
1103 WINDOW_FRAME (XWINDOW
1104 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1105 error ("Attempt to delete a surrogate minibuffer frame");
1106 }
1107 }
1108
1109 minibuffer_selected = EQ (minibuf_window, selected_window);
1110
1111 /* Don't let the frame remain selected. */
1112 if (f == selected_frame)
1113 {
1114 Lisp_Object tail, frame1;
1115
1116 /* Look for another visible frame on the same terminal. */
1117 frame1 = next_frame (frame, Qvisible);
1118
1119 /* If there is none, find *some* other frame. */
1120 if (NILP (frame1) || EQ (frame1, frame))
1121 {
1122 FOR_EACH_FRAME (tail, frame1)
1123 {
1124 if (! EQ (frame, frame1))
1125 break;
1126 }
1127 }
1128
1129 do_switch_frame (frame1, Qnil, 0);
1130 }
1131
1132 /* Don't allow minibuf_window to remain on a deleted frame. */
1133 if (EQ (f->minibuffer_window, minibuf_window))
1134 {
1135 Fset_window_buffer (selected_frame->minibuffer_window,
1136 XWINDOW (minibuf_window)->buffer);
1137 minibuf_window = selected_frame->minibuffer_window;
1138
1139 /* If the dying minibuffer window was selected,
1140 select the new one. */
1141 if (minibuffer_selected)
1142 Fselect_window (minibuf_window);
1143 }
1144
1145 /* Clear any X selections for this frame. */
1146 #ifdef HAVE_X_WINDOWS
1147 if (FRAME_X_P (f))
1148 x_clear_frame_selections (f);
1149 #endif
1150
1151 /* Mark all the windows that used to be on FRAME as deleted, and then
1152 remove the reference to them. */
1153 delete_all_subwindows (XWINDOW (f->root_window));
1154 f->root_window = Qnil;
1155
1156 Vframe_list = Fdelq (frame, Vframe_list);
1157 FRAME_SET_VISIBLE (f, 0);
1158
1159 if (echo_area_glyphs == FRAME_MESSAGE_BUF (f))
1160 {
1161 echo_area_glyphs = 0;
1162 previous_echo_glyphs = 0;
1163 }
1164
1165 if (f->namebuf)
1166 free (f->namebuf);
1167 if (FRAME_CURRENT_GLYPHS (f))
1168 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
1169 if (FRAME_DESIRED_GLYPHS (f))
1170 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
1171 if (FRAME_TEMP_GLYPHS (f))
1172 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
1173 if (FRAME_INSERT_COST (f))
1174 free (FRAME_INSERT_COST (f));
1175 if (FRAME_DELETEN_COST (f))
1176 free (FRAME_DELETEN_COST (f));
1177 if (FRAME_INSERTN_COST (f))
1178 free (FRAME_INSERTN_COST (f));
1179 if (FRAME_DELETE_COST (f))
1180 free (FRAME_DELETE_COST (f));
1181 if (FRAME_MESSAGE_BUF (f))
1182 free (FRAME_MESSAGE_BUF (f));
1183
1184 #ifdef HAVE_WINDOW_SYSTEM
1185 /* Free all fontset data. */
1186 free_fontset_data (FRAME_FONTSET_DATA (f));
1187 #endif
1188
1189 /* Since some events are handled at the interrupt level, we may get
1190 an event for f at any time; if we zero out the frame's display
1191 now, then we may trip up the event-handling code. Instead, we'll
1192 promise that the display of the frame must be valid until we have
1193 called the window-system-dependent frame destruction routine. */
1194
1195 /* I think this should be done with a hook. */
1196 #ifdef HAVE_WINDOW_SYSTEM
1197 if (FRAME_WINDOW_P (f))
1198 x_destroy_window (f);
1199 #endif
1200
1201 f->output_data.nothing = 0;
1202
1203 /* If we've deleted the last_nonminibuf_frame, then try to find
1204 another one. */
1205 if (f == last_nonminibuf_frame)
1206 {
1207 Lisp_Object frames;
1208
1209 last_nonminibuf_frame = 0;
1210
1211 for (frames = Vframe_list;
1212 CONSP (frames);
1213 frames = XCONS (frames)->cdr)
1214 {
1215 f = XFRAME (XCONS (frames)->car);
1216 if (!FRAME_MINIBUF_ONLY_P (f))
1217 {
1218 last_nonminibuf_frame = f;
1219 break;
1220 }
1221 }
1222 }
1223
1224 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1225 find another one. Prefer minibuffer-only frames, but also notice
1226 frames with other windows. */
1227 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1228 {
1229 Lisp_Object frames;
1230
1231 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1232 Lisp_Object frame_with_minibuf;
1233 /* Some frame we found on the same kboard, or nil if there are none. */
1234 Lisp_Object frame_on_same_kboard;
1235
1236 frame_on_same_kboard = Qnil;
1237 frame_with_minibuf = Qnil;
1238
1239 for (frames = Vframe_list;
1240 CONSP (frames);
1241 frames = XCONS (frames)->cdr)
1242 {
1243 Lisp_Object this;
1244 struct frame *f1;
1245
1246 this = XCONS (frames)->car;
1247 if (!FRAMEP (this))
1248 abort ();
1249 f1 = XFRAME (this);
1250
1251 /* Consider only frames on the same kboard
1252 and only those with minibuffers. */
1253 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1254 && FRAME_HAS_MINIBUF_P (f1))
1255 {
1256 frame_with_minibuf = this;
1257 if (FRAME_MINIBUF_ONLY_P (f1))
1258 break;
1259 }
1260
1261 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1262 frame_on_same_kboard = this;
1263 }
1264
1265 if (!NILP (frame_on_same_kboard))
1266 {
1267 /* We know that there must be some frame with a minibuffer out
1268 there. If this were not true, all of the frames present
1269 would have to be minibufferless, which implies that at some
1270 point their minibuffer frames must have been deleted, but
1271 that is prohibited at the top; you can't delete surrogate
1272 minibuffer frames. */
1273 if (NILP (frame_with_minibuf))
1274 abort ();
1275
1276 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1277 }
1278 else
1279 /* No frames left on this kboard--say no minibuffer either. */
1280 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1281 }
1282
1283 /* Cause frame titles to update--necessary if we now have just one frame. */
1284 update_mode_lines = 1;
1285
1286 return Qnil;
1287 }
1288 \f
1289 /* Return mouse position in character cell units. */
1290
1291 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1292 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1293 The position is given in character cells, where (0, 0) is the\n\
1294 upper-left corner.\n\
1295 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1296 to read the mouse position, it returns the selected frame for FRAME\n\
1297 and nil for X and Y.")
1298 ()
1299 {
1300 FRAME_PTR f;
1301 Lisp_Object lispy_dummy;
1302 enum scroll_bar_part party_dummy;
1303 Lisp_Object x, y;
1304 int col, row;
1305 unsigned long long_dummy;
1306
1307 f = selected_frame;
1308 x = y = Qnil;
1309
1310 #ifdef HAVE_MOUSE
1311 /* It's okay for the hook to refrain from storing anything. */
1312 if (mouse_position_hook)
1313 (*mouse_position_hook) (&f, -1,
1314 &lispy_dummy, &party_dummy,
1315 &x, &y,
1316 &long_dummy);
1317 if (! NILP (x))
1318 {
1319 col = XINT (x);
1320 row = XINT (y);
1321 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1322 XSETINT (x, col);
1323 XSETINT (y, row);
1324 }
1325 #endif
1326 XSETFRAME (lispy_dummy, f);
1327 return Fcons (lispy_dummy, Fcons (x, y));
1328 }
1329
1330 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1331 Smouse_pixel_position, 0, 0, 0,
1332 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1333 The position is given in pixel units, where (0, 0) is the\n\
1334 upper-left corner.\n\
1335 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1336 to read the mouse position, it returns the selected frame for FRAME\n\
1337 and nil for X and Y.")
1338 ()
1339 {
1340 FRAME_PTR f;
1341 Lisp_Object lispy_dummy;
1342 enum scroll_bar_part party_dummy;
1343 Lisp_Object x, y;
1344 int col, row;
1345 unsigned long long_dummy;
1346
1347 f = selected_frame;
1348 x = y = Qnil;
1349
1350 #ifdef HAVE_MOUSE
1351 /* It's okay for the hook to refrain from storing anything. */
1352 if (mouse_position_hook)
1353 (*mouse_position_hook) (&f, -1,
1354 &lispy_dummy, &party_dummy,
1355 &x, &y,
1356 &long_dummy);
1357 #endif
1358 XSETFRAME (lispy_dummy, f);
1359 return Fcons (lispy_dummy, Fcons (x, y));
1360 }
1361
1362 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1363 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1364 Note, this is a no-op for an X frame that is not visible.\n\
1365 If you have just created a frame, you must wait for it to become visible\n\
1366 before calling this function on it, like this.\n\
1367 (while (not (frame-visible-p frame)) (sleep-for .5))")
1368 (frame, x, y)
1369 Lisp_Object frame, x, y;
1370 {
1371 CHECK_LIVE_FRAME (frame, 0);
1372 CHECK_NUMBER (x, 2);
1373 CHECK_NUMBER (y, 1);
1374
1375 /* I think this should be done with a hook. */
1376 #ifdef HAVE_WINDOW_SYSTEM
1377 if (FRAME_WINDOW_P (XFRAME (frame)))
1378 /* Warping the mouse will cause enternotify and focus events. */
1379 x_set_mouse_position (XFRAME (frame), x, y);
1380 #else
1381 #if defined (MSDOS) && defined (HAVE_MOUSE)
1382 if (FRAME_MSDOS_P (XFRAME (frame)))
1383 {
1384 Fselect_frame (frame, Qnil);
1385 mouse_moveto (XINT (x), XINT (y));
1386 }
1387 #endif
1388 #endif
1389
1390 return Qnil;
1391 }
1392
1393 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1394 Sset_mouse_pixel_position, 3, 3, 0,
1395 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1396 Note, this is a no-op for an X frame that is not visible.\n\
1397 If you have just created a frame, you must wait for it to become visible\n\
1398 before calling this function on it, like this.\n\
1399 (while (not (frame-visible-p frame)) (sleep-for .5))")
1400 (frame, x, y)
1401 Lisp_Object frame, x, y;
1402 {
1403 CHECK_LIVE_FRAME (frame, 0);
1404 CHECK_NUMBER (x, 2);
1405 CHECK_NUMBER (y, 1);
1406
1407 /* I think this should be done with a hook. */
1408 #ifdef HAVE_WINDOW_SYSTEM
1409 if (FRAME_WINDOW_P (XFRAME (frame)))
1410 /* Warping the mouse will cause enternotify and focus events. */
1411 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1412 #else
1413 #if defined (MSDOS) && defined (HAVE_MOUSE)
1414 if (FRAME_MSDOS_P (XFRAME (frame)))
1415 {
1416 Fselect_frame (frame, Qnil);
1417 mouse_moveto (XINT (x), XINT (y));
1418 }
1419 #endif
1420 #endif
1421
1422 return Qnil;
1423 }
1424 \f
1425 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1426 0, 1, "",
1427 "Make the frame FRAME visible (assuming it is an X-window).\n\
1428 If omitted, FRAME defaults to the currently selected frame.")
1429 (frame)
1430 Lisp_Object frame;
1431 {
1432 if (NILP (frame))
1433 XSETFRAME (frame, selected_frame);
1434
1435 CHECK_LIVE_FRAME (frame, 0);
1436
1437 /* I think this should be done with a hook. */
1438 #ifdef HAVE_WINDOW_SYSTEM
1439 if (FRAME_WINDOW_P (XFRAME (frame)))
1440 {
1441 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1442 x_make_frame_visible (XFRAME (frame));
1443 }
1444 #endif
1445
1446 /* Make menu bar update for the Buffers and Frams menus. */
1447 windows_or_buffers_changed++;
1448
1449 return frame;
1450 }
1451
1452 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1453 0, 2, "",
1454 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1455 If omitted, FRAME defaults to the currently selected frame.\n\
1456 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1457 but if the second optional argument FORCE is non-nil, you may do so.")
1458 (frame, force)
1459 Lisp_Object frame, force;
1460 {
1461 if (NILP (frame))
1462 XSETFRAME (frame, selected_frame);
1463
1464 CHECK_LIVE_FRAME (frame, 0);
1465
1466 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1467 error ("Attempt to make invisible the sole visible or iconified frame");
1468
1469 #if 0 /* This isn't logically necessary, and it can do GC. */
1470 /* Don't let the frame remain selected. */
1471 if (XFRAME (frame) == selected_frame)
1472 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1473 #endif
1474
1475 /* Don't allow minibuf_window to remain on a deleted frame. */
1476 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1477 {
1478 Fset_window_buffer (selected_frame->minibuffer_window,
1479 XWINDOW (minibuf_window)->buffer);
1480 minibuf_window = selected_frame->minibuffer_window;
1481 }
1482
1483 /* I think this should be done with a hook. */
1484 #ifdef HAVE_WINDOW_SYSTEM
1485 if (FRAME_WINDOW_P (XFRAME (frame)))
1486 x_make_frame_invisible (XFRAME (frame));
1487 #endif
1488
1489 /* Make menu bar update for the Buffers and Frams menus. */
1490 windows_or_buffers_changed++;
1491
1492 return Qnil;
1493 }
1494
1495 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1496 0, 1, "",
1497 "Make the frame FRAME into an icon.\n\
1498 If omitted, FRAME defaults to the currently selected frame.")
1499 (frame)
1500 Lisp_Object frame;
1501 {
1502 if (NILP (frame))
1503 XSETFRAME (frame, selected_frame);
1504
1505 CHECK_LIVE_FRAME (frame, 0);
1506
1507 #if 0 /* This isn't logically necessary, and it can do GC. */
1508 /* Don't let the frame remain selected. */
1509 if (XFRAME (frame) == selected_frame)
1510 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1511 #endif
1512
1513 /* Don't allow minibuf_window to remain on a deleted frame. */
1514 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1515 {
1516 Fset_window_buffer (selected_frame->minibuffer_window,
1517 XWINDOW (minibuf_window)->buffer);
1518 minibuf_window = selected_frame->minibuffer_window;
1519 }
1520
1521 /* I think this should be done with a hook. */
1522 #ifdef HAVE_WINDOW_SYSTEM
1523 if (FRAME_WINDOW_P (XFRAME (frame)))
1524 x_iconify_frame (XFRAME (frame));
1525 #endif
1526
1527 /* Make menu bar update for the Buffers and Frams menus. */
1528 windows_or_buffers_changed++;
1529
1530 return Qnil;
1531 }
1532
1533 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1534 1, 1, 0,
1535 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1536 A frame that is not \"visible\" is not updated and, if it works through\n\
1537 a window system, it may not show at all.\n\
1538 Return the symbol `icon' if frame is visible only as an icon.")
1539 (frame)
1540 Lisp_Object frame;
1541 {
1542 CHECK_LIVE_FRAME (frame, 0);
1543
1544 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1545
1546 if (FRAME_VISIBLE_P (XFRAME (frame)))
1547 return Qt;
1548 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1549 return Qicon;
1550 return Qnil;
1551 }
1552
1553 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1554 0, 0, 0,
1555 "Return a list of all frames now \"visible\" (being updated).")
1556 ()
1557 {
1558 Lisp_Object tail, frame;
1559 struct frame *f;
1560 Lisp_Object value;
1561
1562 value = Qnil;
1563 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1564 {
1565 frame = XCONS (tail)->car;
1566 if (!FRAMEP (frame))
1567 continue;
1568 f = XFRAME (frame);
1569 if (FRAME_VISIBLE_P (f))
1570 value = Fcons (frame, value);
1571 }
1572 return value;
1573 }
1574
1575
1576 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1577 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1578 If FRAME is invisible, make it visible.\n\
1579 If you don't specify a frame, the selected frame is used.\n\
1580 If Emacs is displaying on an ordinary terminal or some other device which\n\
1581 doesn't support multiple overlapping frames, this function does nothing.")
1582 (frame)
1583 Lisp_Object frame;
1584 {
1585 if (NILP (frame))
1586 XSETFRAME (frame, selected_frame);
1587
1588 CHECK_LIVE_FRAME (frame, 0);
1589
1590 /* Do like the documentation says. */
1591 Fmake_frame_visible (frame);
1592
1593 if (frame_raise_lower_hook)
1594 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1595
1596 return Qnil;
1597 }
1598
1599 /* Should we have a corresponding function called Flower_Power? */
1600 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1601 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1602 If you don't specify a frame, the selected frame is used.\n\
1603 If Emacs is displaying on an ordinary terminal or some other device which\n\
1604 doesn't support multiple overlapping frames, this function does nothing.")
1605 (frame)
1606 Lisp_Object frame;
1607 {
1608 if (NILP (frame))
1609 XSETFRAME (frame, selected_frame);
1610
1611 CHECK_LIVE_FRAME (frame, 0);
1612
1613 if (frame_raise_lower_hook)
1614 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1615
1616 return Qnil;
1617 }
1618
1619 \f
1620 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1621 1, 2, 0,
1622 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1623 In other words, switch-frame events caused by events in FRAME will\n\
1624 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1625 FOCUS-FRAME after reading an event typed at FRAME.\n\
1626 \n\
1627 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1628 cancelled, and the frame again receives its own keystrokes.\n\
1629 \n\
1630 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1631 a surrogate minibuffer frame when a frame doesn't have its own\n\
1632 minibuffer window.\n\
1633 \n\
1634 A frame's focus redirection can be changed by select-frame. If frame\n\
1635 FOO is selected, and then a different frame BAR is selected, any\n\
1636 frames redirecting their focus to FOO are shifted to redirect their\n\
1637 focus to BAR. This allows focus redirection to work properly when the\n\
1638 user switches from one frame to another using `select-window'.\n\
1639 \n\
1640 This means that a frame whose focus is redirected to itself is treated\n\
1641 differently from a frame whose focus is redirected to nil; the former\n\
1642 is affected by select-frame, while the latter is not.\n\
1643 \n\
1644 The redirection lasts until `redirect-frame-focus' is called to change it.")
1645 (frame, focus_frame)
1646 Lisp_Object frame, focus_frame;
1647 {
1648 /* Note that we don't check for a live frame here. It's reasonable
1649 to redirect the focus of a frame you're about to delete, if you
1650 know what other frame should receive those keystrokes. */
1651 CHECK_FRAME (frame, 0);
1652
1653 if (! NILP (focus_frame))
1654 CHECK_LIVE_FRAME (focus_frame, 1);
1655
1656 XFRAME (frame)->focus_frame = focus_frame;
1657
1658 if (frame_rehighlight_hook)
1659 (*frame_rehighlight_hook) (XFRAME (frame));
1660
1661 return Qnil;
1662 }
1663
1664
1665 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1666 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1667 This returns nil if FRAME's focus is not redirected.\n\
1668 See `redirect-frame-focus'.")
1669 (frame)
1670 Lisp_Object frame;
1671 {
1672 CHECK_LIVE_FRAME (frame, 0);
1673
1674 return FRAME_FOCUS_FRAME (XFRAME (frame));
1675 }
1676
1677
1678 \f
1679 /* Return the value of frame parameter PROP in frame FRAME. */
1680
1681 Lisp_Object
1682 get_frame_param (frame, prop)
1683 register struct frame *frame;
1684 Lisp_Object prop;
1685 {
1686 register Lisp_Object tem;
1687
1688 tem = Fassq (prop, frame->param_alist);
1689 if (EQ (tem, Qnil))
1690 return tem;
1691 return Fcdr (tem);
1692 }
1693
1694 /* Return the buffer-predicate of the selected frame. */
1695
1696 Lisp_Object
1697 frame_buffer_predicate ()
1698 {
1699 return selected_frame->buffer_predicate;
1700 }
1701
1702 /* Return the buffer-list of the selected frame. */
1703
1704 Lisp_Object
1705 frame_buffer_list ()
1706 {
1707 return selected_frame->buffer_list;
1708 }
1709
1710 /* Set the buffer-list of the selected frame. */
1711
1712 void
1713 set_frame_buffer_list (list)
1714 Lisp_Object list;
1715 {
1716 selected_frame->buffer_list = list;
1717 }
1718
1719 /* Discard BUFFER from the buffer-list of each frame. */
1720
1721 void
1722 frames_discard_buffer (buffer)
1723 Lisp_Object buffer;
1724 {
1725 Lisp_Object frame, tail;
1726
1727 FOR_EACH_FRAME (tail, frame)
1728 {
1729 XFRAME (frame)->buffer_list
1730 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1731 }
1732 }
1733
1734 /* Move BUFFER to the end of the buffer-list of each frame. */
1735
1736 void
1737 frames_bury_buffer (buffer)
1738 Lisp_Object buffer;
1739 {
1740 Lisp_Object frame, tail;
1741
1742 FOR_EACH_FRAME (tail, frame)
1743 {
1744 XFRAME (frame)->buffer_list
1745 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1746 Fcons (buffer, Qnil));
1747 }
1748 }
1749
1750 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1751 If the alist already has an element for PROP, we change it. */
1752
1753 void
1754 store_in_alist (alistptr, prop, val)
1755 Lisp_Object *alistptr, val;
1756 Lisp_Object prop;
1757 {
1758 register Lisp_Object tem;
1759
1760 tem = Fassq (prop, *alistptr);
1761 if (EQ (tem, Qnil))
1762 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1763 else
1764 Fsetcdr (tem, val);
1765 }
1766
1767 static int
1768 frame_name_fnn_p (str, len)
1769 char *str;
1770 int len;
1771 {
1772 if (len > 1 && str[0] == 'F')
1773 {
1774 char *end_ptr;
1775 long num = strtol (str + 1, &end_ptr, 10);
1776
1777 if (end_ptr == str + len)
1778 return 1;
1779 }
1780 return 0;
1781 }
1782
1783 /* Set the name of the terminal frame. Also used by MSDOS frames.
1784 Modeled after x_set_name which is used for WINDOW frames. */
1785
1786 void
1787 set_term_frame_name (f, name)
1788 struct frame *f;
1789 Lisp_Object name;
1790 {
1791 f->explicit_name = ! NILP (name);
1792
1793 /* If NAME is nil, set the name to F<num>. */
1794 if (NILP (name))
1795 {
1796 char namebuf[20];
1797
1798 /* Check for no change needed in this very common case
1799 before we do any consing. */
1800 if (frame_name_fnn_p (XSTRING (f->name)->data,
1801 STRING_BYTES (XSTRING (f->name))))
1802 return;
1803
1804 terminal_frame_count++;
1805 sprintf (namebuf, "F%d", terminal_frame_count);
1806 name = build_string (namebuf);
1807 }
1808 else
1809 {
1810 CHECK_STRING (name, 0);
1811
1812 /* Don't change the name if it's already NAME. */
1813 if (! NILP (Fstring_equal (name, f->name)))
1814 return;
1815
1816 /* Don't allow the user to set the frame name to F<num>, so it
1817 doesn't clash with the names we generate for terminal frames. */
1818 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1819 error ("Frame names of the form F<num> are usurped by Emacs");
1820 }
1821
1822 f->name = name;
1823 update_mode_lines = 1;
1824 }
1825
1826 void
1827 store_frame_param (f, prop, val)
1828 struct frame *f;
1829 Lisp_Object prop, val;
1830 {
1831 register Lisp_Object tem;
1832
1833 if (EQ (prop, Qbuffer_list))
1834 {
1835 f->buffer_list = val;
1836 return;
1837 }
1838
1839 tem = Fassq (prop, f->param_alist);
1840 if (EQ (tem, Qnil))
1841 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1842 else
1843 Fsetcdr (tem, val);
1844
1845 if (EQ (prop, Qbuffer_predicate))
1846 f->buffer_predicate = val;
1847
1848 if (! FRAME_WINDOW_P (f))
1849 {
1850 if (EQ (prop, Qmenu_bar_lines))
1851 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1852 else if (EQ (prop, Qname))
1853 set_term_frame_name (f, val);
1854 }
1855
1856 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1857 {
1858 if (! MINI_WINDOW_P (XWINDOW (val)))
1859 error ("Surrogate minibuffer windows must be minibuffer windows.");
1860
1861 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1862 && !EQ (val, f->minibuffer_window))
1863 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1864
1865 /* Install the chosen minibuffer window, with proper buffer. */
1866 f->minibuffer_window = val;
1867 }
1868 }
1869
1870 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1871 "Return the parameters-alist of frame FRAME.\n\
1872 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1873 The meaningful PARMs depend on the kind of frame.\n\
1874 If FRAME is omitted, return information on the currently selected frame.")
1875 (frame)
1876 Lisp_Object frame;
1877 {
1878 Lisp_Object alist;
1879 FRAME_PTR f;
1880 int height, width;
1881
1882 if (EQ (frame, Qnil))
1883 f = selected_frame;
1884 else
1885 {
1886 CHECK_FRAME (frame, 0);
1887 f = XFRAME (frame);
1888 }
1889
1890 if (!FRAME_LIVE_P (f))
1891 return Qnil;
1892
1893 alist = Fcopy_alist (f->param_alist);
1894 #ifdef MSDOS
1895 if (FRAME_MSDOS_P (f))
1896 {
1897 static char *colornames[16] =
1898 {
1899 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1900 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1901 "lightred", "lightmagenta", "yellow", "white"
1902 };
1903 store_in_alist (&alist, intern ("foreground-color"),
1904 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
1905 store_in_alist (&alist, intern ("background-color"),
1906 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
1907 }
1908 store_in_alist (&alist, intern ("font"), build_string ("default"));
1909 #endif
1910 store_in_alist (&alist, Qname, f->name);
1911 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
1912 store_in_alist (&alist, Qheight, make_number (height));
1913 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
1914 store_in_alist (&alist, Qwidth, make_number (width));
1915 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
1916 store_in_alist (&alist, Qminibuffer,
1917 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
1918 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1919 : FRAME_MINIBUF_WINDOW (f)));
1920 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
1921 store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
1922
1923 /* I think this should be done with a hook. */
1924 #ifdef HAVE_WINDOW_SYSTEM
1925 if (FRAME_WINDOW_P (f))
1926 x_report_frame_params (f, &alist);
1927 else
1928 #endif
1929 {
1930 /* This ought to be correct in f->param_alist for an X frame. */
1931 Lisp_Object lines;
1932 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
1933 store_in_alist (&alist, Qmenu_bar_lines, lines);
1934 }
1935 return alist;
1936 }
1937
1938 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1939 Smodify_frame_parameters, 2, 2, 0,
1940 "Modify the parameters of frame FRAME according to ALIST.\n\
1941 ALIST is an alist of parameters to change and their new values.\n\
1942 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1943 The meaningful PARMs depend on the kind of frame.\n\
1944 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1945 so that `frame-parameters' will return them.")
1946 (frame, alist)
1947 Lisp_Object frame, alist;
1948 {
1949 FRAME_PTR f;
1950 register Lisp_Object tail, elt, prop, val;
1951
1952 if (EQ (frame, Qnil))
1953 f = selected_frame;
1954 else
1955 {
1956 CHECK_LIVE_FRAME (frame, 0);
1957 f = XFRAME (frame);
1958 }
1959
1960 /* I think this should be done with a hook. */
1961 #ifdef HAVE_WINDOW_SYSTEM
1962 if (FRAME_WINDOW_P (f))
1963 x_set_frame_parameters (f, alist);
1964 else
1965 #endif
1966 #ifdef MSDOS
1967 if (FRAME_MSDOS_P (f))
1968 IT_set_frame_parameters (f, alist);
1969 else
1970 #endif
1971 {
1972 int length = XINT (Flength (alist));
1973 int i;
1974 Lisp_Object *parms
1975 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1976 Lisp_Object *values
1977 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1978
1979 /* Extract parm names and values into those vectors. */
1980
1981 i = 0;
1982 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
1983 {
1984 Lisp_Object elt, prop, val;
1985
1986 elt = Fcar (tail);
1987 parms[i] = Fcar (elt);
1988 values[i] = Fcdr (elt);
1989 i++;
1990 }
1991
1992 /* Now process them in reverse of specified order. */
1993 for (i--; i >= 0; i--)
1994 {
1995 prop = parms[i];
1996 val = values[i];
1997 store_frame_param (f, prop, val);
1998 }
1999 }
2000
2001 return Qnil;
2002 }
2003 \f
2004 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2005 0, 1, 0,
2006 "Height in pixels of a line in the font in frame FRAME.\n\
2007 If FRAME is omitted, the selected frame is used.\n\
2008 For a terminal frame, the value is always 1.")
2009 (frame)
2010 Lisp_Object frame;
2011 {
2012 struct frame *f;
2013
2014 if (NILP (frame))
2015 f = selected_frame;
2016 else
2017 {
2018 CHECK_FRAME (frame, 0);
2019 f = XFRAME (frame);
2020 }
2021
2022 #ifdef HAVE_WINDOW_SYSTEM
2023 if (FRAME_WINDOW_P (f))
2024 return make_number (x_char_height (f));
2025 else
2026 #endif
2027 return make_number (1);
2028 }
2029
2030
2031 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2032 0, 1, 0,
2033 "Width in pixels of characters in the font in frame FRAME.\n\
2034 If FRAME is omitted, the selected frame is used.\n\
2035 The width is the same for all characters, because\n\
2036 currently Emacs supports only fixed-width fonts.\n\
2037 For a terminal screen, the value is always 1.")
2038 (frame)
2039 Lisp_Object frame;
2040 {
2041 struct frame *f;
2042
2043 if (NILP (frame))
2044 f = selected_frame;
2045 else
2046 {
2047 CHECK_FRAME (frame, 0);
2048 f = XFRAME (frame);
2049 }
2050
2051 #ifdef HAVE_WINDOW_SYSTEM
2052 if (FRAME_WINDOW_P (f))
2053 return make_number (x_char_width (f));
2054 else
2055 #endif
2056 return make_number (1);
2057 }
2058
2059 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2060 Sframe_pixel_height, 0, 1, 0,
2061 "Return a FRAME's height in pixels.\n\
2062 This counts only the height available for text lines,\n\
2063 not menu bars on window-system Emacs frames.\n\
2064 For a terminal frame, the result really gives the height in characters.\n\
2065 If FRAME is omitted, the selected frame is used.")
2066 (frame)
2067 Lisp_Object frame;
2068 {
2069 struct frame *f;
2070
2071 if (NILP (frame))
2072 f = selected_frame;
2073 else
2074 {
2075 CHECK_FRAME (frame, 0);
2076 f = XFRAME (frame);
2077 }
2078
2079 #ifdef HAVE_WINDOW_SYSTEM
2080 if (FRAME_WINDOW_P (f))
2081 return make_number (x_pixel_height (f));
2082 else
2083 #endif
2084 return make_number (FRAME_HEIGHT (f));
2085 }
2086
2087 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2088 Sframe_pixel_width, 0, 1, 0,
2089 "Return FRAME's width in pixels.\n\
2090 For a terminal frame, the result really gives the width in characters.\n\
2091 If FRAME is omitted, the selected frame is used.")
2092 (frame)
2093 Lisp_Object frame;
2094 {
2095 struct frame *f;
2096
2097 if (NILP (frame))
2098 f = selected_frame;
2099 else
2100 {
2101 CHECK_FRAME (frame, 0);
2102 f = XFRAME (frame);
2103 }
2104
2105 #ifdef HAVE_WINDOW_SYSTEM
2106 if (FRAME_WINDOW_P (f))
2107 return make_number (x_pixel_width (f));
2108 else
2109 #endif
2110 return make_number (FRAME_WIDTH (f));
2111 }
2112 \f
2113 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2114 "Specify that the frame FRAME has LINES lines.\n\
2115 Optional third arg non-nil means that redisplay should use LINES lines\n\
2116 but that the idea of the actual height of the frame should not be changed.")
2117 (frame, lines, pretend)
2118 Lisp_Object frame, lines, pretend;
2119 {
2120 register struct frame *f;
2121
2122 CHECK_NUMBER (lines, 0);
2123 if (NILP (frame))
2124 f = selected_frame;
2125 else
2126 {
2127 CHECK_LIVE_FRAME (frame, 0);
2128 f = XFRAME (frame);
2129 }
2130
2131 /* I think this should be done with a hook. */
2132 #ifdef HAVE_WINDOW_SYSTEM
2133 if (FRAME_WINDOW_P (f))
2134 {
2135 if (XINT (lines) != f->height)
2136 x_set_window_size (f, 1, f->width, XINT (lines));
2137 }
2138 else
2139 #endif
2140 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
2141 return Qnil;
2142 }
2143
2144 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2145 "Specify that the frame FRAME has COLS columns.\n\
2146 Optional third arg non-nil means that redisplay should use COLS columns\n\
2147 but that the idea of the actual width of the frame should not be changed.")
2148 (frame, cols, pretend)
2149 Lisp_Object frame, cols, pretend;
2150 {
2151 register struct frame *f;
2152 CHECK_NUMBER (cols, 0);
2153 if (NILP (frame))
2154 f = selected_frame;
2155 else
2156 {
2157 CHECK_LIVE_FRAME (frame, 0);
2158 f = XFRAME (frame);
2159 }
2160
2161 /* I think this should be done with a hook. */
2162 #ifdef HAVE_WINDOW_SYSTEM
2163 if (FRAME_WINDOW_P (f))
2164 {
2165 if (XINT (cols) != f->width)
2166 x_set_window_size (f, 1, XINT (cols), f->height);
2167 }
2168 else
2169 #endif
2170 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
2171 return Qnil;
2172 }
2173
2174 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2175 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2176 (frame, cols, rows)
2177 Lisp_Object frame, cols, rows;
2178 {
2179 register struct frame *f;
2180 int mask;
2181
2182 CHECK_LIVE_FRAME (frame, 0);
2183 CHECK_NUMBER (cols, 2);
2184 CHECK_NUMBER (rows, 1);
2185 f = XFRAME (frame);
2186
2187 /* I think this should be done with a hook. */
2188 #ifdef HAVE_WINDOW_SYSTEM
2189 if (FRAME_WINDOW_P (f))
2190 {
2191 if (XINT (rows) != f->height || XINT (cols) != f->width
2192 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2193 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2194 }
2195 else
2196 #endif
2197 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
2198
2199 return Qnil;
2200 }
2201
2202 DEFUN ("set-frame-position", Fset_frame_position,
2203 Sset_frame_position, 3, 3, 0,
2204 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2205 This is actually the position of the upper left corner of the frame.\n\
2206 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2207 the rightmost or bottommost possible position (that stays within the screen).")
2208 (frame, xoffset, yoffset)
2209 Lisp_Object frame, xoffset, yoffset;
2210 {
2211 register struct frame *f;
2212 int mask;
2213
2214 CHECK_LIVE_FRAME (frame, 0);
2215 CHECK_NUMBER (xoffset, 1);
2216 CHECK_NUMBER (yoffset, 2);
2217 f = XFRAME (frame);
2218
2219 /* I think this should be done with a hook. */
2220 #ifdef HAVE_WINDOW_SYSTEM
2221 if (FRAME_WINDOW_P (f))
2222 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2223 #endif
2224
2225 return Qt;
2226 }
2227
2228 \f
2229 void
2230 syms_of_frame ()
2231 {
2232 syms_of_frame_1 ();
2233
2234 staticpro (&Vframe_list);
2235
2236 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2237 "The initial frame-object, which represents Emacs's stdout.");
2238
2239 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2240 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2241 Vemacs_iconified = Qnil;
2242
2243 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2244 "Minibufferless frames use this frame's minibuffer.\n\
2245 \n\
2246 Emacs cannot create minibufferless frames unless this is set to an\n\
2247 appropriate surrogate.\n\
2248 \n\
2249 Emacs consults this variable only when creating minibufferless\n\
2250 frames; once the frame is created, it sticks with its assigned\n\
2251 minibuffer, no matter what this variable is set to. This means that\n\
2252 this variable doesn't necessarily say anything meaningful about the\n\
2253 current set of frames, or where the minibuffer is currently being\n\
2254 displayed.");
2255
2256 defsubr (&Sactive_minibuffer_window);
2257 defsubr (&Sframep);
2258 defsubr (&Sframe_live_p);
2259 defsubr (&Smake_terminal_frame);
2260 defsubr (&Shandle_switch_frame);
2261 defsubr (&Signore_event);
2262 defsubr (&Sselect_frame);
2263 defsubr (&Sselected_frame);
2264 defsubr (&Swindow_frame);
2265 defsubr (&Sframe_root_window);
2266 defsubr (&Sframe_first_window);
2267 defsubr (&Sframe_selected_window);
2268 defsubr (&Sset_frame_selected_window);
2269 defsubr (&Sframe_list);
2270 defsubr (&Snext_frame);
2271 defsubr (&Sprevious_frame);
2272 defsubr (&Sdelete_frame);
2273 defsubr (&Smouse_position);
2274 defsubr (&Smouse_pixel_position);
2275 defsubr (&Sset_mouse_position);
2276 defsubr (&Sset_mouse_pixel_position);
2277 #if 0
2278 defsubr (&Sframe_configuration);
2279 defsubr (&Srestore_frame_configuration);
2280 #endif
2281 defsubr (&Smake_frame_visible);
2282 defsubr (&Smake_frame_invisible);
2283 defsubr (&Siconify_frame);
2284 defsubr (&Sframe_visible_p);
2285 defsubr (&Svisible_frame_list);
2286 defsubr (&Sraise_frame);
2287 defsubr (&Slower_frame);
2288 defsubr (&Sredirect_frame_focus);
2289 defsubr (&Sframe_focus);
2290 defsubr (&Sframe_parameters);
2291 defsubr (&Smodify_frame_parameters);
2292 defsubr (&Sframe_char_height);
2293 defsubr (&Sframe_char_width);
2294 defsubr (&Sframe_pixel_height);
2295 defsubr (&Sframe_pixel_width);
2296 defsubr (&Sset_frame_height);
2297 defsubr (&Sset_frame_width);
2298 defsubr (&Sset_frame_size);
2299 defsubr (&Sset_frame_position);
2300 }
2301
2302 void
2303 keys_of_frame ()
2304 {
2305 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2306 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2307 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2308 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2309 }