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