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