(run-python): Remove '' from sys.path.
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
0b5538bd 2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
8cabe764 3 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
dc6f92b8
JB
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
dc6f92b8 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
dc6f92b8
JB
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
dc6f92b8 19
18160b98 20#include <config.h>
565620a5
RS
21
22#include <stdio.h>
22e64f7c 23#include <ctype.h>
cc38027b 24#include "lisp.h"
83be827a 25#include "character.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
edfda783
AR
32#ifdef HAVE_NS
33#include "nsterm.h"
34#endif
2538fae4
AI
35#include "buffer.h"
36/* These help us bind and responding to switch-frame events. */
37#include "commands.h"
38#include "keyboard.h"
cc38027b 39#include "frame.h"
972f4259 40#include "blockinput.h"
28d440ab 41#include "termchar.h"
bc1ed486 42#include "termhooks.h"
dfcf069d 43#include "dispextern.h"
f769f1b2 44#include "window.h"
e0c8ad78
KH
45#ifdef HAVE_WINDOW_SYSTEM
46#include "font.h"
47#include "fontset.h"
48#endif
87485d6f
MW
49#ifdef MSDOS
50#include "msdos.h"
4aec4b29 51#include "dosfns.h"
87485d6f 52#endif
e5d77022 53
972f4259 54
2731a0ad
KS
55#ifdef HAVE_WINDOW_SYSTEM
56
972f4259
KS
57/* The name we're using in resource queries. Most often "emacs". */
58
59Lisp_Object Vx_resource_name;
60
61/* The application class we're using in resource queries.
62 Normally "Emacs". */
63
64Lisp_Object Vx_resource_class;
65
0a708637
GM
66/* Lower limit value of the frame opacity (alpha transparency). */
67
68Lisp_Object Vframe_alpha_lower_limit;
69
2731a0ad 70#endif
972f4259 71
dc4db71c
CY
72#ifdef HAVE_NS
73Lisp_Object Qns_parse_geometry;
74#endif
75
972f4259
KS
76Lisp_Object Qframep, Qframe_live_p;
77Lisp_Object Qicon, Qmodeline;
fd0c2bd1 78Lisp_Object Qonly;
edfda783 79Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
f7af3f7b 80Lisp_Object Qvisible;
8b60f7bc 81Lisp_Object Qdisplay_type;
6345f6aa 82Lisp_Object Qbackground_mode;
c53956fe 83Lisp_Object Qnoelisp;
972f4259
KS
84
85Lisp_Object Qx_frame_parameter;
86Lisp_Object Qx_resource_name;
6ed8eeff
KL
87Lisp_Object Qterminal;
88Lisp_Object Qterminal_live_p;
972f4259
KS
89
90/* Frame parameters (set or reported). */
91
92Lisp_Object Qauto_raise, Qauto_lower;
93Lisp_Object Qborder_color, Qborder_width;
94Lisp_Object Qcursor_color, Qcursor_type;
95Lisp_Object Qgeometry; /* Not used */
96Lisp_Object Qheight, Qwidth;
97Lisp_Object Qleft, Qright;
98Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
99Lisp_Object Qinternal_border_width;
100Lisp_Object Qmouse_color;
101Lisp_Object Qminibuffer;
102Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
103Lisp_Object Qvisibility;
104Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
105Lisp_Object Qscreen_gamma;
106Lisp_Object Qline_spacing;
107Lisp_Object Quser_position, Quser_size;
108Lisp_Object Qwait_for_wm;
109Lisp_Object Qwindow_id;
110#ifdef HAVE_X_WINDOWS
111Lisp_Object Qouter_window_id;
112#endif
113Lisp_Object Qparent_id;
114Lisp_Object Qtitle, Qname;
5839d7e8 115Lisp_Object Qexplicit_name;
972f4259
KS
116Lisp_Object Qunsplittable;
117Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
118Lisp_Object Qleft_fringe, Qright_fringe;
a18b8cb5 119Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
94674d18 120Lisp_Object Qtty_color_mode;
28d440ab 121Lisp_Object Qtty, Qtty_type;
dc6f92b8 122
972f4259 123Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
1a356571 124Lisp_Object Qfont_backend;
0a708637 125Lisp_Object Qalpha;
972f4259
KS
126
127Lisp_Object Qface_set_after_frame_default;
128
a249de79 129Lisp_Object Vterminal_frame;
a1aaa23f 130Lisp_Object Vdefault_frame_alist;
6b61353c 131Lisp_Object Vdefault_frame_scroll_bars;
beb0bc36 132Lisp_Object Vmouse_position_function;
6018080f 133Lisp_Object Vmouse_highlight;
58555d81 134static Lisp_Object Vdelete_frame_functions, Qdelete_frame_functions;
da1da002
MR
135
136int focus_follows_mouse;
a249de79
RS
137\f
138static void
139set_menu_bar_lines_1 (window, n)
daf01701
KL
140 Lisp_Object window;
141 int n;
a249de79
RS
142{
143 struct window *w = XWINDOW (window);
144
57aeea1e 145 XSETFASTINT (w->last_modified, 0);
5af5757b
KS
146 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
147 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
177c0ea7 148
5af5757b
KS
149 if (INTEGERP (w->orig_top_line))
150 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
151 if (INTEGERP (w->orig_total_lines))
152 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
a249de79
RS
153
154 /* Handle just the top child in a vertical split. */
155 if (!NILP (w->vchild))
156 set_menu_bar_lines_1 (w->vchild, n);
157
158 /* Adjust all children in a horizontal split. */
159 for (window = w->hchild; !NILP (window); window = w->next)
160 {
161 w = XWINDOW (window);
162 set_menu_bar_lines_1 (window, n);
163 }
164}
165
e48f782c 166void
a249de79
RS
167set_menu_bar_lines (f, value, oldval)
168 struct frame *f;
169 Lisp_Object value, oldval;
170{
171 int nlines;
172 int olines = FRAME_MENU_BAR_LINES (f);
173
174 /* Right now, menu bars don't work properly in minibuf-only frames;
175 most of the commands try to apply themselves to the minibuffer
e3678b64 176 frame itself, and get an error because you can't switch buffers
a249de79
RS
177 in or split the minibuffer window. */
178 if (FRAME_MINIBUF_ONLY_P (f))
179 return;
180
181 if (INTEGERP (value))
182 nlines = XINT (value);
183 else
184 nlines = 0;
185
57aeea1e
RS
186 if (nlines != olines)
187 {
188 windows_or_buffers_changed++;
189 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
190 FRAME_MENU_BAR_LINES (f) = nlines;
191 set_menu_bar_lines_1 (f->root_window, nlines - olines);
18082e2d 192 adjust_glyphs (f);
57aeea1e 193 }
a249de79
RS
194}
195\f
a249de79
RS
196Lisp_Object Vemacs_iconified;
197Lisp_Object Vframe_list;
a249de79 198
dc6f92b8
JB
199extern Lisp_Object Vminibuffer_list;
200extern Lisp_Object get_minibuffer ();
84386599
RS
201extern Lisp_Object Fhandle_switch_frame ();
202extern Lisp_Object Fredirect_frame_focus ();
a54d3a73 203extern Lisp_Object x_get_focus_frame ();
dc6f92b8 204\f
ff11dfa1 205DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
14ff1ee0
PJ
206 doc: /* Return non-nil if OBJECT is a frame.
207Value is t for a termcap frame (a character-only terminal),
208`x' for an Emacs frame that is really an X window,
209`w32' for an Emacs frame that is a window on MS-Windows display,
edfda783 210`ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
14ff1ee0
PJ
211`pc' for a direct-write MS-DOS frame.
212See also `frame-live-p'. */)
213 (object)
f9898cc6 214 Lisp_Object object;
dc6f92b8 215{
e35d291d 216 if (!FRAMEP (object))
dc6f92b8 217 return Qnil;
ff11dfa1 218 switch (XFRAME (object)->output_method)
dc6f92b8 219 {
3224dac1 220 case output_initial: /* The initial frame is like a termcap frame. */
dc6f92b8
JB
221 case output_termcap:
222 return Qt;
223 case output_x_window:
fd0c2bd1 224 return Qx;
fbd6baed
GV
225 case output_w32:
226 return Qw32;
bb221971
RS
227 case output_msdos_raw:
228 return Qpc;
574a1a90
RS
229 case output_mac:
230 return Qmac;
edfda783
AR
231 case output_ns:
232 return Qns;
dc6f92b8
JB
233 default:
234 abort ();
235 }
236}
237
dbc4e1c1 238DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
14ff1ee0
PJ
239 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
240Value is nil if OBJECT is not a live frame. If object is a live
6ed8eeff 241frame, the return value indicates what sort of terminal device it is
f6fa0866 242displayed on. See the documentation of `framep' for possible
4e10df59 243return values. */)
14ff1ee0 244 (object)
f9898cc6
JB
245 Lisp_Object object;
246{
ff11dfa1
JB
247 return ((FRAMEP (object)
248 && FRAME_LIVE_P (XFRAME (object)))
249 ? Fframep (object)
f9898cc6
JB
250 : Qnil);
251}
252
428a555e
KL
253DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
254 doc: /* The name of the window system that FRAME is displaying through.
255The value is a symbol---for instance, 'x' for X windows.
256The value is nil if Emacs is using a text-only terminal.
257
258FRAME defaults to the currently selected frame. */)
259 (frame)
260 Lisp_Object frame;
261{
262 Lisp_Object type;
263 if (NILP (frame))
264 frame = selected_frame;
265
266 type = Fframep (frame);
267
268 if (NILP (type))
269 wrong_type_argument (Qframep, frame);
270
271 if (EQ (type, Qt))
272 return Qnil;
273 else
274 return type;
a3547743 275}
428a555e 276
ff11dfa1
JB
277struct frame *
278make_frame (mini_p)
dc6f92b8
JB
279 int mini_p;
280{
ff11dfa1
JB
281 Lisp_Object frame;
282 register struct frame *f;
dc6f92b8
JB
283 register Lisp_Object root_window;
284 register Lisp_Object mini_window;
e9c96c62
GM
285
286 f = allocate_frame ();
36af7d69 287 XSETFRAME (frame, f);
ff11dfa1 288
18082e2d
GM
289 f->desired_matrix = 0;
290 f->current_matrix = 0;
291 f->desired_pool = 0;
292 f->current_pool = 0;
293 f->glyphs_initialized_p = 0;
294 f->decode_mode_spec_buffer = 0;
ff11dfa1 295 f->visible = 0;
323405de 296 f->async_visible = 0;
7556890b 297 f->output_data.nothing = 0;
ff11dfa1 298 f->iconified = 0;
323405de 299 f->async_iconified = 0;
ff11dfa1
JB
300 f->wants_modeline = 1;
301 f->auto_raise = 0;
302 f->auto_lower = 0;
303 f->no_split = 0;
10689a01 304 f->garbaged = 1;
ff11dfa1 305 f->has_minibuffer = mini_p;
a42e9724 306 f->focus_frame = Qnil;
804518aa 307 f->explicit_name = 0;
fd2777e0 308 f->can_have_scroll_bars = 0;
3a43d2dd 309 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
ff11dfa1 310 f->param_alist = Qnil;
fd2777e0
JB
311 f->scroll_bars = Qnil;
312 f->condemned_scroll_bars = Qnil;
306cc902 313 f->face_alist = Qnil;
18082e2d 314 f->face_cache = NULL;
9dd935ee 315 f->menu_bar_items = Qnil;
c8b8e7e3
RS
316 f->menu_bar_vector = Qnil;
317 f->menu_bar_items_used = 0;
329ca574 318 f->buffer_predicate = Qnil;
fa54c6ae 319 f->buffer_list = Qnil;
a18b8cb5 320 f->buried_buffer_list = Qnil;
aec6e486 321 f->namebuf = 0;
2b1c9cfb 322 f->title = Qnil;
18082e2d 323 f->menu_bar_window = Qnil;
9ea173e8 324 f->tool_bar_window = Qnil;
61752261 325 f->tool_bar_items = Qnil;
9ea173e8 326 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
61752261 327 f->n_tool_bar_items = 0;
5af5757b
KS
328 f->left_fringe_width = f->right_fringe_width = 0;
329 f->fringe_cols = 0;
330 f->scroll_bar_actual_width = 0;
331 f->border_width = 0;
332 f->internal_border_width = 0;
333 f->column_width = 1; /* !FRAME_WINDOW_P value */
334 f->line_height = 1; /* !FRAME_WINDOW_P value */
335 f->x_pixels_diff = f->y_pixels_diff = 0;
93421a1f 336#ifdef HAVE_WINDOW_SYSTEM
5af5757b 337 f->want_fullscreen = FULLSCREEN_NONE;
93421a1f 338#endif
5af5757b
KS
339 f->size_hint_flags = 0;
340 f->win_gravity = 0;
698ca23e 341 f->font_driver_list = NULL;
50e3873c 342 f->font_data_list = NULL;
dc6f92b8 343
cc38027b 344 root_window = make_window ();
dc6f92b8
JB
345 if (mini_p)
346 {
cc38027b 347 mini_window = make_window ();
dc6f92b8
JB
348 XWINDOW (root_window)->next = mini_window;
349 XWINDOW (mini_window)->prev = root_window;
350 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
351 XWINDOW (mini_window)->frame = frame;
352 f->minibuffer_window = mini_window;
dc6f92b8
JB
353 }
354 else
355 {
356 mini_window = Qnil;
357 XWINDOW (root_window)->next = Qnil;
ff11dfa1 358 f->minibuffer_window = Qnil;
dc6f92b8
JB
359 }
360
ff11dfa1 361 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
362
363 /* 10 is arbitrary,
364 just so that there is "something there."
ff11dfa1 365 Correct size will be set up later with change_frame_size. */
dc6f92b8 366
5af5757b
KS
367 SET_FRAME_COLS (f, 10);
368 FRAME_LINES (f) = 10;
dc6f92b8 369
5af5757b
KS
370 XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
371 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10));
dc6f92b8
JB
372
373 if (mini_p)
374 {
5af5757b
KS
375 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
376 XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
377 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1);
dc6f92b8
JB
378 }
379
ff11dfa1 380 /* Choose a buffer for the frame's root window. */
5bce042c
JB
381 {
382 Lisp_Object buf;
383
384 XWINDOW (root_window)->buffer = Qt;
385 buf = Fcurrent_buffer ();
386 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
387 a space), try to find another one. */
d5db4077 388 if (SREF (Fbuffer_name (buf), 0) == ' ')
98ce1622 389 buf = Fother_buffer (buf, Qnil, Qnil);
fa54c6ae 390
18082e2d
GM
391 /* Use set_window_buffer, not Fset_window_buffer, and don't let
392 hooks be run by it. The reason is that the whole frame/window
393 arrangement is not yet fully intialized at this point. Windows
394 don't have the right size, glyph matrices aren't initialized
395 etc. Running Lisp functions at this point surely ends in a
396 SEGV. */
5af5757b 397 set_window_buffer (root_window, buf, 0, 0);
fa54c6ae 398 f->buffer_list = Fcons (buf, Qnil);
5bce042c
JB
399 }
400
dc6f92b8
JB
401 if (mini_p)
402 {
403 XWINDOW (mini_window)->buffer = Qt;
18082e2d
GM
404 set_window_buffer (mini_window,
405 (NILP (Vminibuffer_list)
406 ? get_minibuffer (0)
407 : Fcar (Vminibuffer_list)),
5af5757b 408 0, 0);
dc6f92b8
JB
409 }
410
ff11dfa1
JB
411 f->root_window = root_window;
412 f->selected_window = root_window;
d5e7c279
JB
413 /* Make sure this window seems more recently used than
414 a newly-created, never-selected window. */
2a1893f4
SM
415 ++window_select_count;
416 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
dc6f92b8 417
a5f696ac
JD
418 f->default_face_done_p = 0;
419
ff11dfa1 420 return f;
dc6f92b8
JB
421}
422\f
bba88bb1 423#ifdef HAVE_WINDOW_SYSTEM
ff11dfa1 424/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
425 MINI_WINDOW is the minibuffer window to use. nil means use the
426 default (the global minibuffer). */
427
ff11dfa1 428struct frame *
b0660239 429make_frame_without_minibuffer (mini_window, kb, display)
dc6f92b8 430 register Lisp_Object mini_window;
662ac59a 431 KBOARD *kb;
b0660239 432 Lisp_Object display;
dc6f92b8 433{
ff11dfa1 434 register struct frame *f;
363b873b 435 struct gcpro gcpro1;
dc6f92b8 436
b0660239 437 if (!NILP (mini_window))
b7826503 438 CHECK_LIVE_WINDOW (mini_window);
dc6f92b8 439
b0660239 440 if (!NILP (mini_window)
6ed8eeff
KL
441 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
442 error ("Frame and minibuffer must be on the same terminal");
662ac59a 443
ff11dfa1
JB
444 /* Make a frame containing just a root window. */
445 f = make_frame (0);
dc6f92b8 446
b0660239
KH
447 if (NILP (mini_window))
448 {
449 /* Use default-minibuffer-frame if possible. */
450 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
451 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
452 {
363b873b
RS
453 Lisp_Object frame_dummy;
454
455 XSETFRAME (frame_dummy, f);
456 GCPRO1 (frame_dummy);
b0660239 457 /* If there's no minibuffer frame to use, create one. */
363b873b
RS
458 kb->Vdefault_minibuffer_frame =
459 call1 (intern ("make-initial-minibuffer-frame"), display);
460 UNGCPRO;
b0660239 461 }
177c0ea7 462
b0660239
KH
463 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
464 }
a2812a26 465
ff11dfa1 466 f->minibuffer_window = mini_window;
a2812a26
RS
467
468 /* Make the chosen minibuffer window display the proper minibuffer,
469 unless it is already showing a minibuffer. */
470 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
471 Fset_window_buffer (mini_window,
472 (NILP (Vminibuffer_list)
473 ? get_minibuffer (0)
5af5757b 474 : Fcar (Vminibuffer_list)), Qnil);
ff11dfa1 475 return f;
dc6f92b8
JB
476}
477
ff11dfa1 478/* Make a frame containing only a minibuffer window. */
dc6f92b8 479
ff11dfa1
JB
480struct frame *
481make_minibuffer_frame ()
dc6f92b8 482{
ff11dfa1 483 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 484
ff11dfa1 485 register struct frame *f = make_frame (0);
dc6f92b8 486 register Lisp_Object mini_window;
ff11dfa1 487 register Lisp_Object frame;
dc6f92b8 488
2d80a27a 489 XSETFRAME (frame, f);
dc6f92b8 490
804518aa 491 f->auto_raise = 0;
ff11dfa1
JB
492 f->auto_lower = 0;
493 f->no_split = 1;
494 f->wants_modeline = 0;
495 f->has_minibuffer = 1;
dc6f92b8
JB
496
497 /* Now label the root window as also being the minibuffer.
498 Avoid infinite looping on the window chain by marking next pointer
499 as nil. */
500
ff11dfa1 501 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
502 XWINDOW (mini_window)->mini_p = Qt;
503 XWINDOW (mini_window)->next = Qnil;
804518aa 504 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 505 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
506
507 /* Put the proper buffer in that window. */
508
509 Fset_window_buffer (mini_window,
265a9e55 510 (NILP (Vminibuffer_list)
dc6f92b8 511 ? get_minibuffer (0)
5af5757b 512 : Fcar (Vminibuffer_list)), Qnil);
ff11dfa1 513 return f;
dc6f92b8 514}
bba88bb1 515#endif /* HAVE_WINDOW_SYSTEM */
dc6f92b8 516\f
28d440ab 517/* Construct a frame that refers to a terminal. */
dc6f92b8 518
6ed8eeff 519static int tty_frame_count;
bb1513c9 520
ff11dfa1 521struct frame *
3224dac1 522make_initial_frame (void)
dc6f92b8 523{
3224dac1 524 struct frame *f;
6ed8eeff 525 struct terminal *terminal;
d063751a 526 Lisp_Object frame;
bb1513c9 527
1bc973c2 528 eassert (initial_kboard);
b4f0ee5d 529
bb1513c9
RS
530 /* The first call must initialize Vframe_list. */
531 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
532 Vframe_list = Qnil;
ff11dfa1 533
6ed8eeff 534 terminal = init_initial_terminal ();
3224dac1
KL
535
536 f = make_frame (1);
537 XSETFRAME (frame, f);
538
539 Vframe_list = Fcons (frame, Vframe_list);
540
6ed8eeff 541 tty_frame_count = 1;
3224dac1
KL
542 f->name = build_string ("F1");
543
544 f->visible = 1;
545 f->async_visible = 1;
546
6ed8eeff
KL
547 f->output_method = terminal->type;
548 f->terminal = terminal;
549 f->terminal->reference_count++;
3224dac1 550 f->output_data.nothing = 0;
a3547743 551
3224dac1
KL
552 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
553 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
a3547743 554
3224dac1
KL
555 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
556 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
557
edfda783
AR
558#ifdef CANNOT_DUMP
559 if (!noninteractive)
560 init_frame_faces (f);
561#endif
562
3224dac1
KL
563 return f;
564}
565
566
567struct frame *
6ed8eeff 568make_terminal_frame (struct terminal *terminal)
3224dac1
KL
569{
570 register struct frame *f;
3224dac1
KL
571 Lisp_Object frame;
572 char name[20];
ab797f65 573
4e213843
SM
574 if (!terminal->name)
575 error ("Terminal is not live, can't create new frames on it");
ab797f65 576
ff11dfa1 577 f = make_frame (1);
d063751a 578
2d80a27a 579 XSETFRAME (frame, f);
d063751a
RS
580 Vframe_list = Fcons (frame, Vframe_list);
581
6ed8eeff
KL
582 tty_frame_count++;
583 sprintf (name, "F%d", tty_frame_count);
0303e8da 584 f->name = build_string (name);
bb1513c9 585
bb1513c9
RS
586 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
587 f->async_visible = 1; /* Don't let visible be cleared later. */
bb221971 588#ifdef MSDOS
99dda2cd 589 f->output_data.tty->display_info = &the_only_display_info;
2d764c78
EZ
590 if (!inhibit_window_system
591 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
592 || XFRAME (selected_frame)->output_method == output_msdos_raw))
65606f5e
EZ
593 {
594 f->output_method = output_msdos_raw;
99dda2cd 595#if 0
65606f5e
EZ
596 /* This initialization of foreground and background pixels is
597 only important for the initial frame created in temacs. If
598 we don't do that, we get black background and foreground in
99dda2cd 599 the dumped Emacs because the_only_display_info is a static
65606f5e
EZ
600 variable, hence it is born all-zeroes, and zero is the code
601 for the black color. Other frames all inherit their pixels
99dda2cd 602 from what's already in the_only_display_info. */
65606f5e 603 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
5bcee7ef
KL
604 && FRAME_BACKGROUND_PIXEL (f) == 0
605 && FRAME_FOREGROUND_PIXEL (f) == 0)
65606f5e 606 {
5bcee7ef
KL
607 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
608 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
65606f5e 609 }
99dda2cd 610#endif
65606f5e 611 }
2d764c78
EZ
612 else
613 f->output_method = output_termcap;
1a578e9b 614#else
0a125897 615 {
0a125897 616 f->output_method = output_termcap;
6ed8eeff
KL
617 f->terminal = terminal;
618 f->terminal->reference_count++;
428a555e 619 create_tty_output (f);
a3547743 620
28d7d09f
KL
621 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
622 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
a3547743 623
428a555e
KL
624 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
625 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
626
428a555e 627 /* Set the top frame to the newly created frame. */
b1cb6b20 628 if (FRAMEP (FRAME_TTY (f)->top_frame)
114a8b8c
KL
629 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
630 XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
a3547743 631
428a555e 632 FRAME_TTY (f)->top_frame = frame;
0a125897 633 }
a3547743 634
58bd8318
KS
635#ifdef CANNOT_DUMP
636 FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
637 FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
638#endif
2d764c78 639#endif /* MSDOS */
574a1a90 640
1a6d3623
EZ
641 if (!noninteractive)
642 init_frame_faces (f);
1a578e9b 643
ff11dfa1 644 return f;
dc6f92b8 645}
bb1513c9 646
ed8dad6b
KL
647/* Get a suitable value for frame parameter PARAMETER for a newly
648 created frame, based on (1) the user-supplied frame parameter
649 alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
650 fails, (3) Vdefault_frame_alist. */
651
652static Lisp_Object
653get_future_frame_param (Lisp_Object parameter,
654 Lisp_Object supplied_parms,
655 char *current_value)
656{
657 Lisp_Object result;
658
659 result = Fassq (parameter, supplied_parms);
660 if (NILP (result))
661 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
662 if (NILP (result) && current_value != NULL)
663 result = build_string (current_value);
664 if (NILP (result))
665 result = Fassq (parameter, Vdefault_frame_alist);
666 if (!NILP (result) && !STRINGP (result))
667 result = XCDR (result);
668 if (NILP (result) || !STRINGP (result))
669 result = Qnil;
670
671 return result;
672}
673
bb1513c9 674DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
14ff1ee0 675 1, 1, 0,
28d440ab 676 doc: /* Create an additional terminal frame, possibly on another terminal.
14ff1ee0 677This function takes one argument, an alist specifying frame parameters.
28d440ab
KL
678
679You can create multiple frames on a single text-only terminal, but
680only one of them (the selected terminal frame) is actually displayed.
681
682In practice, generally you don't need to specify any parameters,
683except when you want to create a new frame on another terminal.
684In that case, the `tty' parameter specifies the device file to open,
685and the `tty-type' parameter specifies the terminal type. Example:
686
687 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
688
0b0d3e0b
KL
689Note that changing the size of one terminal frame automatically
690affects all frames on the same terminal device. */)
14ff1ee0 691 (parms)
bb1513c9
RS
692 Lisp_Object parms;
693{
694 struct frame *f;
6ed8eeff 695 struct terminal *t = NULL;
574a1a90 696 Lisp_Object frame, tem;
8d2666fe 697 struct frame *sf = SELECTED_FRAME ();
bb1513c9 698
541580aa 699#ifdef MSDOS
2d764c78
EZ
700 if (sf->output_method != output_msdos_raw
701 && sf->output_method != output_termcap)
bb221971 702 abort ();
574a1a90
RS
703#else /* not MSDOS */
704
daf01701 705#if 0 /* This should work now! */
8d2666fe 706 if (sf->output_method != output_termcap)
bb1513c9 707 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
bb221971 708#endif
574a1a90 709#endif /* not MSDOS */
a3547743 710
b6660415 711 {
6ed8eeff 712 Lisp_Object terminal;
bb1513c9 713
6ed8eeff
KL
714 terminal = Fassq (Qterminal, parms);
715 if (!NILP (terminal))
28d440ab 716 {
6ed8eeff
KL
717 terminal = XCDR (terminal);
718 t = get_terminal (terminal, 1);
28d440ab 719 }
28d440ab 720 }
a3547743 721
6ed8eeff 722 if (!t)
a3547743 723 {
99dda2cd
EZ
724#ifdef MSDOS
725 /* msdos.c assumes a single tty_display_info object. */
726 error ("Multiple terminals are not supported on this platform");
727#else /* !MSDOS */
b6660415 728 char *name = 0, *type = 0;
ed8dad6b 729 Lisp_Object tty, tty_type;
b6660415 730
ed8dad6b
KL
731 tty = get_future_frame_param
732 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
733 ? FRAME_TTY (XFRAME (selected_frame))->name
734 : NULL));
735 if (!NILP (tty))
b6660415
KL
736 {
737 name = (char *) alloca (SBYTES (tty) + 1);
738 strncpy (name, SDATA (tty), SBYTES (tty));
739 name[SBYTES (tty)] = 0;
740 }
a3547743 741
ed8dad6b
KL
742 tty_type = get_future_frame_param
743 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
744 ? FRAME_TTY (XFRAME (selected_frame))->type
745 : NULL));
746 if (!NILP (tty_type))
b6660415
KL
747 {
748 type = (char *) alloca (SBYTES (tty_type) + 1);
749 strncpy (type, SDATA (tty_type), SBYTES (tty_type));
750 type[SBYTES (tty_type)] = 0;
751 }
752
6ed8eeff 753 t = init_tty (name, type, 0); /* Errors are not fatal. */
99dda2cd 754#endif /* !MSDOS */
b6660415 755 }
bb1513c9 756
6ed8eeff 757 f = make_terminal_frame (t);
574a1a90 758
9628b887
KL
759 {
760 int width, height;
0b0d3e0b 761 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
9628b887
KL
762 change_frame_size (f, height, width, 0, 0, 0);
763 }
a3547743 764
18082e2d 765 adjust_glyphs (f);
bb1513c9
RS
766 calculate_costs (f);
767 XSETFRAME (frame, f);
8adfc1ec 768 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
bb1513c9 769 Fmodify_frame_parameters (frame, parms);
ed8dad6b 770 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
6ed8eeff 771 build_string (t->display_info.tty->type)),
ed8dad6b 772 Qnil));
db9d7d9a
KL
773 if (t->display_info.tty->name != NULL)
774 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
775 build_string (t->display_info.tty->name)),
776 Qnil));
777 else
778 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
a3547743 779
87f1940e
EZ
780 /* Make the frame face alist be frame-specific, so that each
781 frame could change its face definitions independently. */
8d2666fe 782 f->face_alist = Fcopy_alist (sf->face_alist);
87f1940e
EZ
783 /* Simple Fcopy_alist isn't enough, because we need the contents of
784 the vectors which are the CDRs of associations in face_alist to
785 be copied as well. */
786 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
f3fbd155 787 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
bb1513c9
RS
788 return frame;
789}
1e8324d9 790
dc6f92b8 791\f
1e8324d9
GM
792/* Perform the switch to frame FRAME.
793
794 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
795 FRAME1 as frame.
796
797 If TRACK is non-zero and the frame that currently has the focus
798 redirects its focus to the selected frame, redirect that focused
799 frame's focus to FRAME instead.
800
801 FOR_DELETION non-zero means that the selected frame is being
6ed8eeff 802 deleted, which includes the possibility that the frame's terminal
1e8324d9
GM
803 is dead. */
804
61f94483 805Lisp_Object
1e8324d9
GM
806do_switch_frame (frame, track, for_deletion)
807 Lisp_Object frame;
808 int track, for_deletion;
dc6f92b8 809{
8d2666fe 810 struct frame *sf = SELECTED_FRAME ();
177c0ea7 811
2f0b07e0
JB
812 /* If FRAME is a switch-frame event, extract the frame we should
813 switch to. */
814 if (CONSP (frame)
7539e11f
KR
815 && EQ (XCAR (frame), Qswitch_frame)
816 && CONSP (XCDR (frame)))
817 frame = XCAR (XCDR (frame));
2f0b07e0 818
09907c3a
KH
819 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
820 a switch-frame event to arrive after a frame is no longer live,
821 especially when deleting the initial frame during startup. */
b7826503 822 CHECK_FRAME (frame);
09907c3a
KH
823 if (! FRAME_LIVE_P (XFRAME (frame)))
824 return Qnil;
dc6f92b8 825
8d2666fe 826 if (sf == XFRAME (frame))
ff11dfa1 827 return frame;
dc6f92b8 828
0aed85f4
KH
829 /* This is too greedy; it causes inappropriate focus redirection
830 that's hard to get rid of. */
831#if 0
a42e9724
JB
832 /* If a frame's focus has been redirected toward the currently
833 selected frame, we should change the redirection to point to the
834 newly selected frame. This means that if the focus is redirected
835 from a minibufferless frame to a surrogate minibuffer frame, we
836 can use `other-window' to switch between all the frames using
837 that minibuffer frame, and the focus redirection will follow us
838 around. */
0aed85f4
KH
839 if (track)
840 {
841 Lisp_Object tail;
a42e9724 842
7539e11f 843 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
0aed85f4
KH
844 {
845 Lisp_Object focus;
a42e9724 846
7539e11f 847 if (!FRAMEP (XCAR (tail)))
0aed85f4 848 abort ();
a42e9724 849
7539e11f 850 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
a42e9724 851
8d2666fe 852 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
7539e11f 853 Fredirect_frame_focus (XCAR (tail), frame);
0aed85f4
KH
854 }
855 }
856#else /* ! 0 */
857 /* Instead, apply it only to the frame we're pointing to. */
032d78fe 858#ifdef HAVE_WINDOW_SYSTEM
1e8324d9 859 if (track && FRAME_WINDOW_P (XFRAME (frame)))
0aed85f4
KH
860 {
861 Lisp_Object focus, xfocus;
862
d7266360 863 xfocus = x_get_focus_frame (XFRAME (frame));
0aed85f4
KH
864 if (FRAMEP (xfocus))
865 {
866 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
8d2666fe 867 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
0aed85f4
KH
868 Fredirect_frame_focus (xfocus, frame);
869 }
870 }
871#endif /* HAVE_X_WINDOWS */
872#endif /* ! 0 */
a42e9724 873
1e8324d9 874 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
550f0e6a
GM
875 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
876
9b2cd403 877 if (FRAME_TERMCAP_P (XFRAME (frame)))
9628b887 878 {
9b2cd403
SM
879 if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
880 /* Mark previously displayed frame as now obscured. */
881 XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2;
9628b887
KL
882 XFRAME (frame)->async_visible = 1;
883 FRAME_TTY (XFRAME (frame))->top_frame = frame;
884 }
885
8d2666fe
GM
886 selected_frame = frame;
887 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
888 last_nonminibuf_frame = XFRAME (selected_frame);
d5e7c279 889
f1321dc3 890 Fselect_window (XFRAME (frame)->selected_window, Qnil);
dc6f92b8 891
edfda783
AR
892#ifdef NS_IMPL_COCOA
893 /* term gets no other notification of this */
894 if (for_deletion)
895 Fraise_frame(Qnil);
896#endif
897
074577b8 898 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 899 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
900 before you take it out, make sure that evaluating something like
901 (select-window (frame-root-window (new-frame))) doesn't end up
902 with your typing being interpreted in the new frame instead of
903 the one you're actually typing in. */
ef352596 904 internal_last_event_frame = Qnil;
074577b8 905
ff11dfa1 906 return frame;
dc6f92b8
JB
907}
908
20dc6fbb 909DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 1, "e",
14ff1ee0
PJ
910 doc: /* Select the frame FRAME.
911Subsequent editing commands apply to its selected window.
912The selection of FRAME lasts until the next time the user does
913something to select a different frame, or until the next time this
e4ed805e
LT
914function is called. If you are using a window system, the previously
915selected frame may be restored as the selected frame after return to
916the command loop, because it still may have the window system's input
917focus. On a text-only terminal, the next redisplay will display FRAME.
918
919This function returns FRAME, or nil if FRAME has been deleted. */)
20dc6fbb
LT
920 (frame)
921 Lisp_Object frame;
0aed85f4 922{
1e8324d9 923 return do_switch_frame (frame, 1, 0);
0aed85f4
KH
924}
925
926
20dc6fbb 927DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
14ff1ee0
PJ
928 doc: /* Handle a switch-frame event EVENT.
929Switch-frame events are usually bound to this function.
930A switch-frame event tells Emacs that the window manager has requested
931that the user's events be directed to the frame mentioned in the event.
932This function selects the selected window of the frame of EVENT.
933
934If EVENT is frame object, handle it as if it were a switch-frame event
935to that frame. */)
20dc6fbb
LT
936 (event)
937 Lisp_Object event;
0aed85f4 938{
6951cd71
KH
939 /* Preserve prefix arg that the command loop just cleared. */
940 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
e05169e2 941 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
1e8324d9 942 return do_switch_frame (event, 0, 0);
0aed85f4
KH
943}
944
ff11dfa1 945DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
14ff1ee0
PJ
946 doc: /* Return the frame that is now selected. */)
947 ()
dc6f92b8 948{
8d2666fe 949 return selected_frame;
dc6f92b8 950}
4a7cfafc 951\f
ff11dfa1 952DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
14ff1ee0
PJ
953 doc: /* Return the frame object that window WINDOW is on. */)
954 (window)
dc6f92b8
JB
955 Lisp_Object window;
956{
b7826503 957 CHECK_LIVE_WINDOW (window);
ff11dfa1 958 return XWINDOW (window)->frame;
dc6f92b8
JB
959}
960
ba32f2db 961DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
14ff1ee0
PJ
962 doc: /* Returns the topmost, leftmost window of FRAME.
963If omitted, FRAME defaults to the currently selected frame. */)
964 (frame)
ba32f2db
KH
965 Lisp_Object frame;
966{
967 Lisp_Object w;
968
969 if (NILP (frame))
8d2666fe 970 w = SELECTED_FRAME ()->root_window;
ba32f2db
KH
971 else
972 {
b7826503 973 CHECK_LIVE_FRAME (frame);
ba32f2db
KH
974 w = XFRAME (frame)->root_window;
975 }
976 while (NILP (XWINDOW (w)->buffer))
977 {
978 if (! NILP (XWINDOW (w)->hchild))
979 w = XWINDOW (w)->hchild;
980 else if (! NILP (XWINDOW (w)->vchild))
981 w = XWINDOW (w)->vchild;
982 else
983 abort ();
984 }
985 return w;
986}
987
5add3885
RS
988DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
989 Sactive_minibuffer_window, 0, 0, 0,
14ff1ee0
PJ
990 doc: /* Return the currently active minibuffer window, or nil if none. */)
991 ()
5add3885
RS
992{
993 return minibuf_level ? minibuf_window : Qnil;
994}
995
ff11dfa1 996DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
14ff1ee0
PJ
997 doc: /* Returns the root-window of FRAME.
998If omitted, FRAME defaults to the currently selected frame. */)
999 (frame)
ff11dfa1 1000 Lisp_Object frame;
dc6f92b8 1001{
8d2666fe 1002 Lisp_Object window;
177c0ea7 1003
ff11dfa1 1004 if (NILP (frame))
8d2666fe 1005 window = SELECTED_FRAME ()->root_window;
f9898cc6 1006 else
8d2666fe 1007 {
b7826503 1008 CHECK_LIVE_FRAME (frame);
8d2666fe
GM
1009 window = XFRAME (frame)->root_window;
1010 }
177c0ea7 1011
8d2666fe 1012 return window;
dc6f92b8
JB
1013}
1014
ff11dfa1
JB
1015DEFUN ("frame-selected-window", Fframe_selected_window,
1016 Sframe_selected_window, 0, 1, 0,
14ff1ee0
PJ
1017 doc: /* Return the selected window of frame object FRAME.
1018If omitted, FRAME defaults to the currently selected frame. */)
1019 (frame)
ff11dfa1 1020 Lisp_Object frame;
dc6f92b8 1021{
8d2666fe 1022 Lisp_Object window;
177c0ea7 1023
ff11dfa1 1024 if (NILP (frame))
8d2666fe 1025 window = SELECTED_FRAME ()->selected_window;
f9898cc6 1026 else
8d2666fe 1027 {
b7826503 1028 CHECK_LIVE_FRAME (frame);
8d2666fe
GM
1029 window = XFRAME (frame)->selected_window;
1030 }
dc6f92b8 1031
8d2666fe 1032 return window;
dc6f92b8
JB
1033}
1034
4a7cfafc
RS
1035DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
1036 Sset_frame_selected_window, 2, 2, 0,
14ff1ee0 1037 doc: /* Set the selected window of frame object FRAME to WINDOW.
e4ed805e 1038Return WINDOW.
14ff1ee0
PJ
1039If FRAME is nil, the selected frame is used.
1040If FRAME is the selected frame, this makes WINDOW the selected window. */)
1041 (frame, window)
4a7cfafc
RS
1042 Lisp_Object frame, window;
1043{
1044 if (NILP (frame))
8d2666fe 1045 frame = selected_frame;
177c0ea7 1046
b7826503
PJ
1047 CHECK_LIVE_FRAME (frame);
1048 CHECK_LIVE_WINDOW (window);
4a7cfafc
RS
1049
1050 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
1051 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
1052
8d2666fe 1053 if (EQ (frame, selected_frame))
f1321dc3 1054 return Fselect_window (window, Qnil);
4a7cfafc
RS
1055
1056 return XFRAME (frame)->selected_window = window;
1057}
b6660415 1058
4a7cfafc 1059\f
ff11dfa1 1060DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 1061 0, 0, 0,
14ff1ee0
PJ
1062 doc: /* Return a list of all frames. */)
1063 ()
dc6f92b8 1064{
d74c1900
GM
1065 Lisp_Object frames;
1066 frames = Fcopy_sequence (Vframe_list);
6a65b1b5 1067#ifdef HAVE_WINDOW_SYSTEM
d74c1900
GM
1068 if (FRAMEP (tip_frame))
1069 frames = Fdelq (tip_frame, frames);
6a65b1b5 1070#endif
d74c1900 1071 return frames;
dc6f92b8
JB
1072}
1073
ff11dfa1 1074/* Return the next frame in the frame list after FRAME.
ff11dfa1 1075 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
1076 If MINIBUF is a window, include only its own frame
1077 and any frame now using that window as the minibuffer.
f7af3f7b 1078 If MINIBUF is `visible', include all visible frames.
a9986780 1079 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
1080 Otherwise, include all frames. */
1081
66a9dbbe 1082static Lisp_Object
ff11dfa1
JB
1083next_frame (frame, minibuf)
1084 Lisp_Object frame;
f9898cc6 1085 Lisp_Object minibuf;
dc6f92b8
JB
1086{
1087 Lisp_Object tail;
1088 int passed = 0;
1089
ff11dfa1
JB
1090 /* There must always be at least one frame in Vframe_list. */
1091 if (! CONSP (Vframe_list))
f9898cc6
JB
1092 abort ();
1093
dbc4e1c1
JB
1094 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
1095 forever. Forestall that. */
b7826503 1096 CHECK_LIVE_FRAME (frame);
dbc4e1c1 1097
dc6f92b8 1098 while (1)
7539e11f 1099 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
dc6f92b8 1100 {
ab9f008d 1101 Lisp_Object f;
d06a8a56 1102
7539e11f 1103 f = XCAR (tail);
06537cc8
RS
1104
1105 if (passed
9628b887
KL
1106 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1107 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1108 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1109 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
d5e7c279 1110 {
d06a8a56
JB
1111 /* Decide whether this frame is eligible to be returned. */
1112
1113 /* If we've looped all the way around without finding any
1114 eligible frames, return the original frame. */
1115 if (EQ (f, frame))
1116 return f;
1117
1118 /* Let minibuf decide if this frame is acceptable. */
1119 if (NILP (minibuf))
1120 {
1121 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1122 return f;
1123 }
f7af3f7b
RS
1124 else if (EQ (minibuf, Qvisible))
1125 {
1126 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1127 if (FRAME_VISIBLE_P (XFRAME (f)))
1128 return f;
1129 }
3780bc22 1130 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
a9986780
RS
1131 {
1132 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1133 if (FRAME_VISIBLE_P (XFRAME (f))
1134 || FRAME_ICONIFIED_P (XFRAME (f)))
1135 return f;
1136 }
f7af3f7b 1137 else if (WINDOWP (minibuf))
d06a8a56 1138 {
a9986780 1139 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
551645f8
GM
1140 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1141 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1142 FRAME_FOCUS_FRAME (XFRAME (f))))
d06a8a56
JB
1143 return f;
1144 }
1145 else
ff11dfa1 1146 return f;
d5e7c279 1147 }
dc6f92b8 1148
d06a8a56 1149 if (EQ (frame, f))
dc6f92b8
JB
1150 passed++;
1151 }
1152}
1153
ff11dfa1 1154/* Return the previous frame in the frame list before FRAME.
ff11dfa1 1155 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
1156 If MINIBUF is a window, include only its own frame
1157 and any frame now using that window as the minibuffer.
f7af3f7b 1158 If MINIBUF is `visible', include all visible frames.
a9986780 1159 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
1160 Otherwise, include all frames. */
1161
66a9dbbe 1162static Lisp_Object
ff11dfa1
JB
1163prev_frame (frame, minibuf)
1164 Lisp_Object frame;
f9898cc6 1165 Lisp_Object minibuf;
dc6f92b8
JB
1166{
1167 Lisp_Object tail;
1168 Lisp_Object prev;
1169
ff11dfa1
JB
1170 /* There must always be at least one frame in Vframe_list. */
1171 if (! CONSP (Vframe_list))
f9898cc6
JB
1172 abort ();
1173
dc6f92b8 1174 prev = Qnil;
7539e11f 1175 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
f9898cc6 1176 {
ab9f008d 1177 Lisp_Object f;
f9898cc6 1178
7539e11f 1179 f = XCAR (tail);
e35d291d 1180 if (!FRAMEP (f))
d06a8a56 1181 abort ();
f9898cc6 1182
d06a8a56
JB
1183 if (EQ (frame, f) && !NILP (prev))
1184 return prev;
f9898cc6 1185
9628b887
KL
1186 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1187 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1188 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1189 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
f7af3f7b 1190 {
06537cc8
RS
1191 /* Decide whether this frame is eligible to be returned,
1192 according to minibuf. */
1193 if (NILP (minibuf))
1194 {
1195 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1196 prev = f;
1197 }
1198 else if (WINDOWP (minibuf))
1199 {
1200 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
551645f8
GM
1201 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1202 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1203 FRAME_FOCUS_FRAME (XFRAME (f))))
06537cc8
RS
1204 prev = f;
1205 }
1206 else if (EQ (minibuf, Qvisible))
1207 {
1208 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1209 if (FRAME_VISIBLE_P (XFRAME (f)))
1210 prev = f;
1211 }
1212 else if (XFASTINT (minibuf) == 0)
1213 {
1214 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1215 if (FRAME_VISIBLE_P (XFRAME (f))
1216 || FRAME_ICONIFIED_P (XFRAME (f)))
1217 prev = f;
1218 }
1219 else
a9986780
RS
1220 prev = f;
1221 }
f9898cc6 1222 }
d06a8a56
JB
1223
1224 /* We've scanned the entire list. */
1225 if (NILP (prev))
1226 /* We went through the whole frame list without finding a single
1227 acceptable frame. Return the original frame. */
1228 return frame;
1229 else
1230 /* There were no acceptable frames in the list before FRAME; otherwise,
1231 we would have returned directly from the loop. Since PREV is the last
1232 acceptable frame in the list, return it. */
1233 return prev;
dc6f92b8
JB
1234}
1235
ef2c57ac 1236
ff11dfa1 1237DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
14ff1ee0
PJ
1238 doc: /* Return the next frame in the frame list after FRAME.
1239It considers only frames on the same terminal as FRAME.
1240By default, skip minibuffer-only frames.
1241If omitted, FRAME defaults to the selected frame.
1242If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1243If MINIFRAME is a window, include only its own frame
1244and any frame now using that window as the minibuffer.
1245If MINIFRAME is `visible', include all visible frames.
1246If MINIFRAME is 0, include all visible and iconified frames.
1247Otherwise, include all frames. */)
1248 (frame, miniframe)
8693ca83 1249 Lisp_Object frame, miniframe;
dc6f92b8 1250{
ff11dfa1 1251 if (NILP (frame))
8d2666fe 1252 frame = selected_frame;
177c0ea7 1253
b7826503 1254 CHECK_LIVE_FRAME (frame);
ff11dfa1 1255 return next_frame (frame, miniframe);
dc6f92b8 1256}
dbc4e1c1 1257
ef2c57ac 1258DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
14ff1ee0
PJ
1259 doc: /* Return the previous frame in the frame list before FRAME.
1260It considers only frames on the same terminal as FRAME.
1261By default, skip minibuffer-only frames.
1262If omitted, FRAME defaults to the selected frame.
1263If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1264If MINIFRAME is a window, include only its own frame
1265and any frame now using that window as the minibuffer.
1266If MINIFRAME is `visible', include all visible frames.
1267If MINIFRAME is 0, include all visible and iconified frames.
1268Otherwise, include all frames. */)
1269 (frame, miniframe)
ef2c57ac
RM
1270 Lisp_Object frame, miniframe;
1271{
ef2c57ac 1272 if (NILP (frame))
8d2666fe 1273 frame = selected_frame;
b7826503 1274 CHECK_LIVE_FRAME (frame);
ef2c57ac
RM
1275 return prev_frame (frame, miniframe);
1276}
dc6f92b8 1277\f
808c0f20
RS
1278/* Return 1 if it is ok to delete frame F;
1279 0 if all frames aside from F are invisible.
1280 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 1281
d56b45eb 1282int
808c0f20
RS
1283other_visible_frames (f)
1284 FRAME_PTR f;
1285{
1286 /* We know the selected frame is visible,
1287 so if F is some other frame, it can't be the sole visible one. */
8d2666fe 1288 if (f == SELECTED_FRAME ())
c08c95c7
RS
1289 {
1290 Lisp_Object frames;
1291 int count = 0;
1292
1293 for (frames = Vframe_list;
1294 CONSP (frames);
7539e11f 1295 frames = XCDR (frames))
c08c95c7 1296 {
ab9f008d 1297 Lisp_Object this;
c08c95c7 1298
7539e11f 1299 this = XCAR (frames);
808c0f20
RS
1300 /* Verify that the frame's window still exists
1301 and we can still talk to it. And note any recent change
1302 in visibility. */
032d78fe
GV
1303#ifdef HAVE_WINDOW_SYSTEM
1304 if (FRAME_WINDOW_P (XFRAME (this)))
5e7b7c5b 1305 {
b0509a40 1306 x_sync (XFRAME (this));
5e7b7c5b
RS
1307 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1308 }
1309#endif
1310
c08c95c7
RS
1311 if (FRAME_VISIBLE_P (XFRAME (this))
1312 || FRAME_ICONIFIED_P (XFRAME (this))
1313 /* Allow deleting the terminal frame when at least
1314 one X frame exists! */
032d78fe 1315 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
c08c95c7
RS
1316 count++;
1317 }
808c0f20 1318 return count > 1;
c08c95c7 1319 }
808c0f20
RS
1320 return 1;
1321}
1322
ea161626
KL
1323/* Error handler for `delete-frame-functions'. */
1324static Lisp_Object
1325delete_frame_handler (Lisp_Object arg)
1326{
1327 add_to_log ("Error during `delete-frame': %s", arg, Qnil);
1328 return Qnil;
1329}
1330
58555d81
SM
1331extern Lisp_Object Qrun_hook_with_args;
1332
808c0f20 1333DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
14ff1ee0
PJ
1334 doc: /* Delete FRAME, permanently eliminating it from use.
1335If omitted, FRAME defaults to the selected frame.
1336A frame may not be deleted if its minibuffer is used by other frames.
1337Normally, you may not delete a frame if all other frames are invisible,
1338but if the second optional argument FORCE is non-nil, you may do so.
1339
cd1d850f
JPW
1340This function runs `delete-frame-functions' before actually deleting the
1341frame, unless the frame is a tooltip.
a31787b1
RS
1342The functions are run with one arg, the frame to be deleted.
1343But FORCE inhibits this too. */)
1344/* FORCE is non-nil when handling a disconnected terminal. */
14ff1ee0 1345 (frame, force)
808c0f20
RS
1346 Lisp_Object frame, force;
1347{
1348 struct frame *f;
8d2666fe 1349 struct frame *sf = SELECTED_FRAME ();
bedb9c0e
KL
1350 struct kboard *kb;
1351
99b92e64 1352 int minibuffer_selected;
808c0f20
RS
1353
1354 if (EQ (frame, Qnil))
1355 {
8d2666fe 1356 f = sf;
2d80a27a 1357 XSETFRAME (frame, f);
808c0f20
RS
1358 }
1359 else
1360 {
b7826503 1361 CHECK_FRAME (frame);
808c0f20
RS
1362 f = XFRAME (frame);
1363 }
1364
1365 if (! FRAME_LIVE_P (f))
1366 return Qnil;
1367
e39a993c 1368 if (NILP (force) && !other_visible_frames (f))
808c0f20 1369 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 1370
00c5fd51
RS
1371#if 0
1372 /* This is a nice idea, but x_connection_closed needs to be able
1373 to delete the last frame, if it is gone. */
7539e11f 1374 if (NILP (XCDR (Vframe_list)))
e9687ee8 1375 error ("Attempt to delete the only frame");
00c5fd51 1376#endif
e9687ee8 1377
ff11dfa1
JB
1378 /* Does this frame have a minibuffer, and is it the surrogate
1379 minibuffer for any other frame? */
fd0c2bd1 1380 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 1381 {
ff11dfa1 1382 Lisp_Object frames;
1113d9db 1383
ff11dfa1
JB
1384 for (frames = Vframe_list;
1385 CONSP (frames);
7539e11f 1386 frames = XCDR (frames))
1113d9db 1387 {
7a8cc307 1388 Lisp_Object this;
7539e11f 1389 this = XCAR (frames);
1113d9db 1390
ff11dfa1
JB
1391 if (! EQ (this, frame)
1392 && EQ (frame,
7a8cc307
RS
1393 WINDOW_FRAME (XWINDOW
1394 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
a31787b1
RS
1395 {
1396 /* If we MUST delete this frame, delete the other first. */
1397 if (!NILP (force))
1398 Fdelete_frame (this, force);
1399 else
1400 error ("Attempt to delete a surrogate minibuffer frame");
1401 }
1113d9db 1402 }
dc6f92b8
JB
1403 }
1404
a31787b1 1405 /* Run `delete-frame-functions'
c53956fe
SM
1406 unless FORCE is `noelisp' or frame is a tooltip.
1407 FORCE is set to `noelisp' when handling a disconnect from the terminal,
a31787b1 1408 so we don't dare call Lisp code. */
58555d81
SM
1409 if (NILP (Vrun_hooks) || !NILP (Fframe_parameter (frame, intern ("tooltip"))))
1410 ;
1411 if (EQ (force, Qnoelisp))
1412 pending_funcalls
1413 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1414 pending_funcalls);
1415 else
1416 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
0e662342 1417
b6660415
KL
1418 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1419 if (! FRAME_LIVE_P (f))
1420 return Qnil;
1421
a31787b1
RS
1422 /* At this point, we are committed to deleting the frame.
1423 There is no more chance for errors to prevent it. */
1424
99b92e64
RS
1425 minibuffer_selected = EQ (minibuf_window, selected_window);
1426
ff11dfa1 1427 /* Don't let the frame remain selected. */
8d2666fe 1428 if (f == sf)
06537cc8
RS
1429 {
1430 Lisp_Object tail, frame1;
1431
1432 /* Look for another visible frame on the same terminal. */
1433 frame1 = next_frame (frame, Qvisible);
1434
1435 /* If there is none, find *some* other frame. */
1436 if (NILP (frame1) || EQ (frame1, frame))
1437 {
1438 FOR_EACH_FRAME (tail, frame1)
1439 {
fca177d4 1440 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
06537cc8
RS
1441 break;
1442 }
1443 }
1444
1e8324d9 1445 do_switch_frame (frame1, 0, 1);
79a65b7f 1446 sf = SELECTED_FRAME ();
06537cc8 1447 }
dc6f92b8 1448
ff11dfa1
JB
1449 /* Don't allow minibuf_window to remain on a deleted frame. */
1450 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 1451 {
8d2666fe 1452 Fset_window_buffer (sf->minibuffer_window,
5af5757b 1453 XWINDOW (minibuf_window)->buffer, Qnil);
8d2666fe 1454 minibuf_window = sf->minibuffer_window;
99b92e64
RS
1455
1456 /* If the dying minibuffer window was selected,
1457 select the new one. */
1458 if (minibuffer_selected)
f1321dc3 1459 Fselect_window (minibuf_window, Qnil);
dc6f92b8
JB
1460 }
1461
130adcb7
EZ
1462 /* Don't let echo_area_window to remain on a deleted frame. */
1463 if (EQ (f->minibuffer_window, echo_area_window))
1464 echo_area_window = sf->minibuffer_window;
1465
bb2a0a65
RS
1466 /* Clear any X selections for this frame. */
1467#ifdef HAVE_X_WINDOWS
1468 if (FRAME_X_P (f))
1469 x_clear_frame_selections (f);
1470#endif
1471
177c0ea7
JB
1472 /* Free glyphs.
1473 This function must be called before the window tree of the
18082e2d
GM
1474 frame is deleted because windows contain dynamically allocated
1475 memory. */
1476 free_glyphs (f);
1477
1ccdfd33 1478#ifdef HAVE_WINDOW_SYSTEM
50e3873c
KH
1479 /* Give chance to each font driver to free a frame specific data. */
1480 font_update_drivers (f, Qnil);
1ccdfd33 1481#endif
50e3873c 1482
4a88b3b0
JB
1483 /* Mark all the windows that used to be on FRAME as deleted, and then
1484 remove the reference to them. */
1485 delete_all_subwindows (XWINDOW (f->root_window));
1486 f->root_window = Qnil;
1487
ff11dfa1 1488 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 1489 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 1490
70fdbb46
JM
1491 xfree (f->namebuf);
1492 xfree (f->decode_mode_spec_buffer);
1493 xfree (FRAME_INSERT_COST (f));
1494 xfree (FRAME_DELETEN_COST (f));
1495 xfree (FRAME_INSERTN_COST (f));
1496 xfree (FRAME_DELETE_COST (f));
1497 xfree (FRAME_MESSAGE_BUF (f));
d2bee99e 1498
8678b9cc 1499 /* Since some events are handled at the interrupt level, we may get
6ed8eeff 1500 an event for f at any time; if we zero out the frame's terminal
8678b9cc 1501 now, then we may trip up the event-handling code. Instead, we'll
6ed8eeff
KL
1502 promise that the terminal of the frame must be valid until we
1503 have called the window-system-dependent frame destruction
1504 routine. */
dbc4e1c1 1505
6ed8eeff
KL
1506 if (FRAME_TERMINAL (f)->delete_frame_hook)
1507 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
d5e7c279 1508
428a555e 1509 {
6ed8eeff 1510 struct terminal *terminal = FRAME_TERMINAL (f);
a3547743 1511 f->output_data.nothing = 0;
6ed8eeff 1512 f->terminal = 0; /* Now the frame is dead. */
428a555e 1513
6ed8eeff 1514 /* If needed, delete the terminal that this frame was on.
bedb9c0e 1515 (This must be done after the frame is killed.) */
6ed8eeff
KL
1516 terminal->reference_count--;
1517 if (terminal->reference_count == 0)
bedb9c0e 1518 {
174105f7
SM
1519 Lisp_Object tmp;
1520 XSETTERMINAL (tmp, terminal);
1521
bedb9c0e 1522 kb = NULL;
174105f7 1523 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
bedb9c0e
KL
1524 }
1525 else
6ed8eeff 1526 kb = terminal->kboard;
428a555e 1527 }
8678b9cc 1528
ff11dfa1 1529 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1530 another one. */
ff11dfa1 1531 if (f == last_nonminibuf_frame)
d5e7c279 1532 {
ff11dfa1 1533 Lisp_Object frames;
1113d9db 1534
ff11dfa1 1535 last_nonminibuf_frame = 0;
d5e7c279 1536
ff11dfa1
JB
1537 for (frames = Vframe_list;
1538 CONSP (frames);
7539e11f 1539 frames = XCDR (frames))
d5e7c279 1540 {
7539e11f 1541 f = XFRAME (XCAR (frames));
ff11dfa1 1542 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1543 {
ff11dfa1 1544 last_nonminibuf_frame = f;
d5e7c279
JB
1545 break;
1546 }
1547 }
1548 }
dc6f92b8 1549
8ceb7434
RS
1550 /* If there's no other frame on the same kboard, get out of
1551 single-kboard state if we're in it for this kboard. */
bedb9c0e
KL
1552 if (kb != NULL)
1553 {
1554 Lisp_Object frames;
1555 /* Some frame we found on the same kboard, or nil if there are none. */
1556 Lisp_Object frame_on_same_kboard;
8ceb7434 1557
bedb9c0e 1558 frame_on_same_kboard = Qnil;
8ceb7434 1559
bedb9c0e
KL
1560 for (frames = Vframe_list;
1561 CONSP (frames);
1562 frames = XCDR (frames))
1563 {
1564 Lisp_Object this;
1565 struct frame *f1;
8ceb7434 1566
bedb9c0e
KL
1567 this = XCAR (frames);
1568 if (!FRAMEP (this))
1569 abort ();
1570 f1 = XFRAME (this);
8ceb7434 1571
bedb9c0e
KL
1572 if (kb == FRAME_KBOARD (f1))
1573 frame_on_same_kboard = this;
1574 }
8ceb7434 1575
bedb9c0e
KL
1576 if (NILP (frame_on_same_kboard))
1577 not_single_kboard_state (kb);
1578 }
8ceb7434
RS
1579
1580
c4c6d073
KH
1581 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1582 find another one. Prefer minibuffer-only frames, but also notice
1583 frames with other windows. */
bedb9c0e 1584 if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
1113d9db 1585 {
ff11dfa1 1586 Lisp_Object frames;
1113d9db 1587
ff11dfa1 1588 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1589 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1590 /* Some frame we found on the same kboard, or nil if there are none. */
1591 Lisp_Object frame_on_same_kboard;
1113d9db 1592
32fda9ba 1593 frame_on_same_kboard = Qnil;
ab9f008d 1594 frame_with_minibuf = Qnil;
32fda9ba 1595
ff11dfa1
JB
1596 for (frames = Vframe_list;
1597 CONSP (frames);
7539e11f 1598 frames = XCDR (frames))
1113d9db 1599 {
ab9f008d 1600 Lisp_Object this;
c4c6d073 1601 struct frame *f1;
1113d9db 1602
7539e11f 1603 this = XCAR (frames);
e35d291d 1604 if (!FRAMEP (this))
1113d9db 1605 abort ();
c4c6d073 1606 f1 = XFRAME (this);
1113d9db 1607
c4c6d073
KH
1608 /* Consider only frames on the same kboard
1609 and only those with minibuffers. */
bedb9c0e 1610 if (kb == FRAME_KBOARD (f1)
c4c6d073 1611 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1612 {
ff11dfa1 1613 frame_with_minibuf = this;
c4c6d073 1614 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1615 break;
1616 }
32fda9ba 1617
bedb9c0e 1618 if (kb == FRAME_KBOARD (f1))
32fda9ba 1619 frame_on_same_kboard = this;
1113d9db
JB
1620 }
1621
32fda9ba
RS
1622 if (!NILP (frame_on_same_kboard))
1623 {
1624 /* We know that there must be some frame with a minibuffer out
1625 there. If this were not true, all of the frames present
1626 would have to be minibufferless, which implies that at some
1627 point their minibuffer frames must have been deleted, but
1628 that is prohibited at the top; you can't delete surrogate
1629 minibuffer frames. */
1630 if (NILP (frame_with_minibuf))
1631 abort ();
1113d9db 1632
bedb9c0e 1633 kb->Vdefault_minibuffer_frame = frame_with_minibuf;
32fda9ba
RS
1634 }
1635 else
1636 /* No frames left on this kboard--say no minibuffer either. */
bedb9c0e 1637 kb->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1638 }
1639
e681c92a
RS
1640 /* Cause frame titles to update--necessary if we now have just one frame. */
1641 update_mode_lines = 1;
1642
dc6f92b8
JB
1643 return Qnil;
1644}
1645\f
1646/* Return mouse position in character cell units. */
1647
f9898cc6 1648DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
14ff1ee0
PJ
1649 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1650The position is given in character cells, where (0, 0) is the
d0cd961e
EZ
1651upper-left corner of the frame, X is the horizontal offset, and Y is
1652the vertical offset.
14ff1ee0
PJ
1653If Emacs is running on a mouseless terminal or hasn't been programmed
1654to read the mouse position, it returns the selected frame for FRAME
1655and nil for X and Y.
1656If `mouse-position-function' is non-nil, `mouse-position' calls it,
1657passing the normal return value to that function as an argument,
1658and returns whatever that function returns. */)
1659 ()
dc6f92b8 1660{
ff11dfa1 1661 FRAME_PTR f;
dbc4e1c1 1662 Lisp_Object lispy_dummy;
fd2777e0 1663 enum scroll_bar_part party_dummy;
beb0bc36 1664 Lisp_Object x, y, retval;
5384466a 1665 int col, row;
dbc4e1c1 1666 unsigned long long_dummy;
cb2255b3 1667 struct gcpro gcpro1;
dc6f92b8 1668
8d2666fe 1669 f = SELECTED_FRAME ();
c5074d8c
RS
1670 x = y = Qnil;
1671
67f6e31c 1672#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
c5074d8c 1673 /* It's okay for the hook to refrain from storing anything. */
6ed8eeff
KL
1674 if (FRAME_TERMINAL (f)->mouse_position_hook)
1675 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1676 &lispy_dummy, &party_dummy,
1677 &x, &y,
1678 &long_dummy);
76db7eb4
KH
1679 if (! NILP (x))
1680 {
1681 col = XINT (x);
1682 row = XINT (y);
8126c3b4 1683 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1684 XSETINT (x, col);
1685 XSETINT (y, row);
1686 }
f443c170 1687#endif
2d80a27a 1688 XSETFRAME (lispy_dummy, f);
beb0bc36 1689 retval = Fcons (lispy_dummy, Fcons (x, y));
cb2255b3 1690 GCPRO1 (retval);
beb0bc36 1691 if (!NILP (Vmouse_position_function))
cb2255b3
GM
1692 retval = call1 (Vmouse_position_function, retval);
1693 RETURN_UNGCPRO (retval);
dc6f92b8
JB
1694}
1695
152e6c70
RS
1696DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1697 Smouse_pixel_position, 0, 0, 0,
14ff1ee0
PJ
1698 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1699The position is given in pixel units, where (0, 0) is the
d0cd961e
EZ
1700upper-left corner of the frame, X is the horizontal offset, and Y is
1701the vertical offset.
14ff1ee0
PJ
1702If Emacs is running on a mouseless terminal or hasn't been programmed
1703to read the mouse position, it returns the selected frame for FRAME
1704and nil for X and Y. */)
1705 ()
152e6c70
RS
1706{
1707 FRAME_PTR f;
1708 Lisp_Object lispy_dummy;
1709 enum scroll_bar_part party_dummy;
1710 Lisp_Object x, y;
152e6c70
RS
1711 unsigned long long_dummy;
1712
8d2666fe 1713 f = SELECTED_FRAME ();
152e6c70
RS
1714 x = y = Qnil;
1715
67f6e31c 1716#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
152e6c70 1717 /* It's okay for the hook to refrain from storing anything. */
6ed8eeff
KL
1718 if (FRAME_TERMINAL (f)->mouse_position_hook)
1719 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1720 &lispy_dummy, &party_dummy,
1721 &x, &y,
1722 &long_dummy);
0c5c1cf7 1723#endif
2d80a27a 1724 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1725 return Fcons (lispy_dummy, Fcons (x, y));
1726}
1727
dc6f92b8 1728DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
14ff1ee0
PJ
1729 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1730Coordinates are relative to the frame, not a window,
1731so the coordinates of the top left character in the frame
1732may be nonzero due to left-hand scroll bars or the menu bar.
1733
d0cd961e
EZ
1734The position is given in character cells, where (0, 0) is the
1735upper-left corner of the frame, X is the horizontal offset, and Y is
1736the vertical offset.
1737
14ff1ee0
PJ
1738This function is a no-op for an X frame that is not visible.
1739If you have just created a frame, you must wait for it to become visible
1740before calling this function on it, like this.
1741 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
ff11dfa1
JB
1742 (frame, x, y)
1743 Lisp_Object frame, x, y;
dc6f92b8 1744{
b7826503
PJ
1745 CHECK_LIVE_FRAME (frame);
1746 CHECK_NUMBER (x);
1747 CHECK_NUMBER (y);
dc6f92b8 1748
dbc4e1c1 1749 /* I think this should be done with a hook. */
032d78fe
GV
1750#ifdef HAVE_WINDOW_SYSTEM
1751 if (FRAME_WINDOW_P (XFRAME (frame)))
d19be8a9 1752 /* Warping the mouse will cause enternotify and focus events. */
d4d76014 1753 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
bb221971 1754#else
be625e00 1755#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1756 if (FRAME_MSDOS_P (XFRAME (frame)))
1757 {
20dc6fbb 1758 Fselect_frame (frame);
bb221971
RS
1759 mouse_moveto (XINT (x), XINT (y));
1760 }
4d1d51d2
NR
1761#else
1762#ifdef HAVE_GPM
1763 {
1764 Fselect_frame (frame);
1765 term_mouse_moveto (XINT (x), XINT (y));
1766 }
1767#endif
bb221971 1768#endif
dc6f92b8
JB
1769#endif
1770
1771 return Qnil;
1772}
152e6c70
RS
1773
1774DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1775 Sset_mouse_pixel_position, 3, 3, 0,
14ff1ee0 1776 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
d0cd961e
EZ
1777The position is given in pixels, where (0, 0) is the upper-left corner
1778of the frame, X is the horizontal offset, and Y is the vertical offset.
1779
14ff1ee0
PJ
1780Note, this is a no-op for an X frame that is not visible.
1781If you have just created a frame, you must wait for it to become visible
1782before calling this function on it, like this.
1783 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
152e6c70
RS
1784 (frame, x, y)
1785 Lisp_Object frame, x, y;
1786{
b7826503
PJ
1787 CHECK_LIVE_FRAME (frame);
1788 CHECK_NUMBER (x);
1789 CHECK_NUMBER (y);
152e6c70
RS
1790
1791 /* I think this should be done with a hook. */
032d78fe
GV
1792#ifdef HAVE_WINDOW_SYSTEM
1793 if (FRAME_WINDOW_P (XFRAME (frame)))
d19be8a9 1794 /* Warping the mouse will cause enternotify and focus events. */
d4d76014 1795 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
bb221971 1796#else
be625e00 1797#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1798 if (FRAME_MSDOS_P (XFRAME (frame)))
1799 {
20dc6fbb 1800 Fselect_frame (frame);
bb221971
RS
1801 mouse_moveto (XINT (x), XINT (y));
1802 }
67f6e31c
NR
1803#else
1804#ifdef HAVE_GPM
1805 {
1806 Fselect_frame (frame);
1807 term_mouse_moveto (XINT (x), XINT (y));
1808 }
1809#endif
bb221971 1810#endif
152e6c70
RS
1811#endif
1812
1813 return Qnil;
1814}
dc6f92b8 1815\f
98ce1622
RS
1816static void make_frame_visible_1 P_ ((Lisp_Object));
1817
ff11dfa1 1818DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1819 0, 1, "",
14ff1ee0
PJ
1820 doc: /* Make the frame FRAME visible (assuming it is an X window).
1821If omitted, FRAME defaults to the currently selected frame. */)
1822 (frame)
ff11dfa1 1823 Lisp_Object frame;
dc6f92b8 1824{
1aa66088 1825 if (NILP (frame))
8d2666fe 1826 frame = selected_frame;
1aa66088 1827
b7826503 1828 CHECK_LIVE_FRAME (frame);
dc6f92b8 1829
dbc4e1c1 1830 /* I think this should be done with a hook. */
032d78fe
GV
1831#ifdef HAVE_WINDOW_SYSTEM
1832 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1833 {
1834 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1835 x_make_frame_visible (XFRAME (frame));
1836 }
fd0c2bd1 1837#endif
dc6f92b8 1838
98ce1622
RS
1839 make_frame_visible_1 (XFRAME (frame)->root_window);
1840
d19be8a9 1841 /* Make menu bar update for the Buffers and Frames menus. */
565620a5
RS
1842 windows_or_buffers_changed++;
1843
ff11dfa1 1844 return frame;
dc6f92b8
JB
1845}
1846
98ce1622
RS
1847/* Update the display_time slot of the buffers shown in WINDOW
1848 and all its descendents. */
1849
1850static void
1851make_frame_visible_1 (window)
1852 Lisp_Object window;
1853{
1854 struct window *w;
1855
1856 for (;!NILP (window); window = w->next)
1857 {
1858 w = XWINDOW (window);
1859
1860 if (!NILP (w->buffer))
1861 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1862
1863 if (!NILP (w->vchild))
1864 make_frame_visible_1 (w->vchild);
1865 if (!NILP (w->hchild))
1866 make_frame_visible_1 (w->hchild);
1867 }
1868}
1869
ff11dfa1 1870DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1871 0, 2, "",
14ff1ee0
PJ
1872 doc: /* Make the frame FRAME invisible (assuming it is an X window).
1873If omitted, FRAME defaults to the currently selected frame.
1874Normally you may not make FRAME invisible if all other frames are invisible,
1875but if the second optional argument FORCE is non-nil, you may do so. */)
808c0f20
RS
1876 (frame, force)
1877 Lisp_Object frame, force;
dc6f92b8 1878{
1aa66088 1879 if (NILP (frame))
8d2666fe 1880 frame = selected_frame;
1aa66088 1881
b7826503 1882 CHECK_LIVE_FRAME (frame);
dc6f92b8 1883
808c0f20
RS
1884 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1885 error ("Attempt to make invisible the sole visible or iconified frame");
1886
3d378fdf 1887#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17 1888 /* Don't let the frame remain selected. */
8d2666fe 1889 if (EQ (frame, selected_frame))
1e8324d9 1890 do_switch_frame (next_frame (frame, Qt), 0, 0)
3d378fdf 1891#endif
9c394f17
RS
1892
1893 /* Don't allow minibuf_window to remain on a deleted frame. */
1894 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1895 {
8d2666fe
GM
1896 struct frame *sf = XFRAME (selected_frame);
1897 Fset_window_buffer (sf->minibuffer_window,
5af5757b 1898 XWINDOW (minibuf_window)->buffer, Qnil);
8d2666fe 1899 minibuf_window = sf->minibuffer_window;
9c394f17
RS
1900 }
1901
dbc4e1c1 1902 /* I think this should be done with a hook. */
032d78fe
GV
1903#ifdef HAVE_WINDOW_SYSTEM
1904 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1905 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1906#endif
dc6f92b8 1907
d19be8a9 1908 /* Make menu bar update for the Buffers and Frames menus. */
565620a5
RS
1909 windows_or_buffers_changed++;
1910
dc6f92b8
JB
1911 return Qnil;
1912}
1913
ff11dfa1 1914DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1915 0, 1, "",
14ff1ee0
PJ
1916 doc: /* Make the frame FRAME into an icon.
1917If omitted, FRAME defaults to the currently selected frame. */)
ff11dfa1
JB
1918 (frame)
1919 Lisp_Object frame;
dc6f92b8 1920{
1aa66088 1921 if (NILP (frame))
8d2666fe 1922 frame = selected_frame;
177c0ea7 1923
b7826503 1924 CHECK_LIVE_FRAME (frame);
dc6f92b8 1925
3d378fdf 1926#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17 1927 /* Don't let the frame remain selected. */
8d2666fe 1928 if (EQ (frame, selected_frame))
20dc6fbb 1929 Fhandle_switch_frame (next_frame (frame, Qt));
3d378fdf 1930#endif
9c394f17
RS
1931
1932 /* Don't allow minibuf_window to remain on a deleted frame. */
1933 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1934 {
8d2666fe
GM
1935 struct frame *sf = XFRAME (selected_frame);
1936 Fset_window_buffer (sf->minibuffer_window,
5af5757b 1937 XWINDOW (minibuf_window)->buffer, Qnil);
8d2666fe 1938 minibuf_window = sf->minibuffer_window;
9c394f17
RS
1939 }
1940
dbc4e1c1 1941 /* I think this should be done with a hook. */
032d78fe
GV
1942#ifdef HAVE_WINDOW_SYSTEM
1943 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1944 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1945#endif
dc6f92b8 1946
d19be8a9 1947 /* Make menu bar update for the Buffers and Frames menus. */
565620a5
RS
1948 windows_or_buffers_changed++;
1949
dc6f92b8
JB
1950 return Qnil;
1951}
1952
ff11dfa1 1953DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1954 1, 1, 0,
14ff1ee0
PJ
1955 doc: /* Return t if FRAME is now \"visible\" (actually in use for display).
1956A frame that is not \"visible\" is not updated and, if it works through
1957a window system, it may not show at all.
e4ed805e
LT
1958Return the symbol `icon' if frame is visible only as an icon.
1959
1960On a text-only terminal, all frames are considered visible, whether
1961they are currently being displayed or not, and this function returns t
1962for all frames. */)
14ff1ee0 1963 (frame)
ff11dfa1 1964 Lisp_Object frame;
dc6f92b8 1965{
b7826503 1966 CHECK_LIVE_FRAME (frame);
dc6f92b8 1967
5c044f55
RS
1968 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1969
a42e9724 1970 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1971 return Qt;
a42e9724 1972 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1973 return Qicon;
dc6f92b8
JB
1974 return Qnil;
1975}
1976
ff11dfa1 1977DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1978 0, 0, 0,
14ff1ee0 1979 doc: /* Return a list of all frames now \"visible\" (being updated). */)
dc6f92b8
JB
1980 ()
1981{
ff11dfa1
JB
1982 Lisp_Object tail, frame;
1983 struct frame *f;
dc6f92b8
JB
1984 Lisp_Object value;
1985
1986 value = Qnil;
7539e11f 1987 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
dc6f92b8 1988 {
7539e11f 1989 frame = XCAR (tail);
e35d291d 1990 if (!FRAMEP (frame))
dc6f92b8 1991 continue;
ff11dfa1 1992 f = XFRAME (frame);
a42e9724 1993 if (FRAME_VISIBLE_P (f))
ff11dfa1 1994 value = Fcons (frame, value);
dc6f92b8
JB
1995 }
1996 return value;
1997}
d5e7c279
JB
1998
1999
e518d5e1 2000DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
14ff1ee0 2001 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
e4ed805e 2002If FRAME is invisible or iconified, make it visible.
14ff1ee0
PJ
2003If you don't specify a frame, the selected frame is used.
2004If Emacs is displaying on an ordinary terminal or some other device which
2005doesn't support multiple overlapping frames, this function does nothing. */)
2006 (frame)
dbc4e1c1
JB
2007 Lisp_Object frame;
2008{
428a555e 2009 struct frame *f;
828ac693 2010 if (NILP (frame))
8d2666fe 2011 frame = selected_frame;
828ac693 2012
b7826503 2013 CHECK_LIVE_FRAME (frame);
8a981af5 2014
428a555e 2015 f = XFRAME (frame);
a3547743 2016
8a981af5
RS
2017 /* Do like the documentation says. */
2018 Fmake_frame_visible (frame);
2019
6ed8eeff
KL
2020 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2021 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
dbc4e1c1
JB
2022
2023 return Qnil;
2024}
2025
b49f5578 2026/* Should we have a corresponding function called Flower_Power? */
e518d5e1 2027DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
14ff1ee0
PJ
2028 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2029If you don't specify a frame, the selected frame is used.
2030If Emacs is displaying on an ordinary terminal or some other device which
2031doesn't support multiple overlapping frames, this function does nothing. */)
2032 (frame)
dbc4e1c1
JB
2033 Lisp_Object frame;
2034{
428a555e 2035 struct frame *f;
a3547743 2036
828ac693 2037 if (NILP (frame))
8d2666fe 2038 frame = selected_frame;
828ac693 2039
b7826503 2040 CHECK_LIVE_FRAME (frame);
177c0ea7 2041
428a555e 2042 f = XFRAME (frame);
a3547743 2043
6ed8eeff
KL
2044 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2045 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
dbc4e1c1
JB
2046
2047 return Qnil;
2048}
2049
d5e7c279 2050\f
ff11dfa1 2051DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 2052 1, 2, 0,
14ff1ee0
PJ
2053 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2054In other words, switch-frame events caused by events in FRAME will
2055request a switch to FOCUS-FRAME, and `last-event-frame' will be
2056FOCUS-FRAME after reading an event typed at FRAME.
2057
2058If FOCUS-FRAME is omitted or nil, any existing redirection is
2059cancelled, and the frame again receives its own keystrokes.
2060
2061Focus redirection is useful for temporarily redirecting keystrokes to
2062a surrogate minibuffer frame when a frame doesn't have its own
2063minibuffer window.
2064
66a9dbbe 2065A frame's focus redirection can be changed by `select-frame'. If frame
14ff1ee0
PJ
2066FOO is selected, and then a different frame BAR is selected, any
2067frames redirecting their focus to FOO are shifted to redirect their
2068focus to BAR. This allows focus redirection to work properly when the
2069user switches from one frame to another using `select-window'.
2070
2071This means that a frame whose focus is redirected to itself is treated
2072differently from a frame whose focus is redirected to nil; the former
66a9dbbe 2073is affected by `select-frame', while the latter is not.
14ff1ee0
PJ
2074
2075The redirection lasts until `redirect-frame-focus' is called to change it. */)
2076 (frame, focus_frame)
2077 Lisp_Object frame, focus_frame;
d5e7c279 2078{
428a555e 2079 struct frame *f;
a3547743 2080
13144095
JB
2081 /* Note that we don't check for a live frame here. It's reasonable
2082 to redirect the focus of a frame you're about to delete, if you
2083 know what other frame should receive those keystrokes. */
b7826503 2084 CHECK_FRAME (frame);
f9898cc6 2085
a42e9724 2086 if (! NILP (focus_frame))
b7826503 2087 CHECK_LIVE_FRAME (focus_frame);
d5e7c279 2088
428a555e 2089 f = XFRAME (frame);
a3547743 2090
428a555e 2091 f->focus_frame = focus_frame;
d5e7c279 2092
6ed8eeff
KL
2093 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
2094 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
177c0ea7 2095
d5e7c279
JB
2096 return Qnil;
2097}
2098
2099
ff11dfa1 2100DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
14ff1ee0
PJ
2101 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
2102This returns nil if FRAME's focus is not redirected.
2103See `redirect-frame-focus'. */)
2104 (frame)
2105 Lisp_Object frame;
d5e7c279 2106{
b7826503 2107 CHECK_LIVE_FRAME (frame);
a42e9724 2108
ff11dfa1 2109 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
2110}
2111
2112
dc6f92b8 2113\f
329ca574
RS
2114/* Return the value of frame parameter PROP in frame FRAME. */
2115
dc6f92b8 2116Lisp_Object
ff11dfa1
JB
2117get_frame_param (frame, prop)
2118 register struct frame *frame;
dc6f92b8
JB
2119 Lisp_Object prop;
2120{
2121 register Lisp_Object tem;
2122
ff11dfa1 2123 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
2124 if (EQ (tem, Qnil))
2125 return tem;
2126 return Fcdr (tem);
2127}
2128
329ca574
RS
2129/* Return the buffer-predicate of the selected frame. */
2130
2131Lisp_Object
98ce1622
RS
2132frame_buffer_predicate (frame)
2133 Lisp_Object frame;
329ca574 2134{
98ce1622 2135 return XFRAME (frame)->buffer_predicate;
329ca574
RS
2136}
2137
fa54c6ae
RS
2138/* Return the buffer-list of the selected frame. */
2139
2140Lisp_Object
98ce1622
RS
2141frame_buffer_list (frame)
2142 Lisp_Object frame;
fa54c6ae 2143{
98ce1622 2144 return XFRAME (frame)->buffer_list;
fa54c6ae
RS
2145}
2146
2147/* Set the buffer-list of the selected frame. */
2148
2149void
98ce1622
RS
2150set_frame_buffer_list (frame, list)
2151 Lisp_Object frame, list;
fa54c6ae 2152{
98ce1622 2153 XFRAME (frame)->buffer_list = list;
fa54c6ae
RS
2154}
2155
a18b8cb5 2156/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
fa54c6ae
RS
2157
2158void
2159frames_discard_buffer (buffer)
2160 Lisp_Object buffer;
2161{
2162 Lisp_Object frame, tail;
2163
2164 FOR_EACH_FRAME (tail, frame)
2165 {
2166 XFRAME (frame)->buffer_list
2167 = Fdelq (buffer, XFRAME (frame)->buffer_list);
a18b8cb5
KL
2168 XFRAME (frame)->buried_buffer_list
2169 = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
fa54c6ae
RS
2170 }
2171}
2172
329ca574
RS
2173/* Modify the alist in *ALISTPTR to associate PROP with VAL.
2174 If the alist already has an element for PROP, we change it. */
2175
dc6f92b8 2176void
fd0c2bd1 2177store_in_alist (alistptr, prop, val)
dc6f92b8 2178 Lisp_Object *alistptr, val;
fd0c2bd1 2179 Lisp_Object prop;
dc6f92b8
JB
2180{
2181 register Lisp_Object tem;
dc6f92b8 2182
dc6f92b8
JB
2183 tem = Fassq (prop, *alistptr);
2184 if (EQ (tem, Qnil))
2185 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2186 else
2187 Fsetcdr (tem, val);
2188}
2189
e5317d61
EZ
2190static int
2191frame_name_fnn_p (str, len)
2192 char *str;
0432e6a1 2193 EMACS_INT len;
e5317d61
EZ
2194{
2195 if (len > 1 && str[0] == 'F')
2196 {
2197 char *end_ptr;
e5317d61 2198
48970f2f
EZ
2199 strtol (str + 1, &end_ptr, 10);
2200
e5317d61
EZ
2201 if (end_ptr == str + len)
2202 return 1;
2203 }
2204 return 0;
2205}
2206
2207/* Set the name of the terminal frame. Also used by MSDOS frames.
2208 Modeled after x_set_name which is used for WINDOW frames. */
2209
66a9dbbe 2210static void
e5317d61
EZ
2211set_term_frame_name (f, name)
2212 struct frame *f;
2213 Lisp_Object name;
2214{
2215 f->explicit_name = ! NILP (name);
2216
2217 /* If NAME is nil, set the name to F<num>. */
2218 if (NILP (name))
2219 {
2220 char namebuf[20];
2221
2222 /* Check for no change needed in this very common case
2223 before we do any consing. */
d5db4077
KR
2224 if (frame_name_fnn_p (SDATA (f->name),
2225 SBYTES (f->name)))
e5317d61
EZ
2226 return;
2227
6ed8eeff
KL
2228 tty_frame_count++;
2229 sprintf (namebuf, "F%d", tty_frame_count);
e5317d61
EZ
2230 name = build_string (namebuf);
2231 }
2232 else
2233 {
b7826503 2234 CHECK_STRING (name);
e5317d61
EZ
2235
2236 /* Don't change the name if it's already NAME. */
2237 if (! NILP (Fstring_equal (name, f->name)))
2238 return;
2239
2240 /* Don't allow the user to set the frame name to F<num>, so it
2241 doesn't clash with the names we generate for terminal frames. */
d5db4077 2242 if (frame_name_fnn_p (SDATA (name), SBYTES (name)))
e5317d61
EZ
2243 error ("Frame names of the form F<num> are usurped by Emacs");
2244 }
2245
2246 f->name = name;
2247 update_mode_lines = 1;
2248}
2249
dc6f92b8 2250void
ff11dfa1
JB
2251store_frame_param (f, prop, val)
2252 struct frame *f;
dc6f92b8
JB
2253 Lisp_Object prop, val;
2254{
7eb63b72 2255 register Lisp_Object old_alist_elt;
dc6f92b8 2256
a18b8cb5
KL
2257 /* The buffer-list parameters are stored in a special place and not
2258 in the alist. */
fa54c6ae
RS
2259 if (EQ (prop, Qbuffer_list))
2260 {
2261 f->buffer_list = val;
2262 return;
2263 }
a18b8cb5
KL
2264 if (EQ (prop, Qburied_buffer_list))
2265 {
2266 f->buried_buffer_list = val;
2267 return;
2268 }
fa54c6ae 2269
7eb63b72
GM
2270 /* If PROP is a symbol which is supposed to have frame-local values,
2271 and it is set up based on this frame, switch to the global
2272 binding. That way, we can create or alter the frame-local binding
2273 without messing up the symbol's status. */
2274 if (SYMBOLP (prop))
2275 {
2276 Lisp_Object valcontents;
f5c1dd0d 2277 valcontents = SYMBOL_VALUE (prop);
67ee9f6e 2278 if ((BUFFER_LOCAL_VALUEP (valcontents))
7eb63b72 2279 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
486420a9 2280 && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame
7eb63b72
GM
2281 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
2282 swap_in_global_binding (prop);
2283 }
2284
94674d18 2285#ifndef WINDOWSNT
9b2cd403
SM
2286 /* The tty color needed to be set before the frame's parameter
2287 alist was updated with the new value. This is not true any more,
2288 but we still do this test early on. */
2289 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2290 && f == FRAME_TTY (f)->previous_frame)
2291 /* Force redisplay of this tty. */
2292 FRAME_TTY (f)->previous_frame = NULL;
94674d18
EZ
2293#endif
2294
7eb63b72
GM
2295 /* Update the frame parameter alist. */
2296 old_alist_elt = Fassq (prop, f->param_alist);
2297 if (EQ (old_alist_elt, Qnil))
ff11dfa1 2298 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8 2299 else
7eb63b72 2300 Fsetcdr (old_alist_elt, val);
bc93c097 2301
7eb63b72
GM
2302 /* Update some other special parameters in their special places
2303 in addition to the alist. */
177c0ea7 2304
329ca574
RS
2305 if (EQ (prop, Qbuffer_predicate))
2306 f->buffer_predicate = val;
2307
032d78fe 2308 if (! FRAME_WINDOW_P (f))
e5317d61
EZ
2309 {
2310 if (EQ (prop, Qmenu_bar_lines))
2311 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2312 else if (EQ (prop, Qname))
2313 set_term_frame_name (f, val);
2314 }
a249de79 2315
e35d291d 2316 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
2317 {
2318 if (! MINI_WINDOW_P (XWINDOW (val)))
6b61353c 2319 error ("Surrogate minibuffer windows must be minibuffer windows");
bc93c097 2320
213bac8a 2321 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
7af7ef38
KH
2322 && !EQ (val, f->minibuffer_window))
2323 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
2324
2325 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 2326 f->minibuffer_window = val;
bc93c097 2327 }
dc6f92b8
JB
2328}
2329
ff11dfa1 2330DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
14ff1ee0
PJ
2331 doc: /* Return the parameters-alist of frame FRAME.
2332It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2333The meaningful PARMs depend on the kind of frame.
2334If FRAME is omitted, return information on the currently selected frame. */)
2335 (frame)
ff11dfa1 2336 Lisp_Object frame;
dc6f92b8
JB
2337{
2338 Lisp_Object alist;
f769f1b2 2339 FRAME_PTR f;
dd10ec4f 2340 int height, width;
57629833 2341 struct gcpro gcpro1;
dc6f92b8 2342
03390a72 2343 if (NILP (frame))
8d2666fe
GM
2344 frame = selected_frame;
2345
b7826503 2346 CHECK_FRAME (frame);
8d2666fe 2347 f = XFRAME (frame);
dc6f92b8 2348
f769f1b2 2349 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
2350 return Qnil;
2351
ff11dfa1 2352 alist = Fcopy_alist (f->param_alist);
57629833 2353 GCPRO1 (alist);
177c0ea7 2354
2d764c78 2355 if (!FRAME_WINDOW_P (f))
bb221971 2356 {
4aec4b29
EZ
2357 int fg = FRAME_FOREGROUND_PIXEL (f);
2358 int bg = FRAME_BACKGROUND_PIXEL (f);
e1d0bbc9
EZ
2359 Lisp_Object elt;
2360
2361 /* If the frame's parameter alist says the colors are
2362 unspecified and reversed, take the frame's background pixel
2363 for foreground and vice versa. */
2364 elt = Fassq (Qforeground_color, alist);
19b5e79b 2365 if (CONSP (elt) && STRINGP (XCDR (elt)))
70de9f06 2366 {
d5db4077 2367 if (strncmp (SDATA (XCDR (elt)),
70de9f06 2368 unspecified_bg,
d5db4077 2369 SCHARS (XCDR (elt))) == 0)
70de9f06 2370 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
d5db4077 2371 else if (strncmp (SDATA (XCDR (elt)),
70de9f06 2372 unspecified_fg,
d5db4077 2373 SCHARS (XCDR (elt))) == 0)
70de9f06
EZ
2374 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2375 }
e1d0bbc9
EZ
2376 else
2377 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2378 elt = Fassq (Qbackground_color, alist);
19b5e79b 2379 if (CONSP (elt) && STRINGP (XCDR (elt)))
70de9f06 2380 {
d5db4077 2381 if (strncmp (SDATA (XCDR (elt)),
70de9f06 2382 unspecified_fg,
d5db4077 2383 SCHARS (XCDR (elt))) == 0)
70de9f06 2384 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
d5db4077 2385 else if (strncmp (SDATA (XCDR (elt)),
70de9f06 2386 unspecified_bg,
d5db4077 2387 SCHARS (XCDR (elt))) == 0)
70de9f06
EZ
2388 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2389 }
e1d0bbc9
EZ
2390 else
2391 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2d764c78
EZ
2392 store_in_alist (&alist, intern ("font"),
2393 build_string (FRAME_MSDOS_P (f)
2394 ? "ms-dos"
4ec0d3c1 2395 : FRAME_W32_P (f) ? "w32term"
4ec0d3c1 2396 :"tty"));
bb221971 2397 }
fd0c2bd1 2398 store_in_alist (&alist, Qname, f->name);
5af5757b 2399 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
dd10ec4f 2400 store_in_alist (&alist, Qheight, make_number (height));
5af5757b 2401 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
dd10ec4f 2402 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 2403 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 2404 store_in_alist (&alist, Qminibuffer,
39acc701 2405 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
2406 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2407 : FRAME_MINIBUF_WINDOW (f)));
2408 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
03390a72 2409 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
a18b8cb5 2410 store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
fd0c2bd1 2411
dbc4e1c1 2412 /* I think this should be done with a hook. */
032d78fe
GV
2413#ifdef HAVE_WINDOW_SYSTEM
2414 if (FRAME_WINDOW_P (f))
ff11dfa1 2415 x_report_frame_params (f, &alist);
b6dd20ed 2416 else
fd0c2bd1 2417#endif
16a3738c
KH
2418 {
2419 /* This ought to be correct in f->param_alist for an X frame. */
2420 Lisp_Object lines;
f4e93c40 2421 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
2422 store_in_alist (&alist, Qmenu_bar_lines, lines);
2423 }
57629833
GM
2424
2425 UNGCPRO;
dc6f92b8
JB
2426 return alist;
2427}
2428
8b60f7bc
GM
2429
2430DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
14ff1ee0
PJ
2431 doc: /* Return FRAME's value for parameter PARAMETER.
2432If FRAME is nil, describe the currently selected frame. */)
2433 (frame, parameter)
2434 Lisp_Object frame, parameter;
8b60f7bc
GM
2435{
2436 struct frame *f;
2437 Lisp_Object value;
2438
2439 if (NILP (frame))
2440 frame = selected_frame;
2441 else
b7826503
PJ
2442 CHECK_FRAME (frame);
2443 CHECK_SYMBOL (parameter);
177c0ea7 2444
8b60f7bc
GM
2445 f = XFRAME (frame);
2446 value = Qnil;
177c0ea7 2447
8b60f7bc
GM
2448 if (FRAME_LIVE_P (f))
2449 {
5cd62b8c 2450 /* Avoid consing in frequent cases. */
67d853e6
GM
2451 if (EQ (parameter, Qname))
2452 value = f->name;
6345f6aa
GM
2453#ifdef HAVE_X_WINDOWS
2454 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2455 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2456#endif /* HAVE_X_WINDOWS */
75700ff2
GM
2457 else if (EQ (parameter, Qbackground_color)
2458 || EQ (parameter, Qforeground_color))
67d853e6
GM
2459 {
2460 value = Fassq (parameter, f->param_alist);
2461 if (CONSP (value))
5f65b39d 2462 {
5f65b39d
EZ
2463 value = XCDR (value);
2464 /* Fframe_parameters puts the actual fg/bg color names,
2465 even if f->param_alist says otherwise. This is
2466 important when param_alist's notion of colors is
2467 "unspecified". We need to do the same here. */
2468 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2469 {
c9b08ba8 2470 const char *color_name;
e1d0bbc9
EZ
2471 EMACS_INT csz;
2472
2473 if (EQ (parameter, Qbackground_color))
2474 {
d5db4077
KR
2475 color_name = SDATA (value);
2476 csz = SCHARS (value);
e1d0bbc9
EZ
2477 if (strncmp (color_name, unspecified_bg, csz) == 0)
2478 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2479 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2480 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2481 }
2482 else if (EQ (parameter, Qforeground_color))
2483 {
d5db4077
KR
2484 color_name = SDATA (value);
2485 csz = SCHARS (value);
e1d0bbc9
EZ
2486 if (strncmp (color_name, unspecified_fg, csz) == 0)
2487 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2488 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2489 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2490 }
5f65b39d
EZ
2491 }
2492 }
b23236fb
EZ
2493 else
2494 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
67d853e6 2495 }
75700ff2
GM
2496 else if (EQ (parameter, Qdisplay_type)
2497 || EQ (parameter, Qbackground_mode))
75700ff2
GM
2498 value = Fcdr (Fassq (parameter, f->param_alist));
2499 else
2500 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
8b60f7bc 2501 }
177c0ea7 2502
8b60f7bc
GM
2503 return value;
2504}
2505
2506
177c0ea7 2507DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
ff11dfa1 2508 Smodify_frame_parameters, 2, 2, 0,
14ff1ee0
PJ
2509 doc: /* Modify the parameters of frame FRAME according to ALIST.
2510If FRAME is nil, it defaults to the selected frame.
2511ALIST is an alist of parameters to change and their new values.
2512Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2513The meaningful PARMs depend on the kind of frame.
2514Undefined PARMs are ignored, but stored in the frame's parameter list
2515so that `frame-parameters' will return them.
2516
2517The value of frame parameter FOO can also be accessed
2518as a frame-local binding for the variable FOO, if you have
2519enabled such bindings for that variable with `make-variable-frame-local'. */)
2520 (frame, alist)
ff11dfa1 2521 Lisp_Object frame, alist;
dc6f92b8 2522{
fd0c2bd1 2523 FRAME_PTR f;
213bac8a 2524 register Lisp_Object tail, prop, val;
dc6f92b8 2525
ff11dfa1 2526 if (EQ (frame, Qnil))
8d2666fe 2527 frame = selected_frame;
b7826503 2528 CHECK_LIVE_FRAME (frame);
8d2666fe 2529 f = XFRAME (frame);
dc6f92b8 2530
dbc4e1c1 2531 /* I think this should be done with a hook. */
032d78fe
GV
2532#ifdef HAVE_WINDOW_SYSTEM
2533 if (FRAME_WINDOW_P (f))
fd0c2bd1 2534 x_set_frame_parameters (f, alist);
329ca574 2535 else
bb221971
RS
2536#endif
2537#ifdef MSDOS
2538 if (FRAME_MSDOS_P (f))
2539 IT_set_frame_parameters (f, alist);
2540 else
329ca574 2541#endif
574a1a90 2542
41d44f1f
RS
2543 {
2544 int length = XINT (Flength (alist));
2545 int i;
2546 Lisp_Object *parms
2547 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2548 Lisp_Object *values
2549 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2550
2551 /* Extract parm names and values into those vectors. */
2552
2553 i = 0;
d7b10f4c 2554 for (tail = alist; CONSP (tail); tail = XCDR (tail))
41d44f1f 2555 {
213bac8a 2556 Lisp_Object elt;
41d44f1f 2557
d7b10f4c 2558 elt = XCAR (tail);
41d44f1f
RS
2559 parms[i] = Fcar (elt);
2560 values[i] = Fcdr (elt);
2561 i++;
2562 }
2563
2564 /* Now process them in reverse of specified order. */
2565 for (i--; i >= 0; i--)
2566 {
2567 prop = parms[i];
2568 val = values[i];
2569 store_frame_param (f, prop, val);
33d537f0
JL
2570
2571 /* Changing the background color might change the background
2572 mode, so that we have to load new defface specs.
2573 Call frame-set-background-mode to do that. */
2574 if (EQ (prop, Qbackground_color))
2575 call1 (Qframe_set_background_mode, frame);
41d44f1f
RS
2576 }
2577 }
3b58be21 2578 return Qnil;
dc6f92b8
JB
2579}
2580\f
a26a1f95 2581DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
14ff1ee0
PJ
2582 0, 1, 0,
2583 doc: /* Height in pixels of a line in the font in frame FRAME.
2584If FRAME is omitted, the selected frame is used.
2585For a terminal frame, the value is always 1. */)
ff11dfa1
JB
2586 (frame)
2587 Lisp_Object frame;
dc6f92b8 2588{
a26a1f95 2589 struct frame *f;
dc6f92b8 2590
a26a1f95 2591 if (NILP (frame))
8d2666fe 2592 frame = selected_frame;
b7826503 2593 CHECK_FRAME (frame);
8d2666fe 2594 f = XFRAME (frame);
a26a1f95 2595
032d78fe
GV
2596#ifdef HAVE_WINDOW_SYSTEM
2597 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2598 return make_number (x_char_height (f));
2599 else
dc6d9681 2600#endif
a26a1f95
RS
2601 return make_number (1);
2602}
dc6d9681 2603
dc6f92b8 2604
a26a1f95 2605DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
14ff1ee0
PJ
2606 0, 1, 0,
2607 doc: /* Width in pixels of characters in the font in frame FRAME.
2608If FRAME is omitted, the selected frame is used.
31b7cc74 2609On a graphical screen, the width is the standard width of the default font.
14ff1ee0
PJ
2610For a terminal screen, the value is always 1. */)
2611 (frame)
a26a1f95 2612 Lisp_Object frame;
dc6f92b8 2613{
a26a1f95
RS
2614 struct frame *f;
2615
2616 if (NILP (frame))
8d2666fe 2617 frame = selected_frame;
b7826503 2618 CHECK_FRAME (frame);
8d2666fe 2619 f = XFRAME (frame);
a26a1f95 2620
032d78fe
GV
2621#ifdef HAVE_WINDOW_SYSTEM
2622 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2623 return make_number (x_char_width (f));
2624 else
2625#endif
2626 return make_number (1);
dc6f92b8
JB
2627}
2628
177c0ea7 2629DEFUN ("frame-pixel-height", Fframe_pixel_height,
a26a1f95 2630 Sframe_pixel_height, 0, 1, 0,
14ff1ee0
PJ
2631 doc: /* Return a FRAME's height in pixels.
2632This counts only the height available for text lines,
2633not menu bars on window-system Emacs frames.
2634For a terminal frame, the result really gives the height in characters.
2635If FRAME is omitted, the selected frame is used. */)
2636 (frame)
a26a1f95 2637 Lisp_Object frame;
dc6f92b8 2638{
a26a1f95
RS
2639 struct frame *f;
2640
2641 if (NILP (frame))
8d2666fe 2642 frame = selected_frame;
b7826503 2643 CHECK_FRAME (frame);
8d2666fe 2644 f = XFRAME (frame);
a26a1f95 2645
032d78fe
GV
2646#ifdef HAVE_WINDOW_SYSTEM
2647 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2648 return make_number (x_pixel_height (f));
2649 else
dc6d9681 2650#endif
5af5757b 2651 return make_number (FRAME_LINES (f));
a26a1f95
RS
2652}
2653
177c0ea7 2654DEFUN ("frame-pixel-width", Fframe_pixel_width,
a26a1f95 2655 Sframe_pixel_width, 0, 1, 0,
14ff1ee0
PJ
2656 doc: /* Return FRAME's width in pixels.
2657For a terminal frame, the result really gives the width in characters.
2658If FRAME is omitted, the selected frame is used. */)
2659 (frame)
a26a1f95
RS
2660 Lisp_Object frame;
2661{
2662 struct frame *f;
2663
2664 if (NILP (frame))
8d2666fe 2665 frame = selected_frame;
b7826503 2666 CHECK_FRAME (frame);
8d2666fe 2667 f = XFRAME (frame);
dc6f92b8 2668
032d78fe
GV
2669#ifdef HAVE_WINDOW_SYSTEM
2670 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2671 return make_number (x_pixel_width (f));
2672 else
2673#endif
5af5757b 2674 return make_number (FRAME_COLS (f));
a26a1f95
RS
2675}
2676\f
ff11dfa1 2677DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
14ff1ee0
PJ
2678 doc: /* Specify that the frame FRAME has LINES lines.
2679Optional third arg non-nil means that redisplay should use LINES lines
2680but that the idea of the actual height of the frame should not be changed. */)
2681 (frame, lines, pretend)
735eeca3 2682 Lisp_Object frame, lines, pretend;
dc6f92b8 2683{
ff11dfa1 2684 register struct frame *f;
dc6f92b8 2685
b7826503 2686 CHECK_NUMBER (lines);
ff11dfa1 2687 if (NILP (frame))
8d2666fe 2688 frame = selected_frame;
b7826503 2689 CHECK_LIVE_FRAME (frame);
8d2666fe 2690 f = XFRAME (frame);
dc6f92b8 2691
dbc4e1c1 2692 /* I think this should be done with a hook. */
032d78fe
GV
2693#ifdef HAVE_WINDOW_SYSTEM
2694 if (FRAME_WINDOW_P (f))
dc6f92b8 2695 {
5af5757b
KS
2696 if (XINT (lines) != FRAME_LINES (f))
2697 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
32347cf4 2698 do_pending_window_change (0);
dc6f92b8
JB
2699 }
2700 else
fd0c2bd1 2701#endif
32347cf4 2702 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
dc6f92b8
JB
2703 return Qnil;
2704}
2705
ff11dfa1 2706DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
14ff1ee0
PJ
2707 doc: /* Specify that the frame FRAME has COLS columns.
2708Optional third arg non-nil means that redisplay should use COLS columns
2709but that the idea of the actual width of the frame should not be changed. */)
2710 (frame, cols, pretend)
fd0c2bd1 2711 Lisp_Object frame, cols, pretend;
dc6f92b8 2712{
ff11dfa1 2713 register struct frame *f;
b7826503 2714 CHECK_NUMBER (cols);
ff11dfa1 2715 if (NILP (frame))
8d2666fe 2716 frame = selected_frame;
b7826503 2717 CHECK_LIVE_FRAME (frame);
8d2666fe 2718 f = XFRAME (frame);
dc6f92b8 2719
dbc4e1c1 2720 /* I think this should be done with a hook. */
032d78fe
GV
2721#ifdef HAVE_WINDOW_SYSTEM
2722 if (FRAME_WINDOW_P (f))
dc6f92b8 2723 {
5af5757b
KS
2724 if (XINT (cols) != FRAME_COLS (f))
2725 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
32347cf4 2726 do_pending_window_change (0);
dc6f92b8
JB
2727 }
2728 else
fd0c2bd1 2729#endif
32347cf4 2730 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
dc6f92b8
JB
2731 return Qnil;
2732}
2733
ff11dfa1 2734DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
14ff1ee0
PJ
2735 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2736 (frame, cols, rows)
ff11dfa1 2737 Lisp_Object frame, cols, rows;
dc6f92b8 2738{
ff11dfa1 2739 register struct frame *f;
dc6f92b8 2740
b7826503
PJ
2741 CHECK_LIVE_FRAME (frame);
2742 CHECK_NUMBER (cols);
2743 CHECK_NUMBER (rows);
ff11dfa1 2744 f = XFRAME (frame);
dc6f92b8 2745
dbc4e1c1 2746 /* I think this should be done with a hook. */
032d78fe
GV
2747#ifdef HAVE_WINDOW_SYSTEM
2748 if (FRAME_WINDOW_P (f))
dc6f92b8 2749 {
5af5757b
KS
2750 if (XINT (rows) != FRAME_LINES (f)
2751 || XINT (cols) != FRAME_COLS (f)
2752 || f->new_text_lines || f->new_text_cols)
808c0f20 2753 x_set_window_size (f, 1, XINT (cols), XINT (rows));
32347cf4 2754 do_pending_window_change (0);
dc6f92b8
JB
2755 }
2756 else
fd0c2bd1 2757#endif
32347cf4 2758 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
dc6f92b8
JB
2759
2760 return Qnil;
2761}
2762
177c0ea7 2763DEFUN ("set-frame-position", Fset_frame_position,
ff11dfa1 2764 Sset_frame_position, 3, 3, 0,
14ff1ee0
PJ
2765 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2766This is actually the position of the upper left corner of the frame.
2767Negative values for XOFFSET or YOFFSET are interpreted relative to
2768the rightmost or bottommost possible position (that stays within the screen). */)
2769 (frame, xoffset, yoffset)
ff11dfa1 2770 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2771{
ff11dfa1 2772 register struct frame *f;
dc6f92b8 2773
b7826503
PJ
2774 CHECK_LIVE_FRAME (frame);
2775 CHECK_NUMBER (xoffset);
2776 CHECK_NUMBER (yoffset);
ff11dfa1 2777 f = XFRAME (frame);
dc6f92b8 2778
dbc4e1c1 2779 /* I think this should be done with a hook. */
032d78fe
GV
2780#ifdef HAVE_WINDOW_SYSTEM
2781 if (FRAME_WINDOW_P (f))
c7c70761 2782 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2783#endif
dc6f92b8
JB
2784
2785 return Qt;
2786}
dc6d9681 2787
dc6f92b8 2788\f
972f4259
KS
2789/***********************************************************************
2790 Frame Parameters
2791 ***********************************************************************/
2792
2793/* Connect the frame-parameter names for X frames
2794 to the ways of passing the parameter values to the window system.
2795
2796 The name of a parameter, as a Lisp symbol,
2797 has an `x-frame-parameter' property which is an integer in Lisp
2798 that is an index in this table. */
2799
2800struct frame_parm_table {
2801 char *name;
2802 Lisp_Object *variable;
2803};
2804
2805static struct frame_parm_table frame_parms[] =
2806{
2807 {"auto-raise", &Qauto_raise},
2808 {"auto-lower", &Qauto_lower},
2809 {"background-color", 0},
2810 {"border-color", &Qborder_color},
2811 {"border-width", &Qborder_width},
2812 {"cursor-color", &Qcursor_color},
2813 {"cursor-type", &Qcursor_type},
2814 {"font", 0},
2815 {"foreground-color", 0},
2816 {"icon-name", &Qicon_name},
2817 {"icon-type", &Qicon_type},
2818 {"internal-border-width", &Qinternal_border_width},
2819 {"menu-bar-lines", &Qmenu_bar_lines},
2820 {"mouse-color", &Qmouse_color},
2821 {"name", &Qname},
2822 {"scroll-bar-width", &Qscroll_bar_width},
2823 {"title", &Qtitle},
2824 {"unsplittable", &Qunsplittable},
2825 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2826 {"visibility", &Qvisibility},
2827 {"tool-bar-lines", &Qtool_bar_lines},
2828 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2829 {"scroll-bar-background", &Qscroll_bar_background},
2830 {"screen-gamma", &Qscreen_gamma},
2831 {"line-spacing", &Qline_spacing},
2832 {"left-fringe", &Qleft_fringe},
2833 {"right-fringe", &Qright_fringe},
2834 {"wait-for-wm", &Qwait_for_wm},
2835 {"fullscreen", &Qfullscreen},
0a708637
GM
2836 {"font-backend", &Qfont_backend},
2837 {"alpha", &Qalpha}
972f4259
KS
2838};
2839
2840#ifdef HAVE_WINDOW_SYSTEM
2841
2842extern Lisp_Object Qbox;
2843extern Lisp_Object Qtop;
2844
2845/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
bd45aef7 2846 wanted positions of the WM window (not Emacs window).
972f4259
KS
2847 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2848 window (FRAME_X_WINDOW).
2849 */
2850
dfcf069d 2851void
972f4259
KS
2852x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2853 struct frame *f;
2854 int *width;
2855 int *height;
2856 int *top_pos;
2857 int *left_pos;
dc6f92b8 2858{
5af5757b
KS
2859 int newwidth = FRAME_COLS (f);
2860 int newheight = FRAME_LINES (f);
dc6f92b8 2861
5af5757b
KS
2862 *top_pos = f->top_pos;
2863 *left_pos = f->left_pos;
3df1fda2 2864
5af5757b 2865 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
972f4259
KS
2866 {
2867 int ph;
2868
2869 ph = FRAME_X_DISPLAY_INFO (f)->height;
5af5757b
KS
2870 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2871 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2872 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
972f4259
KS
2873 *top_pos = 0;
2874 }
dc6f92b8 2875
5af5757b 2876 if (f->want_fullscreen & FULLSCREEN_WIDTH)
972f4259
KS
2877 {
2878 int pw;
2879
2880 pw = FRAME_X_DISPLAY_INFO (f)->width;
5af5757b
KS
2881 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2882 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2883 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
972f4259
KS
2884 *left_pos = 0;
2885 }
dc6f92b8 2886
972f4259
KS
2887 *width = newwidth;
2888 *height = newheight;
2889}
dc6f92b8 2890
beb0bc36 2891
972f4259
KS
2892/* Change the parameters of frame F as specified by ALIST.
2893 If a parameter is not specially recognized, do nothing special;
2894 otherwise call the `x_set_...' function for that parameter.
2895 Except for certain geometry properties, always call store_frame_param
2896 to store the new value in the parameter alist. */
14ff1ee0 2897
972f4259
KS
2898void
2899x_set_frame_parameters (f, alist)
2900 FRAME_PTR f;
2901 Lisp_Object alist;
2902{
2903 Lisp_Object tail;
dc6f92b8 2904
972f4259
KS
2905 /* If both of these parameters are present, it's more efficient to
2906 set them both at once. So we wait until we've looked at the
2907 entire list before we set them. */
2908 int width, height;
3df1fda2 2909
972f4259
KS
2910 /* Same here. */
2911 Lisp_Object left, top;
2912
2913 /* Same with these. */
2914 Lisp_Object icon_left, icon_top;
2915
2916 /* Record in these vectors all the parms specified. */
2917 Lisp_Object *parms;
2918 Lisp_Object *values;
2919 int i, p;
2920 int left_no_change = 0, top_no_change = 0;
2921 int icon_left_no_change = 0, icon_top_no_change = 0;
2922 int fullscreen_is_being_set = 0;
2923
2924 struct gcpro gcpro1, gcpro2;
2925
2926 i = 0;
2927 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2928 i++;
2929
2930 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2931 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2932
2933 /* Extract parm names and values into those vectors. */
2934
2935 i = 0;
d7b10f4c 2936 for (tail = alist; CONSP (tail); tail = XCDR (tail))
972f4259
KS
2937 {
2938 Lisp_Object elt;
2939
d7b10f4c 2940 elt = XCAR (tail);
972f4259
KS
2941 parms[i] = Fcar (elt);
2942 values[i] = Fcdr (elt);
2943 i++;
2944 }
2945 /* TAIL and ALIST are not used again below here. */
2946 alist = tail = Qnil;
2947
2948 GCPRO2 (*parms, *values);
2949 gcpro1.nvars = i;
2950 gcpro2.nvars = i;
2951
2952 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2953 because their values appear in VALUES and strings are not valid. */
2954 top = left = Qunbound;
2955 icon_left = icon_top = Qunbound;
2956
2957 /* Provide default values for HEIGHT and WIDTH. */
5af5757b
KS
2958 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2959 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
972f4259
KS
2960
2961 /* Process foreground_color and background_color before anything else.
2962 They are independent of other properties, but other properties (e.g.,
2963 cursor_color) are dependent upon them. */
2964 /* Process default font as well, since fringe widths depends on it. */
2965 /* Also, process fullscreen, width and height depend upon that */
2966 for (p = 0; p < i; p++)
2967 {
2968 Lisp_Object prop, val;
2969
2970 prop = parms[p];
2971 val = values[p];
2972 if (EQ (prop, Qforeground_color)
2973 || EQ (prop, Qbackground_color)
2974 || EQ (prop, Qfont)
2975 || EQ (prop, Qfullscreen))
2976 {
2977 register Lisp_Object param_index, old_value;
2978
2979 old_value = get_frame_param (f, prop);
2980 fullscreen_is_being_set |= EQ (prop, Qfullscreen);
972f4259
KS
2981 if (NILP (Fequal (val, old_value)))
2982 {
2983 store_frame_param (f, prop, val);
2984
2985 param_index = Fget (prop, Qx_frame_parameter);
2986 if (NATNUMP (param_index)
2987 && (XFASTINT (param_index)
2988 < sizeof (frame_parms)/sizeof (frame_parms[0]))
fa971ac3
KL
2989 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2990 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
972f4259
KS
2991 }
2992 }
2993 }
2994
2995 /* Now process them in reverse of specified order. */
2996 for (i--; i >= 0; i--)
2997 {
2998 Lisp_Object prop, val;
2999
3000 prop = parms[i];
3001 val = values[i];
3002
629c715d 3003 if (EQ (prop, Qwidth) && NATNUMP (val))
972f4259 3004 width = XFASTINT (val);
629c715d 3005 else if (EQ (prop, Qheight) && NATNUMP (val))
972f4259
KS
3006 height = XFASTINT (val);
3007 else if (EQ (prop, Qtop))
3008 top = val;
3009 else if (EQ (prop, Qleft))
3010 left = val;
3011 else if (EQ (prop, Qicon_top))
3012 icon_top = val;
3013 else if (EQ (prop, Qicon_left))
3014 icon_left = val;
3015 else if (EQ (prop, Qforeground_color)
3016 || EQ (prop, Qbackground_color)
3017 || EQ (prop, Qfont)
3018 || EQ (prop, Qfullscreen))
3019 /* Processed above. */
3020 continue;
3021 else
3022 {
3023 register Lisp_Object param_index, old_value;
3024
3025 old_value = get_frame_param (f, prop);
3026
3027 store_frame_param (f, prop, val);
3028
3029 param_index = Fget (prop, Qx_frame_parameter);
3030 if (NATNUMP (param_index)
3031 && (XFASTINT (param_index)
3032 < sizeof (frame_parms)/sizeof (frame_parms[0]))
fa971ac3
KL
3033 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3034 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
972f4259
KS
3035 }
3036 }
3037
3038 /* Don't die if just one of these was set. */
3039 if (EQ (left, Qunbound))
3040 {
3041 left_no_change = 1;
5af5757b
KS
3042 if (f->left_pos < 0)
3043 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
972f4259 3044 else
5af5757b 3045 XSETINT (left, f->left_pos);
972f4259
KS
3046 }
3047 if (EQ (top, Qunbound))
3048 {
3049 top_no_change = 1;
5af5757b
KS
3050 if (f->top_pos < 0)
3051 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
972f4259 3052 else
5af5757b 3053 XSETINT (top, f->top_pos);
972f4259
KS
3054 }
3055
3056 /* If one of the icon positions was not set, preserve or default it. */
3057 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
3058 {
3059 icon_left_no_change = 1;
3060 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
3061 if (NILP (icon_left))
3062 XSETINT (icon_left, 0);
3063 }
3064 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
3065 {
3066 icon_top_no_change = 1;
3067 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
3068 if (NILP (icon_top))
3069 XSETINT (icon_top, 0);
3070 }
3071
972f4259
KS
3072 if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
3073 {
3074 /* If the frame is visible already and the fullscreen parameter is
3075 being set, it is too late to set WM manager hints to specify
3076 size and position.
3077 Here we first get the width, height and position that applies to
3078 fullscreen. We then move the frame to the appropriate
3079 position. Resize of the frame is taken care of in the code after
3080 this if-statement. */
3081 int new_left, new_top;
3082
3083 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
6b61353c
KH
3084 if (new_top != f->top_pos || new_left != f->left_pos)
3085 x_set_offset (f, new_left, new_top, 1);
972f4259 3086 }
972f4259
KS
3087
3088 /* Don't set these parameters unless they've been explicitly
3089 specified. The window might be mapped or resized while we're in
3090 this function, and we don't want to override that unless the lisp
3091 code has asked for it.
3092
3093 Don't set these parameters unless they actually differ from the
3094 window's current parameters; the window may not actually exist
3095 yet. */
3096 {
3097 Lisp_Object frame;
3098
3099 check_frame_size (f, &height, &width);
3100
3101 XSETFRAME (frame, f);
3102
5af5757b
KS
3103 if (width != FRAME_COLS (f)
3104 || height != FRAME_LINES (f)
3105 || f->new_text_lines || f->new_text_cols)
972f4259
KS
3106 Fset_frame_size (frame, make_number (width), make_number (height));
3107
3108 if ((!NILP (left) || !NILP (top))
3109 && ! (left_no_change && top_no_change)
5af5757b
KS
3110 && ! (NUMBERP (left) && XINT (left) == f->left_pos
3111 && NUMBERP (top) && XINT (top) == f->top_pos))
972f4259
KS
3112 {
3113 int leftpos = 0;
3114 int toppos = 0;
3115
3116 /* Record the signs. */
5af5757b 3117 f->size_hint_flags &= ~ (XNegative | YNegative);
972f4259 3118 if (EQ (left, Qminus))
5af5757b 3119 f->size_hint_flags |= XNegative;
972f4259
KS
3120 else if (INTEGERP (left))
3121 {
3122 leftpos = XINT (left);
3123 if (leftpos < 0)
5af5757b 3124 f->size_hint_flags |= XNegative;
972f4259
KS
3125 }
3126 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3127 && CONSP (XCDR (left))
3128 && INTEGERP (XCAR (XCDR (left))))
3129 {
3130 leftpos = - XINT (XCAR (XCDR (left)));
5af5757b 3131 f->size_hint_flags |= XNegative;
972f4259
KS
3132 }
3133 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3134 && CONSP (XCDR (left))
3135 && INTEGERP (XCAR (XCDR (left))))
3136 {
3137 leftpos = XINT (XCAR (XCDR (left)));
3138 }
3139
3140 if (EQ (top, Qminus))
5af5757b 3141 f->size_hint_flags |= YNegative;
972f4259
KS
3142 else if (INTEGERP (top))
3143 {
3144 toppos = XINT (top);
3145 if (toppos < 0)
5af5757b 3146 f->size_hint_flags |= YNegative;
972f4259
KS
3147 }
3148 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3149 && CONSP (XCDR (top))
3150 && INTEGERP (XCAR (XCDR (top))))
3151 {
3152 toppos = - XINT (XCAR (XCDR (top)));
5af5757b 3153 f->size_hint_flags |= YNegative;
972f4259
KS
3154 }
3155 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3156 && CONSP (XCDR (top))
3157 && INTEGERP (XCAR (XCDR (top))))
3158 {
3159 toppos = XINT (XCAR (XCDR (top)));
3160 }
3161
3162
3163 /* Store the numeric value of the position. */
5af5757b
KS
3164 f->top_pos = toppos;
3165 f->left_pos = leftpos;
972f4259 3166
5af5757b 3167 f->win_gravity = NorthWestGravity;
972f4259
KS
3168
3169 /* Actually set that position, and convert to absolute. */
3170 x_set_offset (f, leftpos, toppos, -1);
3171 }
3172
3173 if ((!NILP (icon_left) || !NILP (icon_top))
3174 && ! (icon_left_no_change && icon_top_no_change))
3175 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3176 }
3177
3178 UNGCPRO;
3179}
3180
3181
3182/* Insert a description of internally-recorded parameters of frame X
3183 into the parameter alist *ALISTPTR that is to be given to the user.
3184 Only parameters that are specific to the X window system
3185 and whose values are not correctly recorded in the frame's
3186 param_alist need to be considered here. */
3187
3188void
3189x_report_frame_params (f, alistptr)
3190 struct frame *f;
3191 Lisp_Object *alistptr;
3192{
3193 char buf[16];
3194 Lisp_Object tem;
3195
3196 /* Represent negative positions (off the top or left screen edge)
3197 in a way that Fmodify_frame_parameters will understand correctly. */
5af5757b
KS
3198 XSETINT (tem, f->left_pos);
3199 if (f->left_pos >= 0)
972f4259
KS
3200 store_in_alist (alistptr, Qleft, tem);
3201 else
3202 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
3203
5af5757b
KS
3204 XSETINT (tem, f->top_pos);
3205 if (f->top_pos >= 0)
972f4259
KS
3206 store_in_alist (alistptr, Qtop, tem);
3207 else
3208 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
3209
3210 store_in_alist (alistptr, Qborder_width,
5af5757b 3211 make_number (f->border_width));
972f4259 3212 store_in_alist (alistptr, Qinternal_border_width,
5af5757b 3213 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
972f4259 3214 store_in_alist (alistptr, Qleft_fringe,
5af5757b 3215 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
972f4259 3216 store_in_alist (alistptr, Qright_fringe,
5af5757b 3217 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
972f4259
KS
3218 store_in_alist (alistptr, Qscroll_bar_width,
3219 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3220 ? make_number (0)
5af5757b
KS
3221 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3222 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
972f4259
KS
3223 /* nil means "use default width"
3224 for non-toolkit scroll bar.
3225 ruler-mode.el depends on this. */
3226 : Qnil));
3227 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
3228 store_in_alist (alistptr, Qwindow_id,
3229 build_string (buf));
3230#ifdef HAVE_X_WINDOWS
3231#ifdef USE_X_TOOLKIT
3232 /* Tooltip frame may not have this widget. */
3233 if (FRAME_X_OUTPUT (f)->widget)
3234#endif
3235 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
3236 store_in_alist (alistptr, Qouter_window_id,
3237 build_string (buf));
3238#endif
3239 store_in_alist (alistptr, Qicon_name, f->icon_name);
3240 FRAME_SAMPLE_VISIBILITY (f);
3241 store_in_alist (alistptr, Qvisibility,
3242 (FRAME_VISIBLE_P (f) ? Qt
3243 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3244 store_in_alist (alistptr, Qdisplay,
3245 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
3246
3247 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
3248 tem = Qnil;
3249 else
3250 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
5839d7e8 3251 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
972f4259
KS
3252 store_in_alist (alistptr, Qparent_id, tem);
3253}
3254
3255
3256/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3257 the previous value of that parameter, NEW_VALUE is the new value. */
3258
3259void
3260x_set_fullscreen (f, new_value, old_value)
3261 struct frame *f;
3262 Lisp_Object new_value, old_value;
3263{
972f4259 3264 if (NILP (new_value))
5af5757b 3265 f->want_fullscreen = FULLSCREEN_NONE;
972f4259 3266 else if (EQ (new_value, Qfullboth))
5af5757b 3267 f->want_fullscreen = FULLSCREEN_BOTH;
972f4259 3268 else if (EQ (new_value, Qfullwidth))
5af5757b 3269 f->want_fullscreen = FULLSCREEN_WIDTH;
972f4259 3270 else if (EQ (new_value, Qfullheight))
5af5757b 3271 f->want_fullscreen = FULLSCREEN_HEIGHT;
d761dd42 3272
a3547743 3273 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
974b73e8 3274 FRAME_TERMINAL (f)->fullscreen_hook (f);
972f4259
KS
3275}
3276
3277
3278/* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3279 the previous value of that parameter, NEW_VALUE is the new value. */
3280
3281void
3282x_set_line_spacing (f, new_value, old_value)
3283 struct frame *f;
3284 Lisp_Object new_value, old_value;
3285{
3286 if (NILP (new_value))
3287 f->extra_line_spacing = 0;
3288 else if (NATNUMP (new_value))
3289 f->extra_line_spacing = XFASTINT (new_value);
3290 else
9dc95187 3291 signal_error ("Invalid line-spacing", new_value);
972f4259
KS
3292 if (FRAME_VISIBLE_P (f))
3293 redraw_frame (f);
3294}
3295
3296
3297/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3298 the previous value of that parameter, NEW_VALUE is the new value. */
3299
3300void
3301x_set_screen_gamma (f, new_value, old_value)
3302 struct frame *f;
3303 Lisp_Object new_value, old_value;
3304{
05fc2ef7
CY
3305 Lisp_Object bgcolor;
3306
972f4259
KS
3307 if (NILP (new_value))
3308 f->gamma = 0;
3309 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
05fc2ef7
CY
3310 /* The value 0.4545 is the normal viewing gamma. */
3311 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
972f4259 3312 else
9dc95187 3313 signal_error ("Invalid screen-gamma", new_value);
972f4259 3314
05fc2ef7
CY
3315 /* Apply the new gamma value to the frame background. */
3316 bgcolor = Fassq (Qbackground_color, f->param_alist);
3317 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3318 {
3319 Lisp_Object index = Fget (Qbackground_color, Qx_frame_parameter);
3320 if (NATNUMP (index)
3321 && (XFASTINT (index)
3322 < sizeof (frame_parms)/sizeof (frame_parms[0]))
6baa22c1
KL
3323 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
3324 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
3325 (f, bgcolor, Qnil);
05fc2ef7
CY
3326 }
3327
3328 Fclear_face_cache (Qnil);
972f4259
KS
3329}
3330
3331
3332void
3333x_set_font (f, arg, oldval)
3334 struct frame *f;
3335 Lisp_Object arg, oldval;
3336{
972f4259 3337 Lisp_Object frame;
e0c8ad78
KH
3338 int fontset = -1;
3339 Lisp_Object font_object;
972f4259 3340
178377e1 3341 /* Set the frame parameter back to the old value because we may
e0c8ad78
KH
3342 fail to use ARG as the new parameter value. */
3343 store_frame_param (f, Qfont, oldval);
0169d360 3344
e0c8ad78
KH
3345 /* ARG is a fontset name, a font name, or a font object.
3346 In the last case, this function never fail. */
3347 if (STRINGP (arg))
3348 {
3349 fontset = fs_query_fontset (arg, 0);
3350 if (fontset < 0)
0169d360 3351 {
e0c8ad78
KH
3352 font_object = font_open_by_name (f, SDATA (arg));
3353 if (NILP (font_object))
3354 error ("Font `%s' is not defined", SDATA (arg));
3355 arg = AREF (font_object, FONT_NAME_INDEX);
0169d360 3356 }
e0c8ad78
KH
3357 else if (fontset > 0)
3358 {
3359 Lisp_Object ascii_font = fontset_ascii (fontset);
0169d360 3360
e0c8ad78
KH
3361 font_object = font_open_by_name (f, SDATA (ascii_font));
3362 if (NILP (font_object))
3363 error ("Font `%s' is not defined", SDATA (arg));
3364 arg = fontset_name (fontset);
3365 }
0169d360 3366 else
e0c8ad78 3367 error ("The default fontset can't be used for a frame font");
0169d360 3368 }
e0c8ad78 3369 else if (FONT_OBJECT_P (arg))
698ca23e 3370 {
e0c8ad78
KH
3371 font_object = arg;
3372 /* This is store the XLFD font name in the frame parameter for
3373 backward compatiblity. We should store the font-object
3374 itself in the future. */
3375 arg = AREF (font_object, FONT_NAME_INDEX);
698ca23e 3376 }
e0c8ad78
KH
3377 else
3378 signal_error ("Invalid font", arg);
972f4259 3379
e0c8ad78
KH
3380 if (! NILP (Fequal (font_object, oldval)))
3381 return;
3382 x_new_font (f, font_object, fontset);
3383 store_frame_param (f, Qfont, arg);
3384 /* Recalculate toolbar height. */
3385 f->n_tool_bar_rows = 0;
3386 /* Ensure we redraw it. */
3387 clear_current_matrices (f);
ca03f883 3388
e0c8ad78 3389 recompute_basic_faces (f);
972f4259
KS
3390
3391 do_pending_window_change (0);
3392
a6f75881
CY
3393 /* We used to call face-set-after-frame-default here, but it leads to
3394 recursive calls (since that function can set the `default' face's
3395 font which in turns changes the frame's `font' parameter).
3396 Also I don't know what this call is meant to do, but it seems the
3397 wrong way to do it anyway (it does a lot more work than what seems
3398 reasonable in response to a change to `font'). */
972f4259
KS
3399}
3400
3401
1a356571
KH
3402void
3403x_set_font_backend (f, new_value, old_value)
3404 struct frame *f;
3405 Lisp_Object new_value, old_value;
3406{
1a356571
KH
3407 if (! NILP (new_value)
3408 && !CONSP (new_value))
3409 {
3410 char *p0, *p1;
3411
3412 CHECK_STRING (new_value);
3413 p0 = p1 = SDATA (new_value);
3414 new_value = Qnil;
3415 while (*p0)
3416 {
22e64f7c 3417 while (*p1 && ! isspace (*p1) && *p1 != ',') p1++;
1a356571
KH
3418 if (p0 < p1)
3419 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3420 new_value);
3421 if (*p1)
22e64f7c
KH
3422 {
3423 int c;
3424
3425 while ((c = *++p1) && isspace (c));
3426 }
1a356571
KH
3427 p0 = p1;
3428 }
8fb9e675
KH
3429 new_value = Fnreverse (new_value);
3430 }
3431
3432 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3433 return;
3434
e0c8ad78 3435 if (FRAME_FONT (f))
dfdf55c0 3436 free_all_realized_faces (Qnil);
1a356571 3437
dfdf55c0 3438 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
8fb9e675 3439 if (NILP (new_value))
dfdf55c0
KH
3440 {
3441 if (NILP (old_value))
3442 error ("No font backend available");
3443 font_update_drivers (f, old_value);
3444 error ("None of specified font backends are available");
3445 }
8fb9e675
KH
3446 store_frame_param (f, Qfont_backend, new_value);
3447
e0c8ad78 3448 if (FRAME_FONT (f))
8fb9e675
KH
3449 {
3450 Lisp_Object frame;
3451
3452 XSETFRAME (frame, f);
3453 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3454 ++face_change_count;
3455 ++windows_or_buffers_changed;
3456 }
1a356571 3457}
1a356571
KH
3458
3459
972f4259
KS
3460void
3461x_set_fringe_width (f, new_value, old_value)
3462 struct frame *f;
3463 Lisp_Object new_value, old_value;
3464{
3465 compute_fringe_widths (f, 1);
3466}
3467
3468void
3469x_set_border_width (f, arg, oldval)
3470 struct frame *f;
3471 Lisp_Object arg, oldval;
3472{
3473 CHECK_NUMBER (arg);
3474
5af5757b 3475 if (XINT (arg) == f->border_width)
972f4259
KS
3476 return;
3477
972f4259 3478 if (FRAME_X_WINDOW (f) != 0)
dac85f4b 3479 error ("Cannot change the border width of a frame");
972f4259 3480
5af5757b 3481 f->border_width = XINT (arg);
972f4259
KS
3482}
3483
3484void
3485x_set_internal_border_width (f, arg, oldval)
3486 struct frame *f;
3487 Lisp_Object arg, oldval;
3488{
5af5757b 3489 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
972f4259
KS
3490
3491 CHECK_NUMBER (arg);
5af5757b
KS
3492 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3493 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3494 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
972f4259
KS
3495
3496#ifdef USE_X_TOOLKIT
3497 if (FRAME_X_OUTPUT (f)->edit_widget)
3498 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3499#endif
3500
5af5757b 3501 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
972f4259
KS
3502 return;
3503
3504 if (FRAME_X_WINDOW (f) != 0)
3505 {
5af5757b 3506 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3507 SET_FRAME_GARBAGED (f);
3508 do_pending_window_change (0);
3509 }
3510 else
3511 SET_FRAME_GARBAGED (f);
3512}
3513
3514void
3515x_set_visibility (f, value, oldval)
3516 struct frame *f;
3517 Lisp_Object value, oldval;
3518{
3519 Lisp_Object frame;
3520 XSETFRAME (frame, f);
3521
3522 if (NILP (value))
3523 Fmake_frame_invisible (frame, Qt);
3524 else if (EQ (value, Qicon))
3525 Ficonify_frame (frame);
3526 else
3527 Fmake_frame_visible (frame);
3528}
3529
3530void
3531x_set_autoraise (f, arg, oldval)
3532 struct frame *f;
3533 Lisp_Object arg, oldval;
3534{
3535 f->auto_raise = !EQ (Qnil, arg);
3536}
3537
3538void
3539x_set_autolower (f, arg, oldval)
3540 struct frame *f;
3541 Lisp_Object arg, oldval;
3542{
3543 f->auto_lower = !EQ (Qnil, arg);
3544}
3545
3546void
3547x_set_unsplittable (f, arg, oldval)
3548 struct frame *f;
3549 Lisp_Object arg, oldval;
3550{
3551 f->no_split = !NILP (arg);
3552}
3553
3554void
3555x_set_vertical_scroll_bars (f, arg, oldval)
3556 struct frame *f;
3557 Lisp_Object arg, oldval;
3558{
3559 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3560 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3561 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3562 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3563 {
3564 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3565 = (NILP (arg)
3566 ? vertical_scroll_bar_none
3567 : EQ (Qleft, arg)
3568 ? vertical_scroll_bar_left
3569 : EQ (Qright, arg)
3570 ? vertical_scroll_bar_right
6b61353c
KH
3571 : EQ (Qleft, Vdefault_frame_scroll_bars)
3572 ? vertical_scroll_bar_left
3573 : EQ (Qright, Vdefault_frame_scroll_bars)
3574 ? vertical_scroll_bar_right
3575 : vertical_scroll_bar_none);
972f4259
KS
3576
3577 /* We set this parameter before creating the X window for the
3578 frame, so we can get the geometry right from the start.
3579 However, if the window hasn't been created yet, we shouldn't
3580 call x_set_window_size. */
3581 if (FRAME_X_WINDOW (f))
5af5757b 3582 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3583 do_pending_window_change (0);
3584 }
3585}
3586
3587void
3588x_set_scroll_bar_width (f, arg, oldval)
3589 struct frame *f;
3590 Lisp_Object arg, oldval;
3591{
5af5757b 3592 int wid = FRAME_COLUMN_WIDTH (f);
972f4259
KS
3593
3594 if (NILP (arg))
3595 {
3596 x_set_scroll_bar_default_width (f);
3597
3598 if (FRAME_X_WINDOW (f))
5af5757b 3599 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3600 do_pending_window_change (0);
3601 }
3602 else if (INTEGERP (arg) && XINT (arg) > 0
5af5757b 3603 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
972f4259
KS
3604 {
3605 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3606 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3607
5af5757b
KS
3608 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3609 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
972f4259 3610 if (FRAME_X_WINDOW (f))
5af5757b 3611 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
972f4259
KS
3612 do_pending_window_change (0);
3613 }
3614
5af5757b 3615 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
972f4259
KS
3616 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3617 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3618}
3619
3620
3621
3622/* Return non-nil if frame F wants a bitmap icon. */
3623
3624Lisp_Object
3625x_icon_type (f)
3626 FRAME_PTR f;
3627{
3628 Lisp_Object tem;
3629
3630 tem = assq_no_quit (Qicon_type, f->param_alist);
3631 if (CONSP (tem))
3632 return XCDR (tem);
3633 else
3634 return Qnil;
3635}
3636
0a708637
GM
3637void
3638x_set_alpha (f, arg, oldval)
3639 struct frame *f;
3640 Lisp_Object arg, oldval;
3641{
3642 double alpha = 1.0;
3643 double newval[2];
3644 int i, ialpha;
3645 Lisp_Object item;
3646
3647 for (i = 0; i < 2; i++)
3648 {
3649 newval[i] = 1.0;
3650 if (CONSP (arg))
3651 {
3652 item = CAR (arg);
3653 arg = CDR (arg);
3654 }
3655 else
1fd877d6 3656 item = arg;
0a708637
GM
3657
3658 if (! NILP (item))
3659 {
3660 if (FLOATP (item))
3661 {
3662 alpha = XFLOAT_DATA (item);
3663 if (alpha < 0.0 || 1.0 < alpha)
3664 args_out_of_range (make_float (0.0), make_float (1.0));
3665 }
3666 else if (INTEGERP (item))
3667 {
3668 ialpha = XINT (item);
3669 if (ialpha < 0 || 100 < ialpha)
3670 args_out_of_range (make_number (0), make_number (100));
3671 else
3672 alpha = ialpha / 100.0;
3673 }
3674 else
3675 wrong_type_argument (Qnumberp, item);
3676 }
3677 newval[i] = alpha;
3678 }
3679
3680 for (i = 0; i < 2; i++)
3681 f->alpha[i] = newval[i];
3682
8b61a891 3683#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
0a708637
GM
3684 BLOCK_INPUT;
3685 x_set_frame_alpha (f);
3686 UNBLOCK_INPUT;
3687#endif
3688
3689 return;
3690}
3691
972f4259
KS
3692\f
3693/* Subroutines of creating an X frame. */
3694
3695/* Make sure that Vx_resource_name is set to a reasonable value.
3696 Fix it up, or set it to `emacs' if it is too hopeless. */
3697
3698void
3699validate_x_resource_name ()
3700{
3701 int len = 0;
3702 /* Number of valid characters in the resource name. */
3703 int good_count = 0;
3704 /* Number of invalid characters in the resource name. */
3705 int bad_count = 0;
3706 Lisp_Object new;
3707 int i;
3708
3709 if (!STRINGP (Vx_resource_class))
3710 Vx_resource_class = build_string (EMACS_CLASS);
3711
3712 if (STRINGP (Vx_resource_name))
3713 {
3714 unsigned char *p = SDATA (Vx_resource_name);
3715 int i;
3716
3717 len = SBYTES (Vx_resource_name);
3718
3719 /* Only letters, digits, - and _ are valid in resource names.
3720 Count the valid characters and count the invalid ones. */
3721 for (i = 0; i < len; i++)
3722 {
3723 int c = p[i];
3724 if (! ((c >= 'a' && c <= 'z')
3725 || (c >= 'A' && c <= 'Z')
3726 || (c >= '0' && c <= '9')
3727 || c == '-' || c == '_'))
3728 bad_count++;
3729 else
3730 good_count++;
3731 }
3732 }
3733 else
3734 /* Not a string => completely invalid. */
3735 bad_count = 5, good_count = 0;
3736
3737 /* If name is valid already, return. */
3738 if (bad_count == 0)
3739 return;
3740
3741 /* If name is entirely invalid, or nearly so, use `emacs'. */
3742 if (good_count == 0
3743 || (good_count == 1 && bad_count > 0))
3744 {
3745 Vx_resource_name = build_string ("emacs");
3746 return;
3747 }
3748
3749 /* Name is partly valid. Copy it and replace the invalid characters
3750 with underscores. */
3751
3752 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3753
3754 for (i = 0; i < len; i++)
3755 {
3756 int c = SREF (new, i);
3757 if (! ((c >= 'a' && c <= 'z')
3758 || (c >= 'A' && c <= 'Z')
3759 || (c >= '0' && c <= '9')
3760 || c == '-' || c == '_'))
3761 SSET (new, i, '_');
3762 }
3763}
3764
3765
3766extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3767extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3768
3769
b5251fe7 3770/* Get specified attribute from resource database RDB.
972f4259
KS
3771 See Fx_get_resource below for other parameters. */
3772
3773static Lisp_Object
3774xrdb_get_resource (rdb, attribute, class, component, subclass)
3775 XrmDatabase rdb;
3776 Lisp_Object attribute, class, component, subclass;
3777{
3778 register char *value;
3779 char *name_key;
3780 char *class_key;
3781
3782 CHECK_STRING (attribute);
3783 CHECK_STRING (class);
3784
3785 if (!NILP (component))
3786 CHECK_STRING (component);
3787 if (!NILP (subclass))
3788 CHECK_STRING (subclass);
3789 if (NILP (component) != NILP (subclass))
3790 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3791
3792 validate_x_resource_name ();
3793
3794 /* Allocate space for the components, the dots which separate them,
3795 and the final '\0'. Make them big enough for the worst case. */
3796 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3797 + (STRINGP (component)
3798 ? SBYTES (component) : 0)
3799 + SBYTES (attribute)
3800 + 3);
3801
3802 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3803 + SBYTES (class)
3804 + (STRINGP (subclass)
3805 ? SBYTES (subclass) : 0)
3806 + 3);
3807
3808 /* Start with emacs.FRAMENAME for the name (the specific one)
3809 and with `Emacs' for the class key (the general one). */
3810 strcpy (name_key, SDATA (Vx_resource_name));
3811 strcpy (class_key, SDATA (Vx_resource_class));
3812
3813 strcat (class_key, ".");
3814 strcat (class_key, SDATA (class));
3815
3816 if (!NILP (component))
3817 {
3818 strcat (class_key, ".");
3819 strcat (class_key, SDATA (subclass));
3820
3821 strcat (name_key, ".");
3822 strcat (name_key, SDATA (component));
3823 }
3824
3825 strcat (name_key, ".");
3826 strcat (name_key, SDATA (attribute));
3827
3828 value = x_get_string_resource (rdb, name_key, class_key);
3829
3830 if (value != (char *) 0)
3831 return build_string (value);
3832 else
3833 return Qnil;
3834}
3835
3836
3837DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3838 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3839This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3840class, where INSTANCE is the name under which Emacs was invoked, or
3841the name specified by the `-name' or `-rn' command-line arguments.
3842
3843The optional arguments COMPONENT and SUBCLASS add to the key and the
3844class, respectively. You must specify both of them or neither.
3845If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3846and the class is `Emacs.CLASS.SUBCLASS'. */)
3847 (attribute, class, component, subclass)
3848 Lisp_Object attribute, class, component, subclass;
3849{
3850#ifdef HAVE_X_WINDOWS
3851 check_x ();
3852#endif
3853
3854 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3855 attribute, class, component, subclass);
3856}
3857
3858/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3859
3860Lisp_Object
3861display_x_get_resource (dpyinfo, attribute, class, component, subclass)
a1702920 3862 Display_Info *dpyinfo;
972f4259
KS
3863 Lisp_Object attribute, class, component, subclass;
3864{
3865 return xrdb_get_resource (dpyinfo->xrdb,
3866 attribute, class, component, subclass);
3867}
3868
3869/* Used when C code wants a resource value. */
3870
3871char *
3872x_get_resource_string (attribute, class)
3873 char *attribute, *class;
3874{
3875 char *name_key;
3876 char *class_key;
3877 struct frame *sf = SELECTED_FRAME ();
3878
3879 /* Allocate space for the components, the dots which separate them,
3880 and the final '\0'. */
3881 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3882 + strlen (attribute) + 2);
3883 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3884 + strlen (class) + 2);
3885
3886 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3887 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3888
3889 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3890 name_key, class_key);
3891}
3892
3893
3894/* Return the value of parameter PARAM.
3895
3896 First search ALIST, then Vdefault_frame_alist, then the X defaults
3897 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3898
3899 Convert the resource to the type specified by desired_type.
3900
3901 If no default is specified, return Qunbound. If you call
3902 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3903 and don't let it get stored in any Lisp-visible variables! */
3904
3905Lisp_Object
3906x_get_arg (dpyinfo, alist, param, attribute, class, type)
b5251fe7 3907 Display_Info *dpyinfo;
972f4259
KS
3908 Lisp_Object alist, param;
3909 char *attribute;
3910 char *class;
3911 enum resource_types type;
3912{
3913 register Lisp_Object tem;
3914
3915 tem = Fassq (param, alist);
d00368cf
RS
3916
3917 if (!NILP (tem))
3918 {
3919 /* If we find this parm in ALIST, clear it out
3920 so that it won't be "left over" at the end. */
58ec2913 3921#ifndef WINDOWSNT /* w32fns.c has not yet been changed to cope with this. */
5f694926 3922 Lisp_Object tail;
d00368cf 3923 XSETCAR (tem, Qnil);
5f694926
RS
3924 /* In case the parameter appears more than once in the alist,
3925 clear it out. */
3926 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3927 if (CONSP (XCAR (tail))
3928 && EQ (XCAR (XCAR (tail)), param))
3929 XSETCAR (XCAR (tail), Qnil);
d00368cf
RS
3930#endif
3931 }
3932 else
972f4259 3933 tem = Fassq (param, Vdefault_frame_alist);
d00368cf
RS
3934
3935 /* If it wasn't specified in ALIST or the Lisp-level defaults,
3936 look in the X resources. */
972f4259
KS
3937 if (EQ (tem, Qnil))
3938 {
3939 if (attribute)
3940 {
3941 tem = display_x_get_resource (dpyinfo,
3942 build_string (attribute),
3943 build_string (class),
3944 Qnil, Qnil);
3945
3946 if (NILP (tem))
3947 return Qunbound;
3948
3949 switch (type)
3950 {
3951 case RES_TYPE_NUMBER:
3952 return make_number (atoi (SDATA (tem)));
3953
3954 case RES_TYPE_FLOAT:
3955 return make_float (atof (SDATA (tem)));
3956
3957 case RES_TYPE_BOOLEAN:
3958 tem = Fdowncase (tem);
3959 if (!strcmp (SDATA (tem), "on")
edfda783
AR
3960#ifdef HAVE_NS
3961 || !strcmp(SDATA(tem), "yes")
3962#endif
972f4259
KS
3963 || !strcmp (SDATA (tem), "true"))
3964 return Qt;
3965 else
3966 return Qnil;
3967
3968 case RES_TYPE_STRING:
3969 return tem;
3970
3971 case RES_TYPE_SYMBOL:
3972 /* As a special case, we map the values `true' and `on'
3973 to Qt, and `false' and `off' to Qnil. */
3974 {
3975 Lisp_Object lower;
3976 lower = Fdowncase (tem);
3977 if (!strcmp (SDATA (lower), "on")
edfda783
AR
3978#ifdef HAVE_NS
3979 || !strcmp(SDATA(lower), "yes")
3980#endif
972f4259
KS
3981 || !strcmp (SDATA (lower), "true"))
3982 return Qt;
3983 else if (!strcmp (SDATA (lower), "off")
edfda783
AR
3984#ifdef HAVE_NS
3985 || !strcmp(SDATA(lower), "no")
3986#endif
972f4259
KS
3987 || !strcmp (SDATA (lower), "false"))
3988 return Qnil;
3989 else
3990 return Fintern (tem, Qnil);
3991 }
3992
3993 default:
3994 abort ();
3995 }
3996 }
3997 else
3998 return Qunbound;
3999 }
4000 return Fcdr (tem);
4001}
4002
4003Lisp_Object
4004x_frame_get_arg (f, alist, param, attribute, class, type)
4005 struct frame *f;
4006 Lisp_Object alist, param;
4007 char *attribute;
4008 char *class;
4009 enum resource_types type;
4010{
4011 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
4012 alist, param, attribute, class, type);
4013}
4014
4015/* Like x_frame_get_arg, but also record the value in f->param_alist. */
4016
4017Lisp_Object
4018x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
4019 struct frame *f;
4020 Lisp_Object alist, param;
4021 char *attribute;
4022 char *class;
4023 enum resource_types type;
4024{
4025 Lisp_Object value;
4026
4027 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
4028 attribute, class, type);
edd1c685 4029 if (! NILP (value) && ! EQ (value, Qunbound))
972f4259
KS
4030 store_frame_param (f, param, value);
4031
4032 return value;
4033}
4034
4035
4036/* Record in frame F the specified or default value according to ALIST
4037 of the parameter named PROP (a Lisp symbol).
4038 If no value is specified for PROP, look for an X default for XPROP
4039 on the frame named NAME.
4040 If that is not found either, use the value DEFLT. */
4041
4042Lisp_Object
4043x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
4044 struct frame *f;
4045 Lisp_Object alist;
4046 Lisp_Object prop;
4047 Lisp_Object deflt;
4048 char *xprop;
4049 char *xclass;
4050 enum resource_types type;
4051{
4052 Lisp_Object tem;
4053
4054 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
4055 if (EQ (tem, Qunbound))
4056 tem = deflt;
4057 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
4058 return tem;
4059}
4060
4061
4062
4063\f
dc4db71c
CY
4064#ifdef HAVE_NS
4065
4066/* We used to define x-parse-geometry directly in ns-win.el, but that
4067 confused make-docfile: the documentation string in ns-win.el was
4068 used for x-parse-geometry even in non-NS builds.. */
4069
4070DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4071 doc: /* Parse a Nextstep-style geometry string STRING.
4072Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4073The properties returned may include `top', `left', `height', and `width'.
4074This works by calling `ns-parse-geometry'. */)
4075 (string)
4076 Lisp_Object string;
4077{
4078 call1 (Qns_parse_geometry, string);
4079}
4080
4081#else /* !HAVE_NS */
4082
972f4259
KS
4083DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4084 doc: /* Parse an X-style geometry string STRING.
4085Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4086The properties returned may include `top', `left', `height', and `width'.
4087The value of `left' or `top' may be an integer,
4088or a list (+ N) meaning N pixels relative to top/left corner,
4089or a list (- N) meaning -N pixels relative to bottom/right corner. */)
4090 (string)
4091 Lisp_Object string;
4092{
4093 int geometry, x, y;
4094 unsigned int width, height;
4095 Lisp_Object result;
4096
4097 CHECK_STRING (string);
4098
4099 geometry = XParseGeometry ((char *) SDATA (string),
4100 &x, &y, &width, &height);
972f4259
KS
4101 result = Qnil;
4102 if (geometry & XValue)
4103 {
4104 Lisp_Object element;
4105
4106 if (x >= 0 && (geometry & XNegative))
4107 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
4108 else if (x < 0 && ! (geometry & XNegative))
4109 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
4110 else
4111 element = Fcons (Qleft, make_number (x));
4112 result = Fcons (element, result);
4113 }
4114
4115 if (geometry & YValue)
4116 {
4117 Lisp_Object element;
4118
4119 if (y >= 0 && (geometry & YNegative))
4120 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
4121 else if (y < 0 && ! (geometry & YNegative))
4122 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
4123 else
4124 element = Fcons (Qtop, make_number (y));
4125 result = Fcons (element, result);
4126 }
4127
4128 if (geometry & WidthValue)
4129 result = Fcons (Fcons (Qwidth, make_number (width)), result);
4130 if (geometry & HeightValue)
4131 result = Fcons (Fcons (Qheight, make_number (height)), result);
4132
4133 return result;
4134}
dc4db71c
CY
4135#endif /* HAVE_NS */
4136
972f4259
KS
4137
4138/* Calculate the desired size and position of frame F.
4139 Return the flags saying which aspects were specified.
4140
4141 Also set the win_gravity and size_hint_flags of F.
4142
4143 Adjust height for toolbar if TOOLBAR_P is 1.
4144
4145 This function does not make the coordinates positive. */
4146
4147#define DEFAULT_ROWS 40
4148#define DEFAULT_COLS 80
4149
4150int
4151x_figure_window_size (f, parms, toolbar_p)
4152 struct frame *f;
4153 Lisp_Object parms;
4154 int toolbar_p;
4155{
4156 register Lisp_Object tem0, tem1, tem2;
4157 long window_prompting = 0;
4158 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4159
4160 /* Default values if we fall through.
4161 Actually, if that happens we should get
4162 window manager prompting. */
5af5757b
KS
4163 SET_FRAME_COLS (f, DEFAULT_COLS);
4164 FRAME_LINES (f) = DEFAULT_ROWS;
972f4259
KS
4165 /* Window managers expect that if program-specified
4166 positions are not (0,0), they're intentional, not defaults. */
5af5757b
KS
4167 f->top_pos = 0;
4168 f->left_pos = 0;
972f4259 4169
5af5757b 4170 /* Ensure that old new_text_cols and new_text_lines will not override the
972f4259
KS
4171 values set here. */
4172 /* ++KFS: This was specific to W32, but seems ok for all platforms */
5af5757b 4173 f->new_text_cols = f->new_text_lines = 0;
972f4259
KS
4174
4175 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4176 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4177 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4178 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4179 {
4180 if (!EQ (tem0, Qunbound))
4181 {
4182 CHECK_NUMBER (tem0);
5af5757b 4183 FRAME_LINES (f) = XINT (tem0);
972f4259
KS
4184 }
4185 if (!EQ (tem1, Qunbound))
4186 {
4187 CHECK_NUMBER (tem1);
5af5757b 4188 SET_FRAME_COLS (f, XINT (tem1));
972f4259
KS
4189 }
4190 if (!NILP (tem2) && !EQ (tem2, Qunbound))
4191 window_prompting |= USSize;
4192 else
4193 window_prompting |= PSize;
4194 }
4195
5af5757b
KS
4196 f->scroll_bar_actual_width
4197 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
972f4259
KS
4198
4199 /* This used to be done _before_ calling x_figure_window_size, but
4200 since the height is reset here, this was really a no-op. I
4201 assume that moving it here does what Gerd intended (although he
4202 no longer can remember what that was... ++KFS, 2003-03-25. */
4203
4204 /* Add the tool-bar height to the initial frame height so that the
4205 user gets a text display area of the size he specified with -g or
4206 via .Xdefaults. Later changes of the tool-bar height don't
4207 change the frame size. This is done so that users can create
4208 tall Emacs frames without having to guess how tall the tool-bar
4209 will get. */
4210 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4211 {
4212 int margin, relief, bar_height;
4213
4214 relief = (tool_bar_button_relief >= 0
4215 ? tool_bar_button_relief
4216 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4217
4218 if (INTEGERP (Vtool_bar_button_margin)
4219 && XINT (Vtool_bar_button_margin) > 0)
4220 margin = XFASTINT (Vtool_bar_button_margin);
4221 else if (CONSP (Vtool_bar_button_margin)
4222 && INTEGERP (XCDR (Vtool_bar_button_margin))
4223 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
4224 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4225 else
4226 margin = 0;
4227
4228 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
5af5757b 4229 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
972f4259
KS
4230 }
4231
4232 compute_fringe_widths (f, 0);
4233
5af5757b
KS
4234 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
4235 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
972f4259
KS
4236
4237 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4238 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4239 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4240 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4241 {
4242 if (EQ (tem0, Qminus))
4243 {
5af5757b 4244 f->top_pos = 0;
972f4259
KS
4245 window_prompting |= YNegative;
4246 }
4247 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
4248 && CONSP (XCDR (tem0))
4249 && INTEGERP (XCAR (XCDR (tem0))))
4250 {
5af5757b 4251 f->top_pos = - XINT (XCAR (XCDR (tem0)));
972f4259
KS
4252 window_prompting |= YNegative;
4253 }
4254 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
4255 && CONSP (XCDR (tem0))
4256 && INTEGERP (XCAR (XCDR (tem0))))
4257 {
5af5757b 4258 f->top_pos = XINT (XCAR (XCDR (tem0)));
972f4259
KS
4259 }
4260 else if (EQ (tem0, Qunbound))
5af5757b 4261 f->top_pos = 0;
972f4259
KS
4262 else
4263 {
4264 CHECK_NUMBER (tem0);
5af5757b
KS
4265 f->top_pos = XINT (tem0);
4266 if (f->top_pos < 0)
972f4259
KS
4267 window_prompting |= YNegative;
4268 }
4269
4270 if (EQ (tem1, Qminus))
4271 {
5af5757b 4272 f->left_pos = 0;
972f4259
KS
4273 window_prompting |= XNegative;
4274 }
4275 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
4276 && CONSP (XCDR (tem1))
4277 && INTEGERP (XCAR (XCDR (tem1))))
4278 {
5af5757b 4279 f->left_pos = - XINT (XCAR (XCDR (tem1)));
972f4259
KS
4280 window_prompting |= XNegative;
4281 }
4282 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
4283 && CONSP (XCDR (tem1))
4284 && INTEGERP (XCAR (XCDR (tem1))))
4285 {
5af5757b 4286 f->left_pos = XINT (XCAR (XCDR (tem1)));
972f4259
KS
4287 }
4288 else if (EQ (tem1, Qunbound))
5af5757b 4289 f->left_pos = 0;
972f4259
KS
4290 else
4291 {
4292 CHECK_NUMBER (tem1);
5af5757b
KS
4293 f->left_pos = XINT (tem1);
4294 if (f->left_pos < 0)
972f4259
KS
4295 window_prompting |= XNegative;
4296 }
4297
4298 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
4299 window_prompting |= USPosition;
4300 else
4301 window_prompting |= PPosition;
4302 }
4303
5af5757b 4304 if (f->want_fullscreen != FULLSCREEN_NONE)
972f4259
KS
4305 {
4306 int left, top;
4307 int width, height;
4308
4309 /* It takes both for some WM:s to place it where we want */
7f6fd740 4310 window_prompting |= USPosition | PPosition;
972f4259 4311 x_fullscreen_adjust (f, &width, &height, &top, &left);
5af5757b
KS
4312 FRAME_COLS (f) = width;
4313 FRAME_LINES (f) = height;
4314 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
4315 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
4316 f->left_pos = left;
4317 f->top_pos = top;
972f4259
KS
4318 }
4319
4320 if (window_prompting & XNegative)
4321 {
4322 if (window_prompting & YNegative)
5af5757b 4323 f->win_gravity = SouthEastGravity;
972f4259 4324 else
5af5757b 4325 f->win_gravity = NorthEastGravity;
972f4259
KS
4326 }
4327 else
4328 {
4329 if (window_prompting & YNegative)
5af5757b 4330 f->win_gravity = SouthWestGravity;
972f4259 4331 else
5af5757b 4332 f->win_gravity = NorthWestGravity;
972f4259
KS
4333 }
4334
5af5757b 4335 f->size_hint_flags = window_prompting;
972f4259
KS
4336
4337 return window_prompting;
4338}
4339
4340
4341
4342#endif /* HAVE_WINDOW_SYSTEM */
4343
4344
4345\f
4346/***********************************************************************
4347 Initialization
4348 ***********************************************************************/
4349
4350void
4351syms_of_frame ()
4352{
4353 Qframep = intern ("framep");
4354 staticpro (&Qframep);
4355 Qframe_live_p = intern ("frame-live-p");
4356 staticpro (&Qframe_live_p);
5839d7e8
MR
4357 Qexplicit_name = intern ("explicit-name");
4358 staticpro (&Qexplicit_name);
972f4259
KS
4359 Qheight = intern ("height");
4360 staticpro (&Qheight);
4361 Qicon = intern ("icon");
4362 staticpro (&Qicon);
4363 Qminibuffer = intern ("minibuffer");
4364 staticpro (&Qminibuffer);
4365 Qmodeline = intern ("modeline");
4366 staticpro (&Qmodeline);
4367 Qonly = intern ("only");
4368 staticpro (&Qonly);
4369 Qwidth = intern ("width");
4370 staticpro (&Qwidth);
4371 Qgeometry = intern ("geometry");
4372 staticpro (&Qgeometry);
4373 Qicon_left = intern ("icon-left");
4374 staticpro (&Qicon_left);
4375 Qicon_top = intern ("icon-top");
4376 staticpro (&Qicon_top);
4377 Qleft = intern ("left");
4378 staticpro (&Qleft);
4379 Qright = intern ("right");
4380 staticpro (&Qright);
4381 Quser_position = intern ("user-position");
4382 staticpro (&Quser_position);
4383 Quser_size = intern ("user-size");
4384 staticpro (&Quser_size);
4385 Qwindow_id = intern ("window-id");
4386 staticpro (&Qwindow_id);
4387#ifdef HAVE_X_WINDOWS
4388 Qouter_window_id = intern ("outer-window-id");
4389 staticpro (&Qouter_window_id);
4390#endif
4391 Qparent_id = intern ("parent-id");
4392 staticpro (&Qparent_id);
4393 Qx = intern ("x");
4394 staticpro (&Qx);
4395 Qw32 = intern ("w32");
4396 staticpro (&Qw32);
4397 Qpc = intern ("pc");
4398 staticpro (&Qpc);
4399 Qmac = intern ("mac");
4400 staticpro (&Qmac);
edfda783
AR
4401 Qns = intern ("ns");
4402 staticpro (&Qns);
972f4259
KS
4403 Qvisible = intern ("visible");
4404 staticpro (&Qvisible);
4405 Qbuffer_predicate = intern ("buffer-predicate");
4406 staticpro (&Qbuffer_predicate);
4407 Qbuffer_list = intern ("buffer-list");
4408 staticpro (&Qbuffer_list);
a18b8cb5
KL
4409 Qburied_buffer_list = intern ("buried-buffer-list");
4410 staticpro (&Qburied_buffer_list);
972f4259
KS
4411 Qdisplay_type = intern ("display-type");
4412 staticpro (&Qdisplay_type);
4413 Qbackground_mode = intern ("background-mode");
4414 staticpro (&Qbackground_mode);
c53956fe
SM
4415 Qnoelisp = intern ("noelisp");
4416 staticpro (&Qnoelisp);
972f4259
KS
4417 Qtty_color_mode = intern ("tty-color-mode");
4418 staticpro (&Qtty_color_mode);
28d440ab
KL
4419 Qtty = intern ("tty");
4420 staticpro (&Qtty);
4421 Qtty_type = intern ("tty-type");
4422 staticpro (&Qtty_type);
972f4259
KS
4423
4424 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
4425 staticpro (&Qface_set_after_frame_default);
4426
4427 Qfullwidth = intern ("fullwidth");
4428 staticpro (&Qfullwidth);
4429 Qfullheight = intern ("fullheight");
4430 staticpro (&Qfullheight);
4431 Qfullboth = intern ("fullboth");
4432 staticpro (&Qfullboth);
4433 Qx_resource_name = intern ("x-resource-name");
4434 staticpro (&Qx_resource_name);
4435
4436 Qx_frame_parameter = intern ("x-frame-parameter");
4437 staticpro (&Qx_frame_parameter);
4438
6ed8eeff
KL
4439 Qterminal = intern ("terminal");
4440 staticpro (&Qterminal);
4441 Qterminal_live_p = intern ("terminal-live-p");
4442 staticpro (&Qterminal_live_p);
a3547743 4443
dc4db71c
CY
4444#ifdef HAVE_NS
4445 Qns_parse_geometry = intern ("ns-parse-geometry");
4446 staticpro (&Qns_parse_geometry);
4447#endif
4448
972f4259
KS
4449 {
4450 int i;
4451
4452 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4453 {
4454 Lisp_Object v = intern (frame_parms[i].name);
4455 if (frame_parms[i].variable)
4456 {
4457 *frame_parms[i].variable = v;
4458 staticpro (frame_parms[i].variable);
4459 }
4460 Fput (v, Qx_frame_parameter, make_number (i));
4461 }
4462 }
4463
2731a0ad 4464#ifdef HAVE_WINDOW_SYSTEM
972f4259
KS
4465 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4466 doc: /* The name Emacs uses to look up X resources.
4467`x-get-resource' uses this as the first component of the instance name
4468when requesting resource values.
4469Emacs initially sets `x-resource-name' to the name under which Emacs
4470was invoked, or to the value specified with the `-name' or `-rn'
4471switches, if present.
4472
4473It may be useful to bind this variable locally around a call
4474to `x-get-resource'. See also the variable `x-resource-class'. */);
4475 Vx_resource_name = Qnil;
4476
4477 DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4478 doc: /* The class Emacs uses to look up X resources.
4479`x-get-resource' uses this as the first component of the instance class
4480when requesting resource values.
4481
4482Emacs initially sets `x-resource-class' to "Emacs".
4483
4484Setting this variable permanently is not a reasonable thing to do,
4485but binding this variable locally around a call to `x-get-resource'
4486is a reasonable practice. See also the variable `x-resource-name'. */);
4487 Vx_resource_class = build_string (EMACS_CLASS);
0a708637
GM
4488
4489 DEFVAR_LISP ("frame-alpha-lower-limit", &Vframe_alpha_lower_limit,
4490 doc: /* The lower limit of the frame opacity (alpha transparency).
4491The value should range from 0 (invisible) to 100 (completely opaque).
4492You can also use a floating number between 0.0 and 1.0.
4493The default is 20. */);
4494 Vframe_alpha_lower_limit = make_number (20);
2731a0ad 4495#endif
972f4259
KS
4496
4497 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
4498 doc: /* Alist of default values for frame creation.
4499These may be set in your init file, like this:
5ff00c42 4500 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
972f4259
KS
4501These override values given in window system configuration data,
4502 including X Windows' defaults database.
4503For values specific to the first Emacs frame, see `initial-frame-alist'.
095fe281 4504For window-system specific values, see `window-system-default-frame-alist'.
972f4259
KS
4505For values specific to the separate minibuffer frame, see
4506 `minibuffer-frame-alist'.
4507The `menu-bar-lines' element of the list controls whether new frames
4508 have menu bars; `menu-bar-mode' works by altering this element.
4509Setting this variable does not affect existing frames, only new ones. */);
4510 Vdefault_frame_alist = Qnil;
4511
6b61353c
KH
4512 DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
4513 doc: /* Default position of scroll bars on this window-system. */);
4514#ifdef HAVE_WINDOW_SYSTEM
9e2a2647 4515#if defined(HAVE_NTGUI) || defined(NS_IMPL_COCOA)
edfda783 4516 /* MS-Windows and Mac OS X have scroll bars on the right by default. */
6b61353c
KH
4517 Vdefault_frame_scroll_bars = Qright;
4518#else
4519 Vdefault_frame_scroll_bars = Qleft;
4520#endif
4521#else
4522 Vdefault_frame_scroll_bars = Qnil;
4523#endif
4524
972f4259 4525 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
daf01701 4526 doc: /* The initial frame-object, which represents Emacs's stdout. */);
972f4259
KS
4527
4528 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
bd45aef7 4529 doc: /* Non-nil if all of Emacs is iconified and frame updates are not needed. */);
972f4259
KS
4530 Vemacs_iconified = Qnil;
4531
4532 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
4533 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4534`mouse-position' calls this function, passing its usual return value as
4535argument, and returns whatever this function returns.
4536This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4537which need to do mouse handling at the Lisp level. */);
4538 Vmouse_position_function = Qnil;
4539
4540 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
4541 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4542If the value is an integer, highlighting is only shown after moving the
4543mouse, while keyboard input turns off the highlight even when the mouse
4544is over the clickable text. However, the mouse shape still indicates
4545when the mouse is over clickable text. */);
4546 Vmouse_highlight = Qt;
4547
4548 DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
4549 doc: /* Functions to be run before deleting a frame.
4550The functions are run with one arg, the frame to be deleted.
e519a50b
KL
4551See `delete-frame'.
4552
58555d81
SM
4553Note that functions in this list may be called just before the frame is
4554actually deleted, or some time later (or even both when an earlier function
4555in `delete-frame-functions' (indirectly) calls `delete-frame'
4556recursively). */);
972f4259 4557 Vdelete_frame_functions = Qnil;
58555d81
SM
4558 Qdelete_frame_functions = intern ("delete-frame-functions");
4559 staticpro (&Qdelete_frame_functions);
972f4259
KS
4560
4561 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4562 doc: /* Minibufferless frames use this frame's minibuffer.
4563
4564Emacs cannot create minibufferless frames unless this is set to an
4565appropriate surrogate.
4566
4567Emacs consults this variable only when creating minibufferless
4568frames; once the frame is created, it sticks with its assigned
4569minibuffer, no matter what this variable is set to. This means that
4570this variable doesn't necessarily say anything meaningful about the
4571current set of frames, or where the minibuffer is currently being
4572displayed.
4573
4574This variable is local to the current terminal and cannot be buffer-local. */);
4575
da1da002
MR
4576 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse,
4577 doc: /* Non-nil if window system changes focus when you move the mouse.
4578You should set this variable to tell Emacs how your window manager
4579handles focus, since there is no way in general for Emacs to find out
4580automatically. */);
4581#ifdef HAVE_WINDOW_SYSTEM
9e2a2647 4582#if defined(HAVE_NTGUI) || defined(HAVE_NS)
da1da002
MR
4583 focus_follows_mouse = 0;
4584#else
4585 focus_follows_mouse = 1;
4586#endif
4587#else
4588 focus_follows_mouse = 0;
4589#endif
a3547743 4590
972f4259
KS
4591 staticpro (&Vframe_list);
4592
4593 defsubr (&Sactive_minibuffer_window);
4594 defsubr (&Sframep);
4595 defsubr (&Sframe_live_p);
428a555e 4596 defsubr (&Swindow_system);
972f4259
KS
4597 defsubr (&Smake_terminal_frame);
4598 defsubr (&Shandle_switch_frame);
972f4259
KS
4599 defsubr (&Sselect_frame);
4600 defsubr (&Sselected_frame);
4601 defsubr (&Swindow_frame);
4602 defsubr (&Sframe_root_window);
4603 defsubr (&Sframe_first_window);
4604 defsubr (&Sframe_selected_window);
4605 defsubr (&Sset_frame_selected_window);
4606 defsubr (&Sframe_list);
4607 defsubr (&Snext_frame);
4608 defsubr (&Sprevious_frame);
4609 defsubr (&Sdelete_frame);
4610 defsubr (&Smouse_position);
4611 defsubr (&Smouse_pixel_position);
4612 defsubr (&Sset_mouse_position);
4613 defsubr (&Sset_mouse_pixel_position);
4614#if 0
4615 defsubr (&Sframe_configuration);
4616 defsubr (&Srestore_frame_configuration);
4617#endif
4618 defsubr (&Smake_frame_visible);
4619 defsubr (&Smake_frame_invisible);
4620 defsubr (&Siconify_frame);
4621 defsubr (&Sframe_visible_p);
4622 defsubr (&Svisible_frame_list);
4623 defsubr (&Sraise_frame);
4624 defsubr (&Slower_frame);
4625 defsubr (&Sredirect_frame_focus);
4626 defsubr (&Sframe_focus);
4627 defsubr (&Sframe_parameters);
4628 defsubr (&Sframe_parameter);
4629 defsubr (&Smodify_frame_parameters);
4630 defsubr (&Sframe_char_height);
4631 defsubr (&Sframe_char_width);
4632 defsubr (&Sframe_pixel_height);
4633 defsubr (&Sframe_pixel_width);
4634 defsubr (&Sset_frame_height);
4635 defsubr (&Sset_frame_width);
4636 defsubr (&Sset_frame_size);
4637 defsubr (&Sset_frame_position);
4638
4639#ifdef HAVE_WINDOW_SYSTEM
4640 defsubr (&Sx_get_resource);
4641 defsubr (&Sx_parse_geometry);
4642#endif
4643
dc6f92b8 4644}
6b61353c
KH
4645
4646/* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039
4647 (do not change this comment) */