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