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