Fully eliminated global tty state variables.
[emacs.git] / src / frame.c
blob72d28c72b7932ad63166547fe3649c2c71c32f39
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2003
3 Free Software Foundation.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <config.h>
24 #include <stdio.h>
25 #include "lisp.h"
26 #include "charset.h"
27 #ifdef HAVE_X_WINDOWS
28 #include "xterm.h"
29 #endif
30 #ifdef WINDOWSNT
31 #include "w32term.h"
32 #endif
33 #ifdef MAC_OS
34 #include "macterm.h"
35 #endif
36 #include "buffer.h"
37 /* These help us bind and responding to switch-frame events. */
38 #include "commands.h"
39 #include "keyboard.h"
40 #include "frame.h"
41 #ifdef HAVE_WINDOW_SYSTEM
42 #include "fontset.h"
43 #endif
44 #include "blockinput.h"
45 #include "systty.h" /* For emacs_tty in termchar.h */
46 #include "termchar.h"
47 #include "termhooks.h"
48 #include "dispextern.h"
49 #include "window.h"
50 #ifdef MSDOS
51 #include "msdos.h"
52 #include "dosfns.h"
53 #endif
56 #ifdef HAVE_WINDOW_SYSTEM
58 /* The name we're using in resource queries. Most often "emacs". */
60 Lisp_Object Vx_resource_name;
62 /* The application class we're using in resource queries.
63 Normally "Emacs". */
65 Lisp_Object Vx_resource_class;
67 #endif
69 Lisp_Object Qframep, Qframe_live_p;
70 Lisp_Object Qicon, Qmodeline;
71 Lisp_Object Qonly;
72 Lisp_Object Qx, Qw32, Qmac, Qpc;
73 Lisp_Object Qvisible;
74 Lisp_Object Qdisplay_type;
75 Lisp_Object Qbackground_mode;
76 Lisp_Object Qinhibit_default_face_x_resources;
78 Lisp_Object Qx_frame_parameter;
79 Lisp_Object Qx_resource_name;
81 /* Frame parameters (set or reported). */
83 Lisp_Object Qauto_raise, Qauto_lower;
84 Lisp_Object Qborder_color, Qborder_width;
85 Lisp_Object Qcursor_color, Qcursor_type;
86 Lisp_Object Qgeometry; /* Not used */
87 Lisp_Object Qheight, Qwidth;
88 Lisp_Object Qleft, Qright;
89 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
90 Lisp_Object Qinternal_border_width;
91 Lisp_Object Qmouse_color;
92 Lisp_Object Qminibuffer;
93 Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
94 Lisp_Object Qvisibility;
95 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
96 Lisp_Object Qscreen_gamma;
97 Lisp_Object Qline_spacing;
98 Lisp_Object Quser_position, Quser_size;
99 Lisp_Object Qwait_for_wm;
100 Lisp_Object Qwindow_id;
101 #ifdef HAVE_X_WINDOWS
102 Lisp_Object Qouter_window_id;
103 #endif
104 Lisp_Object Qparent_id;
105 Lisp_Object Qtitle, Qname;
106 Lisp_Object Qunsplittable;
107 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
108 Lisp_Object Qleft_fringe, Qright_fringe;
109 Lisp_Object Qbuffer_predicate, Qbuffer_list;
110 Lisp_Object Qtty_color_mode;
111 Lisp_Object Qtty, Qtty_type;
113 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
115 Lisp_Object Qface_set_after_frame_default;
117 Lisp_Object Vdefault_frame_alist;
118 Lisp_Object Vdefault_frame_scroll_bars;
119 Lisp_Object Vmouse_position_function;
120 Lisp_Object Vmouse_highlight;
121 Lisp_Object Vdelete_frame_functions;
123 static void
124 set_menu_bar_lines_1 (window, n)
125 Lisp_Object window;
126 int n;
128 struct window *w = XWINDOW (window);
130 XSETFASTINT (w->last_modified, 0);
131 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
132 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
134 if (INTEGERP (w->orig_top_line))
135 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
136 if (INTEGERP (w->orig_total_lines))
137 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
139 /* Handle just the top child in a vertical split. */
140 if (!NILP (w->vchild))
141 set_menu_bar_lines_1 (w->vchild, n);
143 /* Adjust all children in a horizontal split. */
144 for (window = w->hchild; !NILP (window); window = w->next)
146 w = XWINDOW (window);
147 set_menu_bar_lines_1 (window, n);
151 void
152 set_menu_bar_lines (f, value, oldval)
153 struct frame *f;
154 Lisp_Object value, oldval;
156 int nlines;
157 int olines = FRAME_MENU_BAR_LINES (f);
159 /* Right now, menu bars don't work properly in minibuf-only frames;
160 most of the commands try to apply themselves to the minibuffer
161 frame itself, and get an error because you can't switch buffers
162 in or split the minibuffer window. */
163 if (FRAME_MINIBUF_ONLY_P (f))
164 return;
166 if (INTEGERP (value))
167 nlines = XINT (value);
168 else
169 nlines = 0;
171 if (nlines != olines)
173 windows_or_buffers_changed++;
174 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
175 FRAME_MENU_BAR_LINES (f) = nlines;
176 set_menu_bar_lines_1 (f->root_window, nlines - olines);
177 adjust_glyphs (f);
181 Lisp_Object Vemacs_iconified;
182 Lisp_Object Vframe_list;
184 extern Lisp_Object Vminibuffer_list;
185 extern Lisp_Object get_minibuffer ();
186 extern Lisp_Object Fhandle_switch_frame ();
187 extern Lisp_Object Fredirect_frame_focus ();
188 extern Lisp_Object x_get_focus_frame ();
190 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
191 doc: /* Return non-nil if OBJECT is a frame.
192 Value is t for a termcap frame (a character-only terminal),
193 `x' for an Emacs frame that is really an X window,
194 `w32' for an Emacs frame that is a window on MS-Windows display,
195 `mac' for an Emacs frame on a Macintosh display,
196 `pc' for a direct-write MS-DOS frame.
197 See also `frame-live-p'. */)
198 (object)
199 Lisp_Object object;
201 if (!FRAMEP (object))
202 return Qnil;
203 switch (XFRAME (object)->output_method)
205 case output_termcap:
206 return Qt;
207 case output_x_window:
208 return Qx;
209 case output_w32:
210 return Qw32;
211 case output_msdos_raw:
212 return Qpc;
213 case output_mac:
214 return Qmac;
215 default:
216 abort ();
220 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
221 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
222 Value is nil if OBJECT is not a live frame. If object is a live
223 frame, the return value indicates what sort of output device it is
224 displayed on. See the documentation of `framep' for possible
225 return values. */)
226 (object)
227 Lisp_Object object;
229 return ((FRAMEP (object)
230 && FRAME_LIVE_P (XFRAME (object)))
231 ? Fframep (object)
232 : Qnil);
235 struct frame *
236 make_frame (mini_p)
237 int mini_p;
239 Lisp_Object frame;
240 register struct frame *f;
241 register Lisp_Object root_window;
242 register Lisp_Object mini_window;
244 f = allocate_frame ();
245 XSETFRAME (frame, f);
247 f->desired_matrix = 0;
248 f->current_matrix = 0;
249 f->desired_pool = 0;
250 f->current_pool = 0;
251 f->glyphs_initialized_p = 0;
252 f->decode_mode_spec_buffer = 0;
253 f->visible = 0;
254 f->async_visible = 0;
255 f->output_data.nothing = 0;
256 f->iconified = 0;
257 f->async_iconified = 0;
258 f->wants_modeline = 1;
259 f->auto_raise = 0;
260 f->auto_lower = 0;
261 f->no_split = 0;
262 f->garbaged = 1;
263 f->has_minibuffer = mini_p;
264 f->focus_frame = Qnil;
265 f->explicit_name = 0;
266 f->can_have_scroll_bars = 0;
267 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
268 f->param_alist = Qnil;
269 f->scroll_bars = Qnil;
270 f->condemned_scroll_bars = Qnil;
271 f->face_alist = Qnil;
272 f->face_cache = NULL;
273 f->menu_bar_items = Qnil;
274 f->menu_bar_vector = Qnil;
275 f->menu_bar_items_used = 0;
276 f->buffer_predicate = Qnil;
277 f->buffer_list = Qnil;
278 #ifdef MULTI_KBOARD
279 f->kboard = initial_kboard;
280 #endif
281 f->namebuf = 0;
282 f->title = Qnil;
283 f->menu_bar_window = Qnil;
284 f->tool_bar_window = Qnil;
285 f->tool_bar_items = Qnil;
286 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
287 f->n_tool_bar_items = 0;
288 f->left_fringe_width = f->right_fringe_width = 0;
289 f->fringe_cols = 0;
290 f->scroll_bar_actual_width = 0;
291 f->border_width = 0;
292 f->internal_border_width = 0;
293 f->column_width = 1; /* !FRAME_WINDOW_P value */
294 f->line_height = 1; /* !FRAME_WINDOW_P value */
295 f->x_pixels_diff = f->y_pixels_diff = 0;
296 #ifdef HAVE_WINDOW_SYSTEM
297 f->want_fullscreen = FULLSCREEN_NONE;
298 #endif
299 f->size_hint_flags = 0;
300 f->win_gravity = 0;
302 root_window = make_window ();
303 if (mini_p)
305 mini_window = make_window ();
306 XWINDOW (root_window)->next = mini_window;
307 XWINDOW (mini_window)->prev = root_window;
308 XWINDOW (mini_window)->mini_p = Qt;
309 XWINDOW (mini_window)->frame = frame;
310 f->minibuffer_window = mini_window;
312 else
314 mini_window = Qnil;
315 XWINDOW (root_window)->next = Qnil;
316 f->minibuffer_window = Qnil;
319 XWINDOW (root_window)->frame = frame;
321 /* 10 is arbitrary,
322 just so that there is "something there."
323 Correct size will be set up later with change_frame_size. */
325 SET_FRAME_COLS (f, 10);
326 FRAME_LINES (f) = 10;
328 XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
329 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10));
331 if (mini_p)
333 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
334 XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
335 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1);
338 /* Choose a buffer for the frame's root window. */
340 Lisp_Object buf;
342 XWINDOW (root_window)->buffer = Qt;
343 buf = Fcurrent_buffer ();
344 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
345 a space), try to find another one. */
346 if (SREF (Fbuffer_name (buf), 0) == ' ')
347 buf = Fother_buffer (buf, Qnil, Qnil);
349 /* Use set_window_buffer, not Fset_window_buffer, and don't let
350 hooks be run by it. The reason is that the whole frame/window
351 arrangement is not yet fully intialized at this point. Windows
352 don't have the right size, glyph matrices aren't initialized
353 etc. Running Lisp functions at this point surely ends in a
354 SEGV. */
355 set_window_buffer (root_window, buf, 0, 0);
356 f->buffer_list = Fcons (buf, Qnil);
359 if (mini_p)
361 XWINDOW (mini_window)->buffer = Qt;
362 set_window_buffer (mini_window,
363 (NILP (Vminibuffer_list)
364 ? get_minibuffer (0)
365 : Fcar (Vminibuffer_list)),
366 0, 0);
369 f->root_window = root_window;
370 f->selected_window = root_window;
371 /* Make sure this window seems more recently used than
372 a newly-created, never-selected window. */
373 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
375 f->default_face_done_p = 0;
377 return f;
380 #ifdef HAVE_WINDOW_SYSTEM
381 /* Make a frame using a separate minibuffer window on another frame.
382 MINI_WINDOW is the minibuffer window to use. nil means use the
383 default (the global minibuffer). */
385 struct frame *
386 make_frame_without_minibuffer (mini_window, kb, display)
387 register Lisp_Object mini_window;
388 KBOARD *kb;
389 Lisp_Object display;
391 register struct frame *f;
392 struct gcpro gcpro1;
394 if (!NILP (mini_window))
395 CHECK_LIVE_WINDOW (mini_window);
397 #ifdef MULTI_KBOARD
398 if (!NILP (mini_window)
399 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
400 error ("frame and minibuffer must be on the same display");
401 #endif
403 /* Make a frame containing just a root window. */
404 f = make_frame (0);
406 if (NILP (mini_window))
408 /* Use default-minibuffer-frame if possible. */
409 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
410 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
412 Lisp_Object frame_dummy;
414 XSETFRAME (frame_dummy, f);
415 GCPRO1 (frame_dummy);
416 /* If there's no minibuffer frame to use, create one. */
417 kb->Vdefault_minibuffer_frame =
418 call1 (intern ("make-initial-minibuffer-frame"), display);
419 UNGCPRO;
422 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
425 f->minibuffer_window = mini_window;
427 /* Make the chosen minibuffer window display the proper minibuffer,
428 unless it is already showing a minibuffer. */
429 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
430 Fset_window_buffer (mini_window,
431 (NILP (Vminibuffer_list)
432 ? get_minibuffer (0)
433 : Fcar (Vminibuffer_list)), Qnil);
434 return f;
437 /* Make a frame containing only a minibuffer window. */
439 struct frame *
440 make_minibuffer_frame ()
442 /* First make a frame containing just a root window, no minibuffer. */
444 register struct frame *f = make_frame (0);
445 register Lisp_Object mini_window;
446 register Lisp_Object frame;
448 XSETFRAME (frame, f);
450 f->auto_raise = 0;
451 f->auto_lower = 0;
452 f->no_split = 1;
453 f->wants_modeline = 0;
454 f->has_minibuffer = 1;
456 /* Now label the root window as also being the minibuffer.
457 Avoid infinite looping on the window chain by marking next pointer
458 as nil. */
460 mini_window = f->minibuffer_window = f->root_window;
461 XWINDOW (mini_window)->mini_p = Qt;
462 XWINDOW (mini_window)->next = Qnil;
463 XWINDOW (mini_window)->prev = Qnil;
464 XWINDOW (mini_window)->frame = frame;
466 /* Put the proper buffer in that window. */
468 Fset_window_buffer (mini_window,
469 (NILP (Vminibuffer_list)
470 ? get_minibuffer (0)
471 : Fcar (Vminibuffer_list)), Qnil);
472 return f;
474 #endif /* HAVE_WINDOW_SYSTEM */
476 /* Construct a frame that refers to a terminal. */
478 static int terminal_frame_count;
480 struct frame *
481 make_terminal_frame (tty_name, tty_type)
482 char *tty_name;
483 char *tty_type;
485 register struct frame *f;
486 Lisp_Object frame;
487 char name[20];
488 struct tty_output *tty;
490 /* init_term may throw an error, so create the tty first. */
491 if (initialized)
492 tty = term_init (tty_name, tty_type);
493 else
494 tty = term_dummy_init ();
496 #ifdef MULTI_KBOARD
497 if (!initial_kboard)
499 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
500 init_kboard (initial_kboard);
501 initial_kboard->next_kboard = all_kboards;
502 all_kboards = initial_kboard;
504 #endif
506 /* The first call must initialize Vframe_list. */
507 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
508 Vframe_list = Qnil;
510 f = make_frame (1);
512 XSETFRAME (frame, f);
513 Vframe_list = Fcons (frame, Vframe_list);
515 terminal_frame_count++;
516 sprintf (name, "F%d", terminal_frame_count);
517 f->name = build_string (name);
519 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
520 f->async_visible = 1; /* Don't let visible be cleared later. */
521 #ifdef MSDOS
522 f->output_data.x = &the_only_x_display;
523 if (!inhibit_window_system
524 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
525 || XFRAME (selected_frame)->output_method == output_msdos_raw))
527 f->output_method = output_msdos_raw;
528 /* This initialization of foreground and background pixels is
529 only important for the initial frame created in temacs. If
530 we don't do that, we get black background and foreground in
531 the dumped Emacs because the_only_x_display is a static
532 variable, hence it is born all-zeroes, and zero is the code
533 for the black color. Other frames all inherit their pixels
534 from what's already in the_only_x_display. */
535 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
536 && f->output_data.x->background_pixel == 0
537 && f->output_data.x->foreground_pixel == 0)
539 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
540 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
543 else
544 f->output_method = output_termcap;
545 #else
546 #ifdef WINDOWSNT
547 f->output_method = output_termcap;
548 f->output_data.x = &tty_display; /* XXX */
549 #else
550 #ifdef MAC_OS8
551 make_mac_terminal_frame (f);
552 #else
553 f->output_method = output_termcap;
554 f->output_data.tty = tty;
555 f->output_data.tty->top_frame = frame;
556 #ifdef CANNOT_DUMP
557 FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
558 FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
559 #endif
560 #endif /* MAC_OS8 */
561 #endif /* WINDOWSNT */
562 #endif /* MSDOS */
564 if (!noninteractive)
565 init_frame_faces (f);
567 return f;
570 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
571 1, 1, 0,
572 doc: /* Create an additional terminal frame, possibly on another terminal.
573 This function takes one argument, an alist specifying frame parameters.
575 You can create multiple frames on a single text-only terminal, but
576 only one of them (the selected terminal frame) is actually displayed.
578 In practice, generally you don't need to specify any parameters,
579 except when you want to create a new frame on another terminal.
580 In that case, the `tty' parameter specifies the device file to open,
581 and the `tty-type' parameter specifies the terminal type. Example:
583 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
585 Note that changing the size of one terminal frame automatically affects all. */)
586 (parms)
587 Lisp_Object parms;
589 struct frame *f;
590 Lisp_Object frame, tem;
591 struct frame *sf = SELECTED_FRAME ();
593 #ifdef MSDOS
594 if (sf->output_method != output_msdos_raw
595 && sf->output_method != output_termcap)
596 abort ();
597 #else /* not MSDOS */
599 #ifdef MAC_OS
600 if (sf->output_method != output_mac)
601 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
602 #else
603 if (sf->output_method != output_termcap)
604 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
605 #endif
606 #endif /* not MSDOS */
609 Lisp_Object tty, tty_type;
610 char *name = 0, *type = 0;
612 /* XXX Ugh, there must be a better way to do this. */
613 tty = Fassq (Qtty, parms);
614 if (EQ (tty, Qnil))
615 tty = Fassq (Qtty, XFRAME (selected_frame)->param_alist);
616 if (EQ (tty, Qnil))
617 tty = Fassq (Qtty, Vdefault_frame_alist);
618 if (! EQ (tty, Qnil))
619 tty = XCDR (tty);
620 if (EQ (tty, Qnil) || !STRINGP (tty))
621 tty = Qnil;
623 tty_type = Fassq (Qtty_type, parms);
624 if (EQ (tty_type, Qnil))
625 tty_type = Fassq (Qtty_type, Vdefault_frame_alist);
626 if (EQ (tty_type, Qnil))
627 tty_type = Fassq (Qtty, XFRAME (selected_frame)->param_alist);
628 if (! EQ (tty_type, Qnil))
629 tty_type = XCDR (tty_type);
630 if (EQ (tty_type, Qnil) || !STRINGP (tty_type))
631 tty_type = Qnil;
633 if (! EQ (tty, Qnil))
635 name = (char *) alloca (SBYTES (tty) + 1);
636 strncpy (name, SDATA (tty), SBYTES (tty));
637 name[SBYTES (tty)] = 0;
640 if (! EQ (tty_type, Qnil))
642 type = (char *) alloca (SBYTES (tty_type) + 1);
643 strncpy (type, SDATA (tty_type), SBYTES (tty_type));
644 type[SBYTES (tty_type)] = 0;
647 f = make_terminal_frame (name, type);
651 int width, height;
652 get_tty_size (FRAME_TTY (f), &width, &height);
653 change_frame_size (f, height, width, 0, 0, 0);
656 adjust_glyphs (f);
657 calculate_costs (f);
658 XSETFRAME (frame, f);
659 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
660 Fmodify_frame_parameters (frame, parms);
662 /* Make the frame face alist be frame-specific, so that each
663 frame could change its face definitions independently. */
664 f->face_alist = Fcopy_alist (sf->face_alist);
665 /* Simple Fcopy_alist isn't enough, because we need the contents of
666 the vectors which are the CDRs of associations in face_alist to
667 be copied as well. */
668 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
669 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
670 return frame;
674 /* Perform the switch to frame FRAME.
676 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
677 FRAME1 as frame.
679 If TRACK is non-zero and the frame that currently has the focus
680 redirects its focus to the selected frame, redirect that focused
681 frame's focus to FRAME instead.
683 FOR_DELETION non-zero means that the selected frame is being
684 deleted, which includes the possibility that the frame's display
685 is dead. */
687 Lisp_Object
688 do_switch_frame (frame, track, for_deletion)
689 Lisp_Object frame;
690 int track, for_deletion;
692 struct frame *sf = SELECTED_FRAME ();
694 /* If FRAME is a switch-frame event, extract the frame we should
695 switch to. */
696 if (CONSP (frame)
697 && EQ (XCAR (frame), Qswitch_frame)
698 && CONSP (XCDR (frame)))
699 frame = XCAR (XCDR (frame));
701 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
702 a switch-frame event to arrive after a frame is no longer live,
703 especially when deleting the initial frame during startup. */
704 CHECK_FRAME (frame);
705 if (! FRAME_LIVE_P (XFRAME (frame)))
706 return Qnil;
708 if (sf == XFRAME (frame))
709 return frame;
711 /* This is too greedy; it causes inappropriate focus redirection
712 that's hard to get rid of. */
713 #if 0
714 /* If a frame's focus has been redirected toward the currently
715 selected frame, we should change the redirection to point to the
716 newly selected frame. This means that if the focus is redirected
717 from a minibufferless frame to a surrogate minibuffer frame, we
718 can use `other-window' to switch between all the frames using
719 that minibuffer frame, and the focus redirection will follow us
720 around. */
721 if (track)
723 Lisp_Object tail;
725 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
727 Lisp_Object focus;
729 if (!FRAMEP (XCAR (tail)))
730 abort ();
732 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
734 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
735 Fredirect_frame_focus (XCAR (tail), frame);
738 #else /* ! 0 */
739 /* Instead, apply it only to the frame we're pointing to. */
740 #ifdef HAVE_WINDOW_SYSTEM
741 if (track && FRAME_WINDOW_P (XFRAME (frame)))
743 Lisp_Object focus, xfocus;
745 xfocus = x_get_focus_frame (XFRAME (frame));
746 if (FRAMEP (xfocus))
748 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
749 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
750 Fredirect_frame_focus (xfocus, frame);
753 #endif /* HAVE_X_WINDOWS */
754 #endif /* ! 0 */
756 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
757 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
759 if (FRAME_TERMCAP_P (XFRAME (selected_frame))
760 && FRAME_TERMCAP_P (XFRAME (frame))
761 && FRAME_TTY (XFRAME (selected_frame)) == FRAME_TTY (XFRAME (frame)))
763 XFRAME (selected_frame)->async_visible = 2; /* obscured */
764 XFRAME (frame)->async_visible = 1;
765 FRAME_TTY (XFRAME (frame))->top_frame = frame;
768 selected_frame = frame;
769 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
770 last_nonminibuf_frame = XFRAME (selected_frame);
772 Fselect_window (XFRAME (frame)->selected_window, Qnil);
774 #ifndef WINDOWSNT
775 /* Make sure to switch the tty color mode to that of the newly
776 selected frame. */
777 sf = SELECTED_FRAME ();
778 if (FRAME_TERMCAP_P (sf))
780 Lisp_Object color_mode_spec, color_mode;
782 color_mode_spec = assq_no_quit (Qtty_color_mode, sf->param_alist);
783 if (CONSP (color_mode_spec))
784 color_mode = XCDR (color_mode_spec);
785 else
786 color_mode = make_number (0);
787 set_tty_color_mode (sf, color_mode);
789 #endif /* !WINDOWSNT */
791 /* We want to make sure that the next event generates a frame-switch
792 event to the appropriate frame. This seems kludgy to me, but
793 before you take it out, make sure that evaluating something like
794 (select-window (frame-root-window (new-frame))) doesn't end up
795 with your typing being interpreted in the new frame instead of
796 the one you're actually typing in. */
797 internal_last_event_frame = Qnil;
799 return frame;
802 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
803 doc: /* Select the frame FRAME.
804 Subsequent editing commands apply to its selected window.
805 The selection of FRAME lasts until the next time the user does
806 something to select a different frame, or until the next time this
807 function is called. */)
808 (frame, no_enter)
809 Lisp_Object frame, no_enter;
811 return do_switch_frame (frame, 1, 0);
815 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
816 doc: /* Handle a switch-frame event EVENT.
817 Switch-frame events are usually bound to this function.
818 A switch-frame event tells Emacs that the window manager has requested
819 that the user's events be directed to the frame mentioned in the event.
820 This function selects the selected window of the frame of EVENT.
822 If EVENT is frame object, handle it as if it were a switch-frame event
823 to that frame. */)
824 (event, no_enter)
825 Lisp_Object event, no_enter;
827 /* Preserve prefix arg that the command loop just cleared. */
828 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
829 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
830 return do_switch_frame (event, 0, 0);
833 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
834 doc: /* Do nothing, but preserve any prefix argument already specified.
835 This is a suitable binding for `iconify-frame' and `make-frame-visible'. */)
838 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
839 return Qnil;
842 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
843 doc: /* Return the frame that is now selected. */)
846 return selected_frame;
849 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
850 doc: /* Return the frame object that window WINDOW is on. */)
851 (window)
852 Lisp_Object window;
854 CHECK_LIVE_WINDOW (window);
855 return XWINDOW (window)->frame;
858 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
859 doc: /* Returns the topmost, leftmost window of FRAME.
860 If omitted, FRAME defaults to the currently selected frame. */)
861 (frame)
862 Lisp_Object frame;
864 Lisp_Object w;
866 if (NILP (frame))
867 w = SELECTED_FRAME ()->root_window;
868 else
870 CHECK_LIVE_FRAME (frame);
871 w = XFRAME (frame)->root_window;
873 while (NILP (XWINDOW (w)->buffer))
875 if (! NILP (XWINDOW (w)->hchild))
876 w = XWINDOW (w)->hchild;
877 else if (! NILP (XWINDOW (w)->vchild))
878 w = XWINDOW (w)->vchild;
879 else
880 abort ();
882 return w;
885 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
886 Sactive_minibuffer_window, 0, 0, 0,
887 doc: /* Return the currently active minibuffer window, or nil if none. */)
890 return minibuf_level ? minibuf_window : Qnil;
893 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
894 doc: /* Returns the root-window of FRAME.
895 If omitted, FRAME defaults to the currently selected frame. */)
896 (frame)
897 Lisp_Object frame;
899 Lisp_Object window;
901 if (NILP (frame))
902 window = SELECTED_FRAME ()->root_window;
903 else
905 CHECK_LIVE_FRAME (frame);
906 window = XFRAME (frame)->root_window;
909 return window;
912 DEFUN ("frame-selected-window", Fframe_selected_window,
913 Sframe_selected_window, 0, 1, 0,
914 doc: /* Return the selected window of frame object FRAME.
915 If omitted, FRAME defaults to the currently selected frame. */)
916 (frame)
917 Lisp_Object frame;
919 Lisp_Object window;
921 if (NILP (frame))
922 window = SELECTED_FRAME ()->selected_window;
923 else
925 CHECK_LIVE_FRAME (frame);
926 window = XFRAME (frame)->selected_window;
929 return window;
932 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
933 Sset_frame_selected_window, 2, 2, 0,
934 doc: /* Set the selected window of frame object FRAME to WINDOW.
935 If FRAME is nil, the selected frame is used.
936 If FRAME is the selected frame, this makes WINDOW the selected window. */)
937 (frame, window)
938 Lisp_Object frame, window;
940 if (NILP (frame))
941 frame = selected_frame;
943 CHECK_LIVE_FRAME (frame);
944 CHECK_LIVE_WINDOW (window);
946 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
947 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
949 if (EQ (frame, selected_frame))
950 return Fselect_window (window, Qnil);
952 return XFRAME (frame)->selected_window = window;
955 DEFUN ("frame-list", Fframe_list, Sframe_list,
956 0, 0, 0,
957 doc: /* Return a list of all frames. */)
960 Lisp_Object frames;
961 frames = Fcopy_sequence (Vframe_list);
962 #ifdef HAVE_WINDOW_SYSTEM
963 if (FRAMEP (tip_frame))
964 frames = Fdelq (tip_frame, frames);
965 #endif
966 return frames;
969 /* Return the next frame in the frame list after FRAME.
970 If MINIBUF is nil, exclude minibuffer-only frames.
971 If MINIBUF is a window, include only its own frame
972 and any frame now using that window as the minibuffer.
973 If MINIBUF is `visible', include all visible frames.
974 If MINIBUF is 0, include all visible and iconified frames.
975 Otherwise, include all frames. */
977 Lisp_Object
978 next_frame (frame, minibuf)
979 Lisp_Object frame;
980 Lisp_Object minibuf;
982 Lisp_Object tail;
983 int passed = 0;
985 /* There must always be at least one frame in Vframe_list. */
986 if (! CONSP (Vframe_list))
987 abort ();
989 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
990 forever. Forestall that. */
991 CHECK_LIVE_FRAME (frame);
993 while (1)
994 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
996 Lisp_Object f;
998 f = XCAR (tail);
1000 if (passed
1001 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1002 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1003 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1004 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
1006 /* Decide whether this frame is eligible to be returned. */
1008 /* If we've looped all the way around without finding any
1009 eligible frames, return the original frame. */
1010 if (EQ (f, frame))
1011 return f;
1013 /* Let minibuf decide if this frame is acceptable. */
1014 if (NILP (minibuf))
1016 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1017 return f;
1019 else if (EQ (minibuf, Qvisible))
1021 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1022 if (FRAME_VISIBLE_P (XFRAME (f)))
1023 return f;
1025 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
1027 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1028 if (FRAME_VISIBLE_P (XFRAME (f))
1029 || FRAME_ICONIFIED_P (XFRAME (f)))
1030 return f;
1032 else if (WINDOWP (minibuf))
1034 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1035 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1036 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1037 FRAME_FOCUS_FRAME (XFRAME (f))))
1038 return f;
1040 else
1041 return f;
1044 if (EQ (frame, f))
1045 passed++;
1049 /* Return the previous frame in the frame list before FRAME.
1050 If MINIBUF is nil, exclude minibuffer-only frames.
1051 If MINIBUF is a window, include only its own frame
1052 and any frame now using that window as the minibuffer.
1053 If MINIBUF is `visible', include all visible frames.
1054 If MINIBUF is 0, include all visible and iconified frames.
1055 Otherwise, include all frames. */
1057 Lisp_Object
1058 prev_frame (frame, minibuf)
1059 Lisp_Object frame;
1060 Lisp_Object minibuf;
1062 Lisp_Object tail;
1063 Lisp_Object prev;
1065 /* There must always be at least one frame in Vframe_list. */
1066 if (! CONSP (Vframe_list))
1067 abort ();
1069 prev = Qnil;
1070 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1072 Lisp_Object f;
1074 f = XCAR (tail);
1075 if (!FRAMEP (f))
1076 abort ();
1078 if (EQ (frame, f) && !NILP (prev))
1079 return prev;
1081 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1082 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1083 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1084 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
1086 /* Decide whether this frame is eligible to be returned,
1087 according to minibuf. */
1088 if (NILP (minibuf))
1090 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1091 prev = f;
1093 else if (WINDOWP (minibuf))
1095 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1096 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1097 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1098 FRAME_FOCUS_FRAME (XFRAME (f))))
1099 prev = f;
1101 else if (EQ (minibuf, Qvisible))
1103 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1104 if (FRAME_VISIBLE_P (XFRAME (f)))
1105 prev = f;
1107 else if (XFASTINT (minibuf) == 0)
1109 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1110 if (FRAME_VISIBLE_P (XFRAME (f))
1111 || FRAME_ICONIFIED_P (XFRAME (f)))
1112 prev = f;
1114 else
1115 prev = f;
1119 /* We've scanned the entire list. */
1120 if (NILP (prev))
1121 /* We went through the whole frame list without finding a single
1122 acceptable frame. Return the original frame. */
1123 return frame;
1124 else
1125 /* There were no acceptable frames in the list before FRAME; otherwise,
1126 we would have returned directly from the loop. Since PREV is the last
1127 acceptable frame in the list, return it. */
1128 return prev;
1132 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1133 doc: /* Return the next frame in the frame list after FRAME.
1134 It considers only frames on the same terminal as FRAME.
1135 By default, skip minibuffer-only frames.
1136 If omitted, FRAME defaults to the selected frame.
1137 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1138 If MINIFRAME is a window, include only its own frame
1139 and any frame now using that window as the minibuffer.
1140 If MINIFRAME is `visible', include all visible frames.
1141 If MINIFRAME is 0, include all visible and iconified frames.
1142 Otherwise, include all frames. */)
1143 (frame, miniframe)
1144 Lisp_Object frame, miniframe;
1146 if (NILP (frame))
1147 frame = selected_frame;
1149 CHECK_LIVE_FRAME (frame);
1150 return next_frame (frame, miniframe);
1153 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1154 doc: /* Return the previous frame in the frame list before FRAME.
1155 It considers only frames on the same terminal as FRAME.
1156 By default, skip minibuffer-only frames.
1157 If omitted, FRAME defaults to the selected frame.
1158 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1159 If MINIFRAME is a window, include only its own frame
1160 and any frame now using that window as the minibuffer.
1161 If MINIFRAME is `visible', include all visible frames.
1162 If MINIFRAME is 0, include all visible and iconified frames.
1163 Otherwise, include all frames. */)
1164 (frame, miniframe)
1165 Lisp_Object frame, miniframe;
1167 if (NILP (frame))
1168 frame = selected_frame;
1169 CHECK_LIVE_FRAME (frame);
1170 return prev_frame (frame, miniframe);
1173 /* Return 1 if it is ok to delete frame F;
1174 0 if all frames aside from F are invisible.
1175 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1178 other_visible_frames (f)
1179 FRAME_PTR f;
1181 /* We know the selected frame is visible,
1182 so if F is some other frame, it can't be the sole visible one. */
1183 if (f == SELECTED_FRAME ())
1185 Lisp_Object frames;
1186 int count = 0;
1188 for (frames = Vframe_list;
1189 CONSP (frames);
1190 frames = XCDR (frames))
1192 Lisp_Object this;
1194 this = XCAR (frames);
1195 /* Verify that the frame's window still exists
1196 and we can still talk to it. And note any recent change
1197 in visibility. */
1198 #ifdef HAVE_WINDOW_SYSTEM
1199 if (FRAME_WINDOW_P (XFRAME (this)))
1201 x_sync (XFRAME (this));
1202 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1204 #endif
1206 if (FRAME_VISIBLE_P (XFRAME (this))
1207 || FRAME_ICONIFIED_P (XFRAME (this))
1208 /* Allow deleting the terminal frame when at least
1209 one X frame exists! */
1210 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1211 count++;
1213 return count > 1;
1215 return 1;
1218 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1219 doc: /* Delete FRAME, permanently eliminating it from use.
1220 If omitted, FRAME defaults to the selected frame.
1221 A frame may not be deleted if its minibuffer is used by other frames.
1222 Normally, you may not delete a frame if all other frames are invisible,
1223 but if the second optional argument FORCE is non-nil, you may do so.
1225 This function runs `delete-frame-functions' before actually deleting the
1226 frame, unless the frame is a tooltip.
1227 The functions are run with one arg, the frame to be deleted. */)
1228 (frame, force)
1229 Lisp_Object frame, force;
1231 struct frame *f;
1232 struct frame *sf = SELECTED_FRAME ();
1233 int minibuffer_selected;
1235 if (EQ (frame, Qnil))
1237 f = sf;
1238 XSETFRAME (frame, f);
1240 else
1242 CHECK_FRAME (frame);
1243 f = XFRAME (frame);
1246 if (! FRAME_LIVE_P (f))
1247 return Qnil;
1249 if (NILP (force) && !other_visible_frames (f)
1250 #ifdef MAC_OS8
1251 /* Terminal frame deleted before any other visible frames are
1252 created. */
1253 && strcmp (SDATA (f->name), "F1") != 0
1254 #endif
1256 error ("Attempt to delete the sole visible or iconified frame");
1258 #if 0
1259 /* This is a nice idea, but x_connection_closed needs to be able
1260 to delete the last frame, if it is gone. */
1261 if (NILP (XCDR (Vframe_list)))
1262 error ("Attempt to delete the only frame");
1263 #endif
1265 /* Does this frame have a minibuffer, and is it the surrogate
1266 minibuffer for any other frame? */
1267 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1269 Lisp_Object frames;
1271 for (frames = Vframe_list;
1272 CONSP (frames);
1273 frames = XCDR (frames))
1275 Lisp_Object this;
1276 this = XCAR (frames);
1278 if (! EQ (this, frame)
1279 && EQ (frame,
1280 WINDOW_FRAME (XWINDOW
1281 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1282 error ("Attempt to delete a surrogate minibuffer frame");
1286 /* Run `delete-frame-functions' unless frame is a tooltip. */
1287 if (!NILP (Vrun_hooks)
1288 && NILP (Fframe_parameter (frame, intern ("tooltip"))))
1290 Lisp_Object args[2];
1291 args[0] = intern ("delete-frame-functions");
1292 args[1] = frame;
1293 Frun_hook_with_args (2, args);
1296 minibuffer_selected = EQ (minibuf_window, selected_window);
1298 /* Don't let the frame remain selected. */
1299 if (f == sf)
1301 Lisp_Object tail, frame1;
1303 /* Look for another visible frame on the same terminal. */
1304 frame1 = next_frame (frame, Qvisible);
1306 /* If there is none, find *some* other frame. */
1307 if (NILP (frame1) || EQ (frame1, frame))
1309 FOR_EACH_FRAME (tail, frame1)
1311 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1312 break;
1316 do_switch_frame (frame1, 0, 1);
1317 sf = SELECTED_FRAME ();
1320 /* Don't allow minibuf_window to remain on a deleted frame. */
1321 if (EQ (f->minibuffer_window, minibuf_window))
1323 Fset_window_buffer (sf->minibuffer_window,
1324 XWINDOW (minibuf_window)->buffer, Qnil);
1325 minibuf_window = sf->minibuffer_window;
1327 /* If the dying minibuffer window was selected,
1328 select the new one. */
1329 if (minibuffer_selected)
1330 Fselect_window (minibuf_window, Qnil);
1333 /* Don't let echo_area_window to remain on a deleted frame. */
1334 if (EQ (f->minibuffer_window, echo_area_window))
1335 echo_area_window = sf->minibuffer_window;
1337 /* Clear any X selections for this frame. */
1338 #ifdef HAVE_X_WINDOWS
1339 if (FRAME_X_P (f))
1340 x_clear_frame_selections (f);
1341 #endif
1343 /* Free glyphs.
1344 This function must be called before the window tree of the
1345 frame is deleted because windows contain dynamically allocated
1346 memory. */
1347 free_glyphs (f);
1349 /* Mark all the windows that used to be on FRAME as deleted, and then
1350 remove the reference to them. */
1351 delete_all_subwindows (XWINDOW (f->root_window));
1352 f->root_window = Qnil;
1354 Vframe_list = Fdelq (frame, Vframe_list);
1355 FRAME_SET_VISIBLE (f, 0);
1357 if (f->namebuf)
1358 xfree (f->namebuf);
1359 if (f->decode_mode_spec_buffer)
1360 xfree (f->decode_mode_spec_buffer);
1361 if (FRAME_INSERT_COST (f))
1362 xfree (FRAME_INSERT_COST (f));
1363 if (FRAME_DELETEN_COST (f))
1364 xfree (FRAME_DELETEN_COST (f));
1365 if (FRAME_INSERTN_COST (f))
1366 xfree (FRAME_INSERTN_COST (f));
1367 if (FRAME_DELETE_COST (f))
1368 xfree (FRAME_DELETE_COST (f));
1369 if (FRAME_MESSAGE_BUF (f))
1370 xfree (FRAME_MESSAGE_BUF (f));
1372 /* Since some events are handled at the interrupt level, we may get
1373 an event for f at any time; if we zero out the frame's display
1374 now, then we may trip up the event-handling code. Instead, we'll
1375 promise that the display of the frame must be valid until we have
1376 called the window-system-dependent frame destruction routine. */
1378 /* I think this should be done with a hook. */
1379 #ifdef HAVE_WINDOW_SYSTEM
1380 if (FRAME_WINDOW_P (f))
1381 x_destroy_window (f);
1382 #endif
1384 f->output_data.nothing = 0;
1386 /* If we've deleted the last_nonminibuf_frame, then try to find
1387 another one. */
1388 if (f == last_nonminibuf_frame)
1390 Lisp_Object frames;
1392 last_nonminibuf_frame = 0;
1394 for (frames = Vframe_list;
1395 CONSP (frames);
1396 frames = XCDR (frames))
1398 f = XFRAME (XCAR (frames));
1399 if (!FRAME_MINIBUF_ONLY_P (f))
1401 last_nonminibuf_frame = f;
1402 break;
1407 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1408 find another one. Prefer minibuffer-only frames, but also notice
1409 frames with other windows. */
1410 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1412 Lisp_Object frames;
1414 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1415 Lisp_Object frame_with_minibuf;
1416 /* Some frame we found on the same kboard, or nil if there are none. */
1417 Lisp_Object frame_on_same_kboard;
1419 frame_on_same_kboard = Qnil;
1420 frame_with_minibuf = Qnil;
1422 for (frames = Vframe_list;
1423 CONSP (frames);
1424 frames = XCDR (frames))
1426 Lisp_Object this;
1427 struct frame *f1;
1429 this = XCAR (frames);
1430 if (!FRAMEP (this))
1431 abort ();
1432 f1 = XFRAME (this);
1434 /* Consider only frames on the same kboard
1435 and only those with minibuffers. */
1436 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1437 && FRAME_HAS_MINIBUF_P (f1))
1439 frame_with_minibuf = this;
1440 if (FRAME_MINIBUF_ONLY_P (f1))
1441 break;
1444 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1445 frame_on_same_kboard = this;
1448 if (!NILP (frame_on_same_kboard))
1450 /* We know that there must be some frame with a minibuffer out
1451 there. If this were not true, all of the frames present
1452 would have to be minibufferless, which implies that at some
1453 point their minibuffer frames must have been deleted, but
1454 that is prohibited at the top; you can't delete surrogate
1455 minibuffer frames. */
1456 if (NILP (frame_with_minibuf))
1457 abort ();
1459 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1461 else
1462 /* No frames left on this kboard--say no minibuffer either. */
1463 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1466 /* Cause frame titles to update--necessary if we now have just one frame. */
1467 update_mode_lines = 1;
1469 return Qnil;
1472 /* Return mouse position in character cell units. */
1474 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1475 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1476 The position is given in character cells, where (0, 0) is the
1477 upper-left corner.
1478 If Emacs is running on a mouseless terminal or hasn't been programmed
1479 to read the mouse position, it returns the selected frame for FRAME
1480 and nil for X and Y.
1481 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1482 passing the normal return value to that function as an argument,
1483 and returns whatever that function returns. */)
1486 FRAME_PTR f;
1487 Lisp_Object lispy_dummy;
1488 enum scroll_bar_part party_dummy;
1489 Lisp_Object x, y, retval;
1490 int col, row;
1491 unsigned long long_dummy;
1492 struct gcpro gcpro1;
1494 f = SELECTED_FRAME ();
1495 x = y = Qnil;
1497 #ifdef HAVE_MOUSE
1498 /* It's okay for the hook to refrain from storing anything. */
1499 if (mouse_position_hook)
1500 (*mouse_position_hook) (&f, -1,
1501 &lispy_dummy, &party_dummy,
1502 &x, &y,
1503 &long_dummy);
1504 if (! NILP (x))
1506 col = XINT (x);
1507 row = XINT (y);
1508 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1509 XSETINT (x, col);
1510 XSETINT (y, row);
1512 #endif
1513 XSETFRAME (lispy_dummy, f);
1514 retval = Fcons (lispy_dummy, Fcons (x, y));
1515 GCPRO1 (retval);
1516 if (!NILP (Vmouse_position_function))
1517 retval = call1 (Vmouse_position_function, retval);
1518 RETURN_UNGCPRO (retval);
1521 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1522 Smouse_pixel_position, 0, 0, 0,
1523 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1524 The position is given in pixel units, where (0, 0) is the
1525 upper-left corner.
1526 If Emacs is running on a mouseless terminal or hasn't been programmed
1527 to read the mouse position, it returns the selected frame for FRAME
1528 and nil for X and Y. */)
1531 FRAME_PTR f;
1532 Lisp_Object lispy_dummy;
1533 enum scroll_bar_part party_dummy;
1534 Lisp_Object x, y;
1535 unsigned long long_dummy;
1537 f = SELECTED_FRAME ();
1538 x = y = Qnil;
1540 #ifdef HAVE_MOUSE
1541 /* It's okay for the hook to refrain from storing anything. */
1542 if (mouse_position_hook)
1543 (*mouse_position_hook) (&f, -1,
1544 &lispy_dummy, &party_dummy,
1545 &x, &y,
1546 &long_dummy);
1547 #endif
1548 XSETFRAME (lispy_dummy, f);
1549 return Fcons (lispy_dummy, Fcons (x, y));
1552 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1553 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1554 Coordinates are relative to the frame, not a window,
1555 so the coordinates of the top left character in the frame
1556 may be nonzero due to left-hand scroll bars or the menu bar.
1558 This function is a no-op for an X frame that is not visible.
1559 If you have just created a frame, you must wait for it to become visible
1560 before calling this function on it, like this.
1561 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1562 (frame, x, y)
1563 Lisp_Object frame, x, y;
1565 CHECK_LIVE_FRAME (frame);
1566 CHECK_NUMBER (x);
1567 CHECK_NUMBER (y);
1569 /* I think this should be done with a hook. */
1570 #ifdef HAVE_WINDOW_SYSTEM
1571 if (FRAME_WINDOW_P (XFRAME (frame)))
1572 /* Warping the mouse will cause enternotify and focus events. */
1573 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1574 #else
1575 #if defined (MSDOS) && defined (HAVE_MOUSE)
1576 if (FRAME_MSDOS_P (XFRAME (frame)))
1578 Fselect_frame (frame, Qnil);
1579 mouse_moveto (XINT (x), XINT (y));
1581 #endif
1582 #endif
1584 return Qnil;
1587 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1588 Sset_mouse_pixel_position, 3, 3, 0,
1589 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1590 Note, this is a no-op for an X frame that is not visible.
1591 If you have just created a frame, you must wait for it to become visible
1592 before calling this function on it, like this.
1593 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1594 (frame, x, y)
1595 Lisp_Object frame, x, y;
1597 CHECK_LIVE_FRAME (frame);
1598 CHECK_NUMBER (x);
1599 CHECK_NUMBER (y);
1601 /* I think this should be done with a hook. */
1602 #ifdef HAVE_WINDOW_SYSTEM
1603 if (FRAME_WINDOW_P (XFRAME (frame)))
1604 /* Warping the mouse will cause enternotify and focus events. */
1605 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1606 #else
1607 #if defined (MSDOS) && defined (HAVE_MOUSE)
1608 if (FRAME_MSDOS_P (XFRAME (frame)))
1610 Fselect_frame (frame, Qnil);
1611 mouse_moveto (XINT (x), XINT (y));
1613 #endif
1614 #endif
1616 return Qnil;
1619 static void make_frame_visible_1 P_ ((Lisp_Object));
1621 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1622 0, 1, "",
1623 doc: /* Make the frame FRAME visible (assuming it is an X window).
1624 If omitted, FRAME defaults to the currently selected frame. */)
1625 (frame)
1626 Lisp_Object frame;
1628 if (NILP (frame))
1629 frame = selected_frame;
1631 CHECK_LIVE_FRAME (frame);
1633 /* I think this should be done with a hook. */
1634 #ifdef HAVE_WINDOW_SYSTEM
1635 if (FRAME_WINDOW_P (XFRAME (frame)))
1637 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1638 x_make_frame_visible (XFRAME (frame));
1640 #endif
1642 make_frame_visible_1 (XFRAME (frame)->root_window);
1644 /* Make menu bar update for the Buffers and Frames menus. */
1645 windows_or_buffers_changed++;
1647 return frame;
1650 /* Update the display_time slot of the buffers shown in WINDOW
1651 and all its descendents. */
1653 static void
1654 make_frame_visible_1 (window)
1655 Lisp_Object window;
1657 struct window *w;
1659 for (;!NILP (window); window = w->next)
1661 w = XWINDOW (window);
1663 if (!NILP (w->buffer))
1664 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1666 if (!NILP (w->vchild))
1667 make_frame_visible_1 (w->vchild);
1668 if (!NILP (w->hchild))
1669 make_frame_visible_1 (w->hchild);
1673 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1674 0, 2, "",
1675 doc: /* Make the frame FRAME invisible (assuming it is an X window).
1676 If omitted, FRAME defaults to the currently selected frame.
1677 Normally you may not make FRAME invisible if all other frames are invisible,
1678 but if the second optional argument FORCE is non-nil, you may do so. */)
1679 (frame, force)
1680 Lisp_Object frame, force;
1682 if (NILP (frame))
1683 frame = selected_frame;
1685 CHECK_LIVE_FRAME (frame);
1687 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1688 error ("Attempt to make invisible the sole visible or iconified frame");
1690 #if 0 /* This isn't logically necessary, and it can do GC. */
1691 /* Don't let the frame remain selected. */
1692 if (EQ (frame, selected_frame))
1693 do_switch_frame (next_frame (frame, Qt), 0, 0)
1694 #endif
1696 /* Don't allow minibuf_window to remain on a deleted frame. */
1697 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1699 struct frame *sf = XFRAME (selected_frame);
1700 Fset_window_buffer (sf->minibuffer_window,
1701 XWINDOW (minibuf_window)->buffer, Qnil);
1702 minibuf_window = sf->minibuffer_window;
1705 /* I think this should be done with a hook. */
1706 #ifdef HAVE_WINDOW_SYSTEM
1707 if (FRAME_WINDOW_P (XFRAME (frame)))
1708 x_make_frame_invisible (XFRAME (frame));
1709 #endif
1711 /* Make menu bar update for the Buffers and Frames menus. */
1712 windows_or_buffers_changed++;
1714 return Qnil;
1717 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1718 0, 1, "",
1719 doc: /* Make the frame FRAME into an icon.
1720 If omitted, FRAME defaults to the currently selected frame. */)
1721 (frame)
1722 Lisp_Object frame;
1724 if (NILP (frame))
1725 frame = selected_frame;
1727 CHECK_LIVE_FRAME (frame);
1729 #if 0 /* This isn't logically necessary, and it can do GC. */
1730 /* Don't let the frame remain selected. */
1731 if (EQ (frame, selected_frame))
1732 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1733 #endif
1735 /* Don't allow minibuf_window to remain on a deleted frame. */
1736 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1738 struct frame *sf = XFRAME (selected_frame);
1739 Fset_window_buffer (sf->minibuffer_window,
1740 XWINDOW (minibuf_window)->buffer, Qnil);
1741 minibuf_window = sf->minibuffer_window;
1744 /* I think this should be done with a hook. */
1745 #ifdef HAVE_WINDOW_SYSTEM
1746 if (FRAME_WINDOW_P (XFRAME (frame)))
1747 x_iconify_frame (XFRAME (frame));
1748 #endif
1750 /* Make menu bar update for the Buffers and Frames menus. */
1751 windows_or_buffers_changed++;
1753 return Qnil;
1756 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1757 1, 1, 0,
1758 doc: /* Return t if FRAME is now \"visible\" (actually in use for display).
1759 A frame that is not \"visible\" is not updated and, if it works through
1760 a window system, it may not show at all.
1761 Return the symbol `icon' if frame is visible only as an icon. */)
1762 (frame)
1763 Lisp_Object frame;
1765 CHECK_LIVE_FRAME (frame);
1767 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1769 if (FRAME_VISIBLE_P (XFRAME (frame)))
1770 return Qt;
1771 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1772 return Qicon;
1773 return Qnil;
1776 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1777 0, 0, 0,
1778 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1781 Lisp_Object tail, frame;
1782 struct frame *f;
1783 Lisp_Object value;
1785 value = Qnil;
1786 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1788 frame = XCAR (tail);
1789 if (!FRAMEP (frame))
1790 continue;
1791 f = XFRAME (frame);
1792 if (FRAME_VISIBLE_P (f))
1793 value = Fcons (frame, value);
1795 return value;
1799 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1800 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
1801 If FRAME is invisible, make it visible.
1802 If you don't specify a frame, the selected frame is used.
1803 If Emacs is displaying on an ordinary terminal or some other device which
1804 doesn't support multiple overlapping frames, this function does nothing. */)
1805 (frame)
1806 Lisp_Object frame;
1808 if (NILP (frame))
1809 frame = selected_frame;
1811 CHECK_LIVE_FRAME (frame);
1813 /* Do like the documentation says. */
1814 Fmake_frame_visible (frame);
1816 if (frame_raise_lower_hook)
1817 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1819 return Qnil;
1822 /* Should we have a corresponding function called Flower_Power? */
1823 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1824 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
1825 If you don't specify a frame, the selected frame is used.
1826 If Emacs is displaying on an ordinary terminal or some other device which
1827 doesn't support multiple overlapping frames, this function does nothing. */)
1828 (frame)
1829 Lisp_Object frame;
1831 if (NILP (frame))
1832 frame = selected_frame;
1834 CHECK_LIVE_FRAME (frame);
1836 if (frame_raise_lower_hook)
1837 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1839 return Qnil;
1843 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1844 1, 2, 0,
1845 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
1846 In other words, switch-frame events caused by events in FRAME will
1847 request a switch to FOCUS-FRAME, and `last-event-frame' will be
1848 FOCUS-FRAME after reading an event typed at FRAME.
1850 If FOCUS-FRAME is omitted or nil, any existing redirection is
1851 cancelled, and the frame again receives its own keystrokes.
1853 Focus redirection is useful for temporarily redirecting keystrokes to
1854 a surrogate minibuffer frame when a frame doesn't have its own
1855 minibuffer window.
1857 A frame's focus redirection can be changed by select-frame. If frame
1858 FOO is selected, and then a different frame BAR is selected, any
1859 frames redirecting their focus to FOO are shifted to redirect their
1860 focus to BAR. This allows focus redirection to work properly when the
1861 user switches from one frame to another using `select-window'.
1863 This means that a frame whose focus is redirected to itself is treated
1864 differently from a frame whose focus is redirected to nil; the former
1865 is affected by select-frame, while the latter is not.
1867 The redirection lasts until `redirect-frame-focus' is called to change it. */)
1868 (frame, focus_frame)
1869 Lisp_Object frame, focus_frame;
1871 /* Note that we don't check for a live frame here. It's reasonable
1872 to redirect the focus of a frame you're about to delete, if you
1873 know what other frame should receive those keystrokes. */
1874 CHECK_FRAME (frame);
1876 if (! NILP (focus_frame))
1877 CHECK_LIVE_FRAME (focus_frame);
1879 XFRAME (frame)->focus_frame = focus_frame;
1881 if (frame_rehighlight_hook)
1882 (*frame_rehighlight_hook) (XFRAME (frame));
1884 return Qnil;
1888 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1889 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
1890 This returns nil if FRAME's focus is not redirected.
1891 See `redirect-frame-focus'. */)
1892 (frame)
1893 Lisp_Object frame;
1895 CHECK_LIVE_FRAME (frame);
1897 return FRAME_FOCUS_FRAME (XFRAME (frame));
1902 /* Return the value of frame parameter PROP in frame FRAME. */
1904 Lisp_Object
1905 get_frame_param (frame, prop)
1906 register struct frame *frame;
1907 Lisp_Object prop;
1909 register Lisp_Object tem;
1911 tem = Fassq (prop, frame->param_alist);
1912 if (EQ (tem, Qnil))
1913 return tem;
1914 return Fcdr (tem);
1917 /* Return the buffer-predicate of the selected frame. */
1919 Lisp_Object
1920 frame_buffer_predicate (frame)
1921 Lisp_Object frame;
1923 return XFRAME (frame)->buffer_predicate;
1926 /* Return the buffer-list of the selected frame. */
1928 Lisp_Object
1929 frame_buffer_list (frame)
1930 Lisp_Object frame;
1932 return XFRAME (frame)->buffer_list;
1935 /* Set the buffer-list of the selected frame. */
1937 void
1938 set_frame_buffer_list (frame, list)
1939 Lisp_Object frame, list;
1941 XFRAME (frame)->buffer_list = list;
1944 /* Discard BUFFER from the buffer-list of each frame. */
1946 void
1947 frames_discard_buffer (buffer)
1948 Lisp_Object buffer;
1950 Lisp_Object frame, tail;
1952 FOR_EACH_FRAME (tail, frame)
1954 XFRAME (frame)->buffer_list
1955 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1959 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1960 If the alist already has an element for PROP, we change it. */
1962 void
1963 store_in_alist (alistptr, prop, val)
1964 Lisp_Object *alistptr, val;
1965 Lisp_Object prop;
1967 register Lisp_Object tem;
1969 tem = Fassq (prop, *alistptr);
1970 if (EQ (tem, Qnil))
1971 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1972 else
1973 Fsetcdr (tem, val);
1976 static int
1977 frame_name_fnn_p (str, len)
1978 char *str;
1979 int len;
1981 if (len > 1 && str[0] == 'F')
1983 char *end_ptr;
1985 strtol (str + 1, &end_ptr, 10);
1987 if (end_ptr == str + len)
1988 return 1;
1990 return 0;
1993 /* Set the name of the terminal frame. Also used by MSDOS frames.
1994 Modeled after x_set_name which is used for WINDOW frames. */
1996 void
1997 set_term_frame_name (f, name)
1998 struct frame *f;
1999 Lisp_Object name;
2001 f->explicit_name = ! NILP (name);
2003 /* If NAME is nil, set the name to F<num>. */
2004 if (NILP (name))
2006 char namebuf[20];
2008 /* Check for no change needed in this very common case
2009 before we do any consing. */
2010 if (frame_name_fnn_p (SDATA (f->name),
2011 SBYTES (f->name)))
2012 return;
2014 terminal_frame_count++;
2015 sprintf (namebuf, "F%d", terminal_frame_count);
2016 name = build_string (namebuf);
2018 else
2020 CHECK_STRING (name);
2022 /* Don't change the name if it's already NAME. */
2023 if (! NILP (Fstring_equal (name, f->name)))
2024 return;
2026 /* Don't allow the user to set the frame name to F<num>, so it
2027 doesn't clash with the names we generate for terminal frames. */
2028 if (frame_name_fnn_p (SDATA (name), SBYTES (name)))
2029 error ("Frame names of the form F<num> are usurped by Emacs");
2032 f->name = name;
2033 update_mode_lines = 1;
2036 void
2037 store_frame_param (f, prop, val)
2038 struct frame *f;
2039 Lisp_Object prop, val;
2041 register Lisp_Object old_alist_elt;
2043 /* The buffer-alist parameter is stored in a special place and is
2044 not in the alist. */
2045 if (EQ (prop, Qbuffer_list))
2047 f->buffer_list = val;
2048 return;
2051 /* If PROP is a symbol which is supposed to have frame-local values,
2052 and it is set up based on this frame, switch to the global
2053 binding. That way, we can create or alter the frame-local binding
2054 without messing up the symbol's status. */
2055 if (SYMBOLP (prop))
2057 Lisp_Object valcontents;
2058 valcontents = SYMBOL_VALUE (prop);
2059 if ((BUFFER_LOCAL_VALUEP (valcontents)
2060 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
2061 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
2062 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
2063 swap_in_global_binding (prop);
2066 #ifndef WINDOWSNT
2067 /* The tty color mode needs to be set before the frame's parameter
2068 alist is updated with the new value, because set_tty_color_mode
2069 wants to look at the old mode. */
2070 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode))
2071 set_tty_color_mode (f, val);
2072 #endif
2074 /* Update the frame parameter alist. */
2075 old_alist_elt = Fassq (prop, f->param_alist);
2076 if (EQ (old_alist_elt, Qnil))
2077 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
2078 else
2079 Fsetcdr (old_alist_elt, val);
2081 /* Update some other special parameters in their special places
2082 in addition to the alist. */
2084 if (EQ (prop, Qbuffer_predicate))
2085 f->buffer_predicate = val;
2087 if (! FRAME_WINDOW_P (f))
2089 if (EQ (prop, Qmenu_bar_lines))
2090 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2091 else if (EQ (prop, Qname))
2092 set_term_frame_name (f, val);
2095 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2097 if (! MINI_WINDOW_P (XWINDOW (val)))
2098 error ("Surrogate minibuffer windows must be minibuffer windows");
2100 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2101 && !EQ (val, f->minibuffer_window))
2102 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2104 /* Install the chosen minibuffer window, with proper buffer. */
2105 f->minibuffer_window = val;
2109 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2110 doc: /* Return the parameters-alist of frame FRAME.
2111 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2112 The meaningful PARMs depend on the kind of frame.
2113 If FRAME is omitted, return information on the currently selected frame. */)
2114 (frame)
2115 Lisp_Object frame;
2117 Lisp_Object alist;
2118 FRAME_PTR f;
2119 int height, width;
2120 struct gcpro gcpro1;
2122 if (NILP (frame))
2123 frame = selected_frame;
2125 CHECK_FRAME (frame);
2126 f = XFRAME (frame);
2128 if (!FRAME_LIVE_P (f))
2129 return Qnil;
2131 alist = Fcopy_alist (f->param_alist);
2132 GCPRO1 (alist);
2134 if (!FRAME_WINDOW_P (f))
2136 int fg = FRAME_FOREGROUND_PIXEL (f);
2137 int bg = FRAME_BACKGROUND_PIXEL (f);
2138 Lisp_Object elt;
2140 /* If the frame's parameter alist says the colors are
2141 unspecified and reversed, take the frame's background pixel
2142 for foreground and vice versa. */
2143 elt = Fassq (Qforeground_color, alist);
2144 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2146 if (strncmp (SDATA (XCDR (elt)),
2147 unspecified_bg,
2148 SCHARS (XCDR (elt))) == 0)
2149 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2150 else if (strncmp (SDATA (XCDR (elt)),
2151 unspecified_fg,
2152 SCHARS (XCDR (elt))) == 0)
2153 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2155 else
2156 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2157 elt = Fassq (Qbackground_color, alist);
2158 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2160 if (strncmp (SDATA (XCDR (elt)),
2161 unspecified_fg,
2162 SCHARS (XCDR (elt))) == 0)
2163 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2164 else if (strncmp (SDATA (XCDR (elt)),
2165 unspecified_bg,
2166 SCHARS (XCDR (elt))) == 0)
2167 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2169 else
2170 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2171 store_in_alist (&alist, intern ("font"),
2172 build_string (FRAME_MSDOS_P (f)
2173 ? "ms-dos"
2174 : FRAME_W32_P (f) ? "w32term"
2175 :"tty"));
2177 store_in_alist (&alist, Qname, f->name);
2178 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2179 store_in_alist (&alist, Qheight, make_number (height));
2180 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2181 store_in_alist (&alist, Qwidth, make_number (width));
2182 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2183 store_in_alist (&alist, Qminibuffer,
2184 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2185 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2186 : FRAME_MINIBUF_WINDOW (f)));
2187 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2188 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
2190 /* I think this should be done with a hook. */
2191 #ifdef HAVE_WINDOW_SYSTEM
2192 if (FRAME_WINDOW_P (f))
2193 x_report_frame_params (f, &alist);
2194 else
2195 #endif
2197 /* This ought to be correct in f->param_alist for an X frame. */
2198 Lisp_Object lines;
2199 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2200 store_in_alist (&alist, Qmenu_bar_lines, lines);
2203 UNGCPRO;
2204 return alist;
2208 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2209 doc: /* Return FRAME's value for parameter PARAMETER.
2210 If FRAME is nil, describe the currently selected frame. */)
2211 (frame, parameter)
2212 Lisp_Object frame, parameter;
2214 struct frame *f;
2215 Lisp_Object value;
2217 if (NILP (frame))
2218 frame = selected_frame;
2219 else
2220 CHECK_FRAME (frame);
2221 CHECK_SYMBOL (parameter);
2223 f = XFRAME (frame);
2224 value = Qnil;
2226 if (FRAME_LIVE_P (f))
2228 /* Avoid consing in frequent cases. */
2229 if (EQ (parameter, Qname))
2230 value = f->name;
2231 #ifdef HAVE_X_WINDOWS
2232 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2233 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2234 #endif /* HAVE_X_WINDOWS */
2235 else if (EQ (parameter, Qbackground_color)
2236 || EQ (parameter, Qforeground_color))
2238 value = Fassq (parameter, f->param_alist);
2239 if (CONSP (value))
2241 value = XCDR (value);
2242 /* Fframe_parameters puts the actual fg/bg color names,
2243 even if f->param_alist says otherwise. This is
2244 important when param_alist's notion of colors is
2245 "unspecified". We need to do the same here. */
2246 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2248 const char *color_name;
2249 EMACS_INT csz;
2251 if (EQ (parameter, Qbackground_color))
2253 color_name = SDATA (value);
2254 csz = SCHARS (value);
2255 if (strncmp (color_name, unspecified_bg, csz) == 0)
2256 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2257 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2258 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2260 else if (EQ (parameter, Qforeground_color))
2262 color_name = SDATA (value);
2263 csz = SCHARS (value);
2264 if (strncmp (color_name, unspecified_fg, csz) == 0)
2265 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2266 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2267 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2271 else
2272 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2274 else if (EQ (parameter, Qdisplay_type)
2275 || EQ (parameter, Qbackground_mode))
2276 value = Fcdr (Fassq (parameter, f->param_alist));
2277 else
2278 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2281 return value;
2285 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2286 Smodify_frame_parameters, 2, 2, 0,
2287 doc: /* Modify the parameters of frame FRAME according to ALIST.
2288 If FRAME is nil, it defaults to the selected frame.
2289 ALIST is an alist of parameters to change and their new values.
2290 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2291 The meaningful PARMs depend on the kind of frame.
2292 Undefined PARMs are ignored, but stored in the frame's parameter list
2293 so that `frame-parameters' will return them.
2295 The value of frame parameter FOO can also be accessed
2296 as a frame-local binding for the variable FOO, if you have
2297 enabled such bindings for that variable with `make-variable-frame-local'. */)
2298 (frame, alist)
2299 Lisp_Object frame, alist;
2301 FRAME_PTR f;
2302 register Lisp_Object tail, prop, val;
2303 int count = SPECPDL_INDEX ();
2305 /* Bind this to t to inhibit initialization of the default face from
2306 X resources in face-set-after-frame-default. If we don't inhibit
2307 this, modifying the `font' frame parameter, for example, while
2308 there is a `default.attributeFont' X resource, won't work,
2309 because `default's font is reset to the value of the X resource
2310 and that resets the `font' frame parameter. */
2311 specbind (Qinhibit_default_face_x_resources, Qt);
2313 if (EQ (frame, Qnil))
2314 frame = selected_frame;
2315 CHECK_LIVE_FRAME (frame);
2316 f = XFRAME (frame);
2318 /* I think this should be done with a hook. */
2319 #ifdef HAVE_WINDOW_SYSTEM
2320 if (FRAME_WINDOW_P (f))
2321 x_set_frame_parameters (f, alist);
2322 else
2323 #endif
2324 #ifdef MSDOS
2325 if (FRAME_MSDOS_P (f))
2326 IT_set_frame_parameters (f, alist);
2327 else
2328 #endif
2331 int length = XINT (Flength (alist));
2332 int i;
2333 Lisp_Object *parms
2334 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2335 Lisp_Object *values
2336 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2338 /* Extract parm names and values into those vectors. */
2340 i = 0;
2341 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2343 Lisp_Object elt;
2345 elt = Fcar (tail);
2346 parms[i] = Fcar (elt);
2347 values[i] = Fcdr (elt);
2348 i++;
2351 /* Now process them in reverse of specified order. */
2352 for (i--; i >= 0; i--)
2354 prop = parms[i];
2355 val = values[i];
2356 store_frame_param (f, prop, val);
2360 return unbind_to (count, Qnil);
2363 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2364 0, 1, 0,
2365 doc: /* Height in pixels of a line in the font in frame FRAME.
2366 If FRAME is omitted, the selected frame is used.
2367 For a terminal frame, the value is always 1. */)
2368 (frame)
2369 Lisp_Object frame;
2371 struct frame *f;
2373 if (NILP (frame))
2374 frame = selected_frame;
2375 CHECK_FRAME (frame);
2376 f = XFRAME (frame);
2378 #ifdef HAVE_WINDOW_SYSTEM
2379 if (FRAME_WINDOW_P (f))
2380 return make_number (x_char_height (f));
2381 else
2382 #endif
2383 return make_number (1);
2387 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2388 0, 1, 0,
2389 doc: /* Width in pixels of characters in the font in frame FRAME.
2390 If FRAME is omitted, the selected frame is used.
2391 The width is the same for all characters, because
2392 currently Emacs supports only fixed-width fonts.
2393 For a terminal screen, the value is always 1. */)
2394 (frame)
2395 Lisp_Object frame;
2397 struct frame *f;
2399 if (NILP (frame))
2400 frame = selected_frame;
2401 CHECK_FRAME (frame);
2402 f = XFRAME (frame);
2404 #ifdef HAVE_WINDOW_SYSTEM
2405 if (FRAME_WINDOW_P (f))
2406 return make_number (x_char_width (f));
2407 else
2408 #endif
2409 return make_number (1);
2412 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2413 Sframe_pixel_height, 0, 1, 0,
2414 doc: /* Return a FRAME's height in pixels.
2415 This counts only the height available for text lines,
2416 not menu bars on window-system Emacs frames.
2417 For a terminal frame, the result really gives the height in characters.
2418 If FRAME is omitted, the selected frame is used. */)
2419 (frame)
2420 Lisp_Object frame;
2422 struct frame *f;
2424 if (NILP (frame))
2425 frame = selected_frame;
2426 CHECK_FRAME (frame);
2427 f = XFRAME (frame);
2429 #ifdef HAVE_WINDOW_SYSTEM
2430 if (FRAME_WINDOW_P (f))
2431 return make_number (x_pixel_height (f));
2432 else
2433 #endif
2434 return make_number (FRAME_LINES (f));
2437 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2438 Sframe_pixel_width, 0, 1, 0,
2439 doc: /* Return FRAME's width in pixels.
2440 For a terminal frame, the result really gives the width in characters.
2441 If FRAME is omitted, the selected frame is used. */)
2442 (frame)
2443 Lisp_Object frame;
2445 struct frame *f;
2447 if (NILP (frame))
2448 frame = selected_frame;
2449 CHECK_FRAME (frame);
2450 f = XFRAME (frame);
2452 #ifdef HAVE_WINDOW_SYSTEM
2453 if (FRAME_WINDOW_P (f))
2454 return make_number (x_pixel_width (f));
2455 else
2456 #endif
2457 return make_number (FRAME_COLS (f));
2460 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2461 doc: /* Specify that the frame FRAME has LINES lines.
2462 Optional third arg non-nil means that redisplay should use LINES lines
2463 but that the idea of the actual height of the frame should not be changed. */)
2464 (frame, lines, pretend)
2465 Lisp_Object frame, lines, pretend;
2467 register struct frame *f;
2469 CHECK_NUMBER (lines);
2470 if (NILP (frame))
2471 frame = selected_frame;
2472 CHECK_LIVE_FRAME (frame);
2473 f = XFRAME (frame);
2475 /* I think this should be done with a hook. */
2476 #ifdef HAVE_WINDOW_SYSTEM
2477 if (FRAME_WINDOW_P (f))
2479 if (XINT (lines) != FRAME_LINES (f))
2480 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
2481 do_pending_window_change (0);
2483 else
2484 #endif
2485 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2486 return Qnil;
2489 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2490 doc: /* Specify that the frame FRAME has COLS columns.
2491 Optional third arg non-nil means that redisplay should use COLS columns
2492 but that the idea of the actual width of the frame should not be changed. */)
2493 (frame, cols, pretend)
2494 Lisp_Object frame, cols, pretend;
2496 register struct frame *f;
2497 CHECK_NUMBER (cols);
2498 if (NILP (frame))
2499 frame = selected_frame;
2500 CHECK_LIVE_FRAME (frame);
2501 f = XFRAME (frame);
2503 /* I think this should be done with a hook. */
2504 #ifdef HAVE_WINDOW_SYSTEM
2505 if (FRAME_WINDOW_P (f))
2507 if (XINT (cols) != FRAME_COLS (f))
2508 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
2509 do_pending_window_change (0);
2511 else
2512 #endif
2513 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2514 return Qnil;
2517 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2518 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2519 (frame, cols, rows)
2520 Lisp_Object frame, cols, rows;
2522 register struct frame *f;
2524 CHECK_LIVE_FRAME (frame);
2525 CHECK_NUMBER (cols);
2526 CHECK_NUMBER (rows);
2527 f = XFRAME (frame);
2529 /* I think this should be done with a hook. */
2530 #ifdef HAVE_WINDOW_SYSTEM
2531 if (FRAME_WINDOW_P (f))
2533 if (XINT (rows) != FRAME_LINES (f)
2534 || XINT (cols) != FRAME_COLS (f)
2535 || f->new_text_lines || f->new_text_cols)
2536 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2537 do_pending_window_change (0);
2539 else
2540 #endif
2541 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2543 return Qnil;
2546 DEFUN ("set-frame-position", Fset_frame_position,
2547 Sset_frame_position, 3, 3, 0,
2548 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2549 This is actually the position of the upper left corner of the frame.
2550 Negative values for XOFFSET or YOFFSET are interpreted relative to
2551 the rightmost or bottommost possible position (that stays within the screen). */)
2552 (frame, xoffset, yoffset)
2553 Lisp_Object frame, xoffset, yoffset;
2555 register struct frame *f;
2557 CHECK_LIVE_FRAME (frame);
2558 CHECK_NUMBER (xoffset);
2559 CHECK_NUMBER (yoffset);
2560 f = XFRAME (frame);
2562 /* I think this should be done with a hook. */
2563 #ifdef HAVE_WINDOW_SYSTEM
2564 if (FRAME_WINDOW_P (f))
2565 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2566 #endif
2568 return Qt;
2572 /***********************************************************************
2573 Frame Parameters
2574 ***********************************************************************/
2576 /* Connect the frame-parameter names for X frames
2577 to the ways of passing the parameter values to the window system.
2579 The name of a parameter, as a Lisp symbol,
2580 has an `x-frame-parameter' property which is an integer in Lisp
2581 that is an index in this table. */
2583 struct frame_parm_table {
2584 char *name;
2585 Lisp_Object *variable;
2588 static struct frame_parm_table frame_parms[] =
2590 {"auto-raise", &Qauto_raise},
2591 {"auto-lower", &Qauto_lower},
2592 {"background-color", 0},
2593 {"border-color", &Qborder_color},
2594 {"border-width", &Qborder_width},
2595 {"cursor-color", &Qcursor_color},
2596 {"cursor-type", &Qcursor_type},
2597 {"font", 0},
2598 {"foreground-color", 0},
2599 {"icon-name", &Qicon_name},
2600 {"icon-type", &Qicon_type},
2601 {"internal-border-width", &Qinternal_border_width},
2602 {"menu-bar-lines", &Qmenu_bar_lines},
2603 {"mouse-color", &Qmouse_color},
2604 {"name", &Qname},
2605 {"scroll-bar-width", &Qscroll_bar_width},
2606 {"title", &Qtitle},
2607 {"unsplittable", &Qunsplittable},
2608 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2609 {"visibility", &Qvisibility},
2610 {"tool-bar-lines", &Qtool_bar_lines},
2611 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2612 {"scroll-bar-background", &Qscroll_bar_background},
2613 {"screen-gamma", &Qscreen_gamma},
2614 {"line-spacing", &Qline_spacing},
2615 {"left-fringe", &Qleft_fringe},
2616 {"right-fringe", &Qright_fringe},
2617 {"wait-for-wm", &Qwait_for_wm},
2618 {"fullscreen", &Qfullscreen},
2621 #ifdef HAVE_WINDOW_SYSTEM
2623 extern Lisp_Object Qbox;
2624 extern Lisp_Object Qtop;
2626 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2627 wanted positions of the WM window (not emacs window).
2628 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2629 window (FRAME_X_WINDOW).
2632 void
2633 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2634 struct frame *f;
2635 int *width;
2636 int *height;
2637 int *top_pos;
2638 int *left_pos;
2640 int newwidth = FRAME_COLS (f);
2641 int newheight = FRAME_LINES (f);
2643 *top_pos = f->top_pos;
2644 *left_pos = f->left_pos;
2646 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
2648 int ph;
2650 ph = FRAME_X_DISPLAY_INFO (f)->height;
2651 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2652 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2653 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2654 *top_pos = 0;
2657 if (f->want_fullscreen & FULLSCREEN_WIDTH)
2659 int pw;
2661 pw = FRAME_X_DISPLAY_INFO (f)->width;
2662 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2663 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2664 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2665 *left_pos = 0;
2668 *width = newwidth;
2669 *height = newheight;
2673 /* Change the parameters of frame F as specified by ALIST.
2674 If a parameter is not specially recognized, do nothing special;
2675 otherwise call the `x_set_...' function for that parameter.
2676 Except for certain geometry properties, always call store_frame_param
2677 to store the new value in the parameter alist. */
2679 void
2680 x_set_frame_parameters (f, alist)
2681 FRAME_PTR f;
2682 Lisp_Object alist;
2684 Lisp_Object tail;
2686 /* If both of these parameters are present, it's more efficient to
2687 set them both at once. So we wait until we've looked at the
2688 entire list before we set them. */
2689 int width, height;
2691 /* Same here. */
2692 Lisp_Object left, top;
2694 /* Same with these. */
2695 Lisp_Object icon_left, icon_top;
2697 /* Record in these vectors all the parms specified. */
2698 Lisp_Object *parms;
2699 Lisp_Object *values;
2700 int i, p;
2701 int left_no_change = 0, top_no_change = 0;
2702 int icon_left_no_change = 0, icon_top_no_change = 0;
2703 int fullscreen_is_being_set = 0;
2705 struct gcpro gcpro1, gcpro2;
2707 i = 0;
2708 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2709 i++;
2711 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2712 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2714 /* Extract parm names and values into those vectors. */
2716 i = 0;
2717 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2719 Lisp_Object elt;
2721 elt = Fcar (tail);
2722 parms[i] = Fcar (elt);
2723 values[i] = Fcdr (elt);
2724 i++;
2726 /* TAIL and ALIST are not used again below here. */
2727 alist = tail = Qnil;
2729 GCPRO2 (*parms, *values);
2730 gcpro1.nvars = i;
2731 gcpro2.nvars = i;
2733 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2734 because their values appear in VALUES and strings are not valid. */
2735 top = left = Qunbound;
2736 icon_left = icon_top = Qunbound;
2738 /* Provide default values for HEIGHT and WIDTH. */
2739 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2740 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2742 /* Process foreground_color and background_color before anything else.
2743 They are independent of other properties, but other properties (e.g.,
2744 cursor_color) are dependent upon them. */
2745 /* Process default font as well, since fringe widths depends on it. */
2746 /* Also, process fullscreen, width and height depend upon that */
2747 for (p = 0; p < i; p++)
2749 Lisp_Object prop, val;
2751 prop = parms[p];
2752 val = values[p];
2753 if (EQ (prop, Qforeground_color)
2754 || EQ (prop, Qbackground_color)
2755 || EQ (prop, Qfont)
2756 || EQ (prop, Qfullscreen))
2758 register Lisp_Object param_index, old_value;
2760 old_value = get_frame_param (f, prop);
2761 fullscreen_is_being_set |= EQ (prop, Qfullscreen);
2763 if (NILP (Fequal (val, old_value)))
2765 store_frame_param (f, prop, val);
2767 param_index = Fget (prop, Qx_frame_parameter);
2768 if (NATNUMP (param_index)
2769 && (XFASTINT (param_index)
2770 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2771 && rif->frame_parm_handlers[XINT (param_index)])
2772 (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2777 /* Now process them in reverse of specified order. */
2778 for (i--; i >= 0; i--)
2780 Lisp_Object prop, val;
2782 prop = parms[i];
2783 val = values[i];
2785 if (EQ (prop, Qwidth) && NUMBERP (val))
2786 width = XFASTINT (val);
2787 else if (EQ (prop, Qheight) && NUMBERP (val))
2788 height = XFASTINT (val);
2789 else if (EQ (prop, Qtop))
2790 top = val;
2791 else if (EQ (prop, Qleft))
2792 left = val;
2793 else if (EQ (prop, Qicon_top))
2794 icon_top = val;
2795 else if (EQ (prop, Qicon_left))
2796 icon_left = val;
2797 else if (EQ (prop, Qforeground_color)
2798 || EQ (prop, Qbackground_color)
2799 || EQ (prop, Qfont)
2800 || EQ (prop, Qfullscreen))
2801 /* Processed above. */
2802 continue;
2803 else
2805 register Lisp_Object param_index, old_value;
2807 old_value = get_frame_param (f, prop);
2809 store_frame_param (f, prop, val);
2811 param_index = Fget (prop, Qx_frame_parameter);
2812 if (NATNUMP (param_index)
2813 && (XFASTINT (param_index)
2814 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2815 && rif->frame_parm_handlers[XINT (param_index)])
2816 (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2820 /* Don't die if just one of these was set. */
2821 if (EQ (left, Qunbound))
2823 left_no_change = 1;
2824 if (f->left_pos < 0)
2825 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
2826 else
2827 XSETINT (left, f->left_pos);
2829 if (EQ (top, Qunbound))
2831 top_no_change = 1;
2832 if (f->top_pos < 0)
2833 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
2834 else
2835 XSETINT (top, f->top_pos);
2838 /* If one of the icon positions was not set, preserve or default it. */
2839 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
2841 icon_left_no_change = 1;
2842 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
2843 if (NILP (icon_left))
2844 XSETINT (icon_left, 0);
2846 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
2848 icon_top_no_change = 1;
2849 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
2850 if (NILP (icon_top))
2851 XSETINT (icon_top, 0);
2854 #ifndef HAVE_CARBON
2855 /* MAC_TODO: fullscreen */
2856 if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
2858 /* If the frame is visible already and the fullscreen parameter is
2859 being set, it is too late to set WM manager hints to specify
2860 size and position.
2861 Here we first get the width, height and position that applies to
2862 fullscreen. We then move the frame to the appropriate
2863 position. Resize of the frame is taken care of in the code after
2864 this if-statement. */
2865 int new_left, new_top;
2867 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
2868 if (new_top != f->top_pos || new_left != f->left_pos)
2869 x_set_offset (f, new_left, new_top, 1);
2871 #endif
2873 /* Don't set these parameters unless they've been explicitly
2874 specified. The window might be mapped or resized while we're in
2875 this function, and we don't want to override that unless the lisp
2876 code has asked for it.
2878 Don't set these parameters unless they actually differ from the
2879 window's current parameters; the window may not actually exist
2880 yet. */
2882 Lisp_Object frame;
2884 check_frame_size (f, &height, &width);
2886 XSETFRAME (frame, f);
2888 if (width != FRAME_COLS (f)
2889 || height != FRAME_LINES (f)
2890 || f->new_text_lines || f->new_text_cols)
2891 Fset_frame_size (frame, make_number (width), make_number (height));
2893 if ((!NILP (left) || !NILP (top))
2894 && ! (left_no_change && top_no_change)
2895 && ! (NUMBERP (left) && XINT (left) == f->left_pos
2896 && NUMBERP (top) && XINT (top) == f->top_pos))
2898 int leftpos = 0;
2899 int toppos = 0;
2901 /* Record the signs. */
2902 f->size_hint_flags &= ~ (XNegative | YNegative);
2903 if (EQ (left, Qminus))
2904 f->size_hint_flags |= XNegative;
2905 else if (INTEGERP (left))
2907 leftpos = XINT (left);
2908 if (leftpos < 0)
2909 f->size_hint_flags |= XNegative;
2911 else if (CONSP (left) && EQ (XCAR (left), Qminus)
2912 && CONSP (XCDR (left))
2913 && INTEGERP (XCAR (XCDR (left))))
2915 leftpos = - XINT (XCAR (XCDR (left)));
2916 f->size_hint_flags |= XNegative;
2918 else if (CONSP (left) && EQ (XCAR (left), Qplus)
2919 && CONSP (XCDR (left))
2920 && INTEGERP (XCAR (XCDR (left))))
2922 leftpos = XINT (XCAR (XCDR (left)));
2925 if (EQ (top, Qminus))
2926 f->size_hint_flags |= YNegative;
2927 else if (INTEGERP (top))
2929 toppos = XINT (top);
2930 if (toppos < 0)
2931 f->size_hint_flags |= YNegative;
2933 else if (CONSP (top) && EQ (XCAR (top), Qminus)
2934 && CONSP (XCDR (top))
2935 && INTEGERP (XCAR (XCDR (top))))
2937 toppos = - XINT (XCAR (XCDR (top)));
2938 f->size_hint_flags |= YNegative;
2940 else if (CONSP (top) && EQ (XCAR (top), Qplus)
2941 && CONSP (XCDR (top))
2942 && INTEGERP (XCAR (XCDR (top))))
2944 toppos = XINT (XCAR (XCDR (top)));
2948 /* Store the numeric value of the position. */
2949 f->top_pos = toppos;
2950 f->left_pos = leftpos;
2952 f->win_gravity = NorthWestGravity;
2954 /* Actually set that position, and convert to absolute. */
2955 x_set_offset (f, leftpos, toppos, -1);
2958 if ((!NILP (icon_left) || !NILP (icon_top))
2959 && ! (icon_left_no_change && icon_top_no_change))
2960 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
2963 UNGCPRO;
2967 /* Insert a description of internally-recorded parameters of frame X
2968 into the parameter alist *ALISTPTR that is to be given to the user.
2969 Only parameters that are specific to the X window system
2970 and whose values are not correctly recorded in the frame's
2971 param_alist need to be considered here. */
2973 void
2974 x_report_frame_params (f, alistptr)
2975 struct frame *f;
2976 Lisp_Object *alistptr;
2978 char buf[16];
2979 Lisp_Object tem;
2981 /* Represent negative positions (off the top or left screen edge)
2982 in a way that Fmodify_frame_parameters will understand correctly. */
2983 XSETINT (tem, f->left_pos);
2984 if (f->left_pos >= 0)
2985 store_in_alist (alistptr, Qleft, tem);
2986 else
2987 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
2989 XSETINT (tem, f->top_pos);
2990 if (f->top_pos >= 0)
2991 store_in_alist (alistptr, Qtop, tem);
2992 else
2993 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
2995 store_in_alist (alistptr, Qborder_width,
2996 make_number (f->border_width));
2997 store_in_alist (alistptr, Qinternal_border_width,
2998 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
2999 store_in_alist (alistptr, Qleft_fringe,
3000 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
3001 store_in_alist (alistptr, Qright_fringe,
3002 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
3003 store_in_alist (alistptr, Qscroll_bar_width,
3004 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3005 ? make_number (0)
3006 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3007 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3008 /* nil means "use default width"
3009 for non-toolkit scroll bar.
3010 ruler-mode.el depends on this. */
3011 : Qnil));
3012 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
3013 store_in_alist (alistptr, Qwindow_id,
3014 build_string (buf));
3015 #ifdef HAVE_X_WINDOWS
3016 #ifdef USE_X_TOOLKIT
3017 /* Tooltip frame may not have this widget. */
3018 if (FRAME_X_OUTPUT (f)->widget)
3019 #endif
3020 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
3021 store_in_alist (alistptr, Qouter_window_id,
3022 build_string (buf));
3023 #endif
3024 store_in_alist (alistptr, Qicon_name, f->icon_name);
3025 FRAME_SAMPLE_VISIBILITY (f);
3026 store_in_alist (alistptr, Qvisibility,
3027 (FRAME_VISIBLE_P (f) ? Qt
3028 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3029 store_in_alist (alistptr, Qdisplay,
3030 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
3032 #ifndef HAVE_CARBON
3033 /* A Mac Window is identified by a struct, not an integer. */
3034 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
3035 tem = Qnil;
3036 else
3037 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
3038 store_in_alist (alistptr, Qparent_id, tem);
3039 #endif
3043 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3044 the previous value of that parameter, NEW_VALUE is the new value. */
3046 void
3047 x_set_fullscreen (f, new_value, old_value)
3048 struct frame *f;
3049 Lisp_Object new_value, old_value;
3051 #ifndef HAVE_CARBON
3052 if (NILP (new_value))
3053 f->want_fullscreen = FULLSCREEN_NONE;
3054 else if (EQ (new_value, Qfullboth))
3055 f->want_fullscreen = FULLSCREEN_BOTH;
3056 else if (EQ (new_value, Qfullwidth))
3057 f->want_fullscreen = FULLSCREEN_WIDTH;
3058 else if (EQ (new_value, Qfullheight))
3059 f->want_fullscreen = FULLSCREEN_HEIGHT;
3060 #endif
3064 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3065 the previous value of that parameter, NEW_VALUE is the new value. */
3067 void
3068 x_set_line_spacing (f, new_value, old_value)
3069 struct frame *f;
3070 Lisp_Object new_value, old_value;
3072 if (NILP (new_value))
3073 f->extra_line_spacing = 0;
3074 else if (NATNUMP (new_value))
3075 f->extra_line_spacing = XFASTINT (new_value);
3076 else
3077 Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"),
3078 Fcons (new_value, Qnil)));
3079 if (FRAME_VISIBLE_P (f))
3080 redraw_frame (f);
3084 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3085 the previous value of that parameter, NEW_VALUE is the new value. */
3087 void
3088 x_set_screen_gamma (f, new_value, old_value)
3089 struct frame *f;
3090 Lisp_Object new_value, old_value;
3092 if (NILP (new_value))
3093 f->gamma = 0;
3094 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3095 /* The value 0.4545 is the normal viewing gamma. */
3096 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3097 else
3098 Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"),
3099 Fcons (new_value, Qnil)));
3101 clear_face_cache (0);
3105 void
3106 x_set_font (f, arg, oldval)
3107 struct frame *f;
3108 Lisp_Object arg, oldval;
3110 Lisp_Object result;
3111 Lisp_Object fontset_name;
3112 Lisp_Object frame;
3113 int old_fontset = FRAME_FONTSET(f);
3115 CHECK_STRING (arg);
3117 fontset_name = Fquery_fontset (arg, Qnil);
3119 BLOCK_INPUT;
3120 result = (STRINGP (fontset_name)
3121 ? x_new_fontset (f, SDATA (fontset_name))
3122 : x_new_font (f, SDATA (arg)));
3123 UNBLOCK_INPUT;
3125 if (EQ (result, Qnil))
3126 error ("Font `%s' is not defined", SDATA (arg));
3127 else if (EQ (result, Qt))
3128 error ("The characters of the given font have varying widths");
3129 else if (STRINGP (result))
3131 if (STRINGP (fontset_name))
3133 /* Fontset names are built from ASCII font names, so the
3134 names may be equal despite there was a change. */
3135 if (old_fontset == FRAME_FONTSET (f))
3136 return;
3138 else if (!NILP (Fequal (result, oldval)))
3139 return;
3141 store_frame_param (f, Qfont, result);
3142 recompute_basic_faces (f);
3144 else
3145 abort ();
3147 do_pending_window_change (0);
3149 /* Don't call `face-set-after-frame-default' when faces haven't been
3150 initialized yet. This is the case when called from
3151 Fx_create_frame. In that case, the X widget or window doesn't
3152 exist either, and we can end up in x_report_frame_params with a
3153 null widget which gives a segfault. */
3154 if (FRAME_FACE_CACHE (f))
3156 XSETFRAME (frame, f);
3157 call1 (Qface_set_after_frame_default, frame);
3162 void
3163 x_set_fringe_width (f, new_value, old_value)
3164 struct frame *f;
3165 Lisp_Object new_value, old_value;
3167 compute_fringe_widths (f, 1);
3170 void
3171 x_set_border_width (f, arg, oldval)
3172 struct frame *f;
3173 Lisp_Object arg, oldval;
3175 CHECK_NUMBER (arg);
3177 if (XINT (arg) == f->border_width)
3178 return;
3180 #ifndef HAVE_CARBON
3181 if (FRAME_X_WINDOW (f) != 0)
3182 error ("Cannot change the border width of a window");
3183 #endif /* MAC_TODO */
3185 f->border_width = XINT (arg);
3188 void
3189 x_set_internal_border_width (f, arg, oldval)
3190 struct frame *f;
3191 Lisp_Object arg, oldval;
3193 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
3195 CHECK_NUMBER (arg);
3196 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3197 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3198 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
3200 #ifdef USE_X_TOOLKIT
3201 if (FRAME_X_OUTPUT (f)->edit_widget)
3202 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3203 #endif
3205 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
3206 return;
3208 if (FRAME_X_WINDOW (f) != 0)
3210 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3211 SET_FRAME_GARBAGED (f);
3212 do_pending_window_change (0);
3214 else
3215 SET_FRAME_GARBAGED (f);
3218 void
3219 x_set_visibility (f, value, oldval)
3220 struct frame *f;
3221 Lisp_Object value, oldval;
3223 Lisp_Object frame;
3224 XSETFRAME (frame, f);
3226 if (NILP (value))
3227 Fmake_frame_invisible (frame, Qt);
3228 else if (EQ (value, Qicon))
3229 Ficonify_frame (frame);
3230 else
3231 Fmake_frame_visible (frame);
3234 void
3235 x_set_autoraise (f, arg, oldval)
3236 struct frame *f;
3237 Lisp_Object arg, oldval;
3239 f->auto_raise = !EQ (Qnil, arg);
3242 void
3243 x_set_autolower (f, arg, oldval)
3244 struct frame *f;
3245 Lisp_Object arg, oldval;
3247 f->auto_lower = !EQ (Qnil, arg);
3250 void
3251 x_set_unsplittable (f, arg, oldval)
3252 struct frame *f;
3253 Lisp_Object arg, oldval;
3255 f->no_split = !NILP (arg);
3258 void
3259 x_set_vertical_scroll_bars (f, arg, oldval)
3260 struct frame *f;
3261 Lisp_Object arg, oldval;
3263 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3264 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3265 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3266 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3268 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3269 = (NILP (arg)
3270 ? vertical_scroll_bar_none
3271 : EQ (Qleft, arg)
3272 ? vertical_scroll_bar_left
3273 : EQ (Qright, arg)
3274 ? vertical_scroll_bar_right
3275 : EQ (Qleft, Vdefault_frame_scroll_bars)
3276 ? vertical_scroll_bar_left
3277 : EQ (Qright, Vdefault_frame_scroll_bars)
3278 ? vertical_scroll_bar_right
3279 : vertical_scroll_bar_none);
3281 /* We set this parameter before creating the X window for the
3282 frame, so we can get the geometry right from the start.
3283 However, if the window hasn't been created yet, we shouldn't
3284 call x_set_window_size. */
3285 if (FRAME_X_WINDOW (f))
3286 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3287 do_pending_window_change (0);
3291 void
3292 x_set_scroll_bar_width (f, arg, oldval)
3293 struct frame *f;
3294 Lisp_Object arg, oldval;
3296 int wid = FRAME_COLUMN_WIDTH (f);
3298 if (NILP (arg))
3300 x_set_scroll_bar_default_width (f);
3302 if (FRAME_X_WINDOW (f))
3303 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3304 do_pending_window_change (0);
3306 else if (INTEGERP (arg) && XINT (arg) > 0
3307 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3309 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3310 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3312 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3313 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3314 if (FRAME_X_WINDOW (f))
3315 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3316 do_pending_window_change (0);
3319 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
3320 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3321 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3326 /* Return non-nil if frame F wants a bitmap icon. */
3328 Lisp_Object
3329 x_icon_type (f)
3330 FRAME_PTR f;
3332 Lisp_Object tem;
3334 tem = assq_no_quit (Qicon_type, f->param_alist);
3335 if (CONSP (tem))
3336 return XCDR (tem);
3337 else
3338 return Qnil;
3342 /* Subroutines of creating an X frame. */
3344 /* Make sure that Vx_resource_name is set to a reasonable value.
3345 Fix it up, or set it to `emacs' if it is too hopeless. */
3347 void
3348 validate_x_resource_name ()
3350 int len = 0;
3351 /* Number of valid characters in the resource name. */
3352 int good_count = 0;
3353 /* Number of invalid characters in the resource name. */
3354 int bad_count = 0;
3355 Lisp_Object new;
3356 int i;
3358 if (!STRINGP (Vx_resource_class))
3359 Vx_resource_class = build_string (EMACS_CLASS);
3361 if (STRINGP (Vx_resource_name))
3363 unsigned char *p = SDATA (Vx_resource_name);
3364 int i;
3366 len = SBYTES (Vx_resource_name);
3368 /* Only letters, digits, - and _ are valid in resource names.
3369 Count the valid characters and count the invalid ones. */
3370 for (i = 0; i < len; i++)
3372 int c = p[i];
3373 if (! ((c >= 'a' && c <= 'z')
3374 || (c >= 'A' && c <= 'Z')
3375 || (c >= '0' && c <= '9')
3376 || c == '-' || c == '_'))
3377 bad_count++;
3378 else
3379 good_count++;
3382 else
3383 /* Not a string => completely invalid. */
3384 bad_count = 5, good_count = 0;
3386 /* If name is valid already, return. */
3387 if (bad_count == 0)
3388 return;
3390 /* If name is entirely invalid, or nearly so, use `emacs'. */
3391 if (good_count == 0
3392 || (good_count == 1 && bad_count > 0))
3394 Vx_resource_name = build_string ("emacs");
3395 return;
3398 /* Name is partly valid. Copy it and replace the invalid characters
3399 with underscores. */
3401 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3403 for (i = 0; i < len; i++)
3405 int c = SREF (new, i);
3406 if (! ((c >= 'a' && c <= 'z')
3407 || (c >= 'A' && c <= 'Z')
3408 || (c >= '0' && c <= '9')
3409 || c == '-' || c == '_'))
3410 SSET (new, i, '_');
3415 extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3416 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3419 /* Get specified attribute from resource database RDB.
3420 See Fx_get_resource below for other parameters. */
3422 static Lisp_Object
3423 xrdb_get_resource (rdb, attribute, class, component, subclass)
3424 XrmDatabase rdb;
3425 Lisp_Object attribute, class, component, subclass;
3427 register char *value;
3428 char *name_key;
3429 char *class_key;
3431 CHECK_STRING (attribute);
3432 CHECK_STRING (class);
3434 if (!NILP (component))
3435 CHECK_STRING (component);
3436 if (!NILP (subclass))
3437 CHECK_STRING (subclass);
3438 if (NILP (component) != NILP (subclass))
3439 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3441 validate_x_resource_name ();
3443 /* Allocate space for the components, the dots which separate them,
3444 and the final '\0'. Make them big enough for the worst case. */
3445 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3446 + (STRINGP (component)
3447 ? SBYTES (component) : 0)
3448 + SBYTES (attribute)
3449 + 3);
3451 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3452 + SBYTES (class)
3453 + (STRINGP (subclass)
3454 ? SBYTES (subclass) : 0)
3455 + 3);
3457 /* Start with emacs.FRAMENAME for the name (the specific one)
3458 and with `Emacs' for the class key (the general one). */
3459 strcpy (name_key, SDATA (Vx_resource_name));
3460 strcpy (class_key, SDATA (Vx_resource_class));
3462 strcat (class_key, ".");
3463 strcat (class_key, SDATA (class));
3465 if (!NILP (component))
3467 strcat (class_key, ".");
3468 strcat (class_key, SDATA (subclass));
3470 strcat (name_key, ".");
3471 strcat (name_key, SDATA (component));
3474 strcat (name_key, ".");
3475 strcat (name_key, SDATA (attribute));
3477 value = x_get_string_resource (rdb, name_key, class_key);
3479 if (value != (char *) 0)
3480 return build_string (value);
3481 else
3482 return Qnil;
3486 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3487 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3488 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3489 class, where INSTANCE is the name under which Emacs was invoked, or
3490 the name specified by the `-name' or `-rn' command-line arguments.
3492 The optional arguments COMPONENT and SUBCLASS add to the key and the
3493 class, respectively. You must specify both of them or neither.
3494 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3495 and the class is `Emacs.CLASS.SUBCLASS'. */)
3496 (attribute, class, component, subclass)
3497 Lisp_Object attribute, class, component, subclass;
3499 #ifdef HAVE_X_WINDOWS
3500 check_x ();
3501 #endif
3503 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3504 attribute, class, component, subclass);
3507 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3509 Lisp_Object
3510 display_x_get_resource (dpyinfo, attribute, class, component, subclass)
3511 Display_Info *dpyinfo;
3512 Lisp_Object attribute, class, component, subclass;
3514 return xrdb_get_resource (dpyinfo->xrdb,
3515 attribute, class, component, subclass);
3518 /* Used when C code wants a resource value. */
3520 char *
3521 x_get_resource_string (attribute, class)
3522 char *attribute, *class;
3524 char *name_key;
3525 char *class_key;
3526 struct frame *sf = SELECTED_FRAME ();
3528 /* Allocate space for the components, the dots which separate them,
3529 and the final '\0'. */
3530 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3531 + strlen (attribute) + 2);
3532 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3533 + strlen (class) + 2);
3535 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3536 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3538 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3539 name_key, class_key);
3543 /* Return the value of parameter PARAM.
3545 First search ALIST, then Vdefault_frame_alist, then the X defaults
3546 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3548 Convert the resource to the type specified by desired_type.
3550 If no default is specified, return Qunbound. If you call
3551 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3552 and don't let it get stored in any Lisp-visible variables! */
3554 Lisp_Object
3555 x_get_arg (dpyinfo, alist, param, attribute, class, type)
3556 Display_Info *dpyinfo;
3557 Lisp_Object alist, param;
3558 char *attribute;
3559 char *class;
3560 enum resource_types type;
3562 register Lisp_Object tem;
3564 tem = Fassq (param, alist);
3565 if (EQ (tem, Qnil))
3566 tem = Fassq (param, Vdefault_frame_alist);
3567 if (EQ (tem, Qnil))
3569 if (attribute)
3571 tem = display_x_get_resource (dpyinfo,
3572 build_string (attribute),
3573 build_string (class),
3574 Qnil, Qnil);
3576 if (NILP (tem))
3577 return Qunbound;
3579 switch (type)
3581 case RES_TYPE_NUMBER:
3582 return make_number (atoi (SDATA (tem)));
3584 case RES_TYPE_FLOAT:
3585 return make_float (atof (SDATA (tem)));
3587 case RES_TYPE_BOOLEAN:
3588 tem = Fdowncase (tem);
3589 if (!strcmp (SDATA (tem), "on")
3590 || !strcmp (SDATA (tem), "true"))
3591 return Qt;
3592 else
3593 return Qnil;
3595 case RES_TYPE_STRING:
3596 return tem;
3598 case RES_TYPE_SYMBOL:
3599 /* As a special case, we map the values `true' and `on'
3600 to Qt, and `false' and `off' to Qnil. */
3602 Lisp_Object lower;
3603 lower = Fdowncase (tem);
3604 if (!strcmp (SDATA (lower), "on")
3605 || !strcmp (SDATA (lower), "true"))
3606 return Qt;
3607 else if (!strcmp (SDATA (lower), "off")
3608 || !strcmp (SDATA (lower), "false"))
3609 return Qnil;
3610 else
3611 return Fintern (tem, Qnil);
3614 default:
3615 abort ();
3618 else
3619 return Qunbound;
3621 return Fcdr (tem);
3624 Lisp_Object
3625 x_frame_get_arg (f, alist, param, attribute, class, type)
3626 struct frame *f;
3627 Lisp_Object alist, param;
3628 char *attribute;
3629 char *class;
3630 enum resource_types type;
3632 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3633 alist, param, attribute, class, type);
3636 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
3638 Lisp_Object
3639 x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
3640 struct frame *f;
3641 Lisp_Object alist, param;
3642 char *attribute;
3643 char *class;
3644 enum resource_types type;
3646 Lisp_Object value;
3648 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3649 attribute, class, type);
3650 if (! NILP (value))
3651 store_frame_param (f, param, value);
3653 return value;
3657 /* Record in frame F the specified or default value according to ALIST
3658 of the parameter named PROP (a Lisp symbol).
3659 If no value is specified for PROP, look for an X default for XPROP
3660 on the frame named NAME.
3661 If that is not found either, use the value DEFLT. */
3663 Lisp_Object
3664 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
3665 struct frame *f;
3666 Lisp_Object alist;
3667 Lisp_Object prop;
3668 Lisp_Object deflt;
3669 char *xprop;
3670 char *xclass;
3671 enum resource_types type;
3673 Lisp_Object tem;
3675 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3676 if (EQ (tem, Qunbound))
3677 tem = deflt;
3678 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
3679 return tem;
3685 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
3686 doc: /* Parse an X-style geometry string STRING.
3687 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3688 The properties returned may include `top', `left', `height', and `width'.
3689 The value of `left' or `top' may be an integer,
3690 or a list (+ N) meaning N pixels relative to top/left corner,
3691 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3692 (string)
3693 Lisp_Object string;
3695 int geometry, x, y;
3696 unsigned int width, height;
3697 Lisp_Object result;
3699 CHECK_STRING (string);
3701 geometry = XParseGeometry ((char *) SDATA (string),
3702 &x, &y, &width, &height);
3704 #if 0
3705 if (!!(geometry & XValue) != !!(geometry & YValue))
3706 error ("Must specify both x and y position, or neither");
3707 #endif
3709 result = Qnil;
3710 if (geometry & XValue)
3712 Lisp_Object element;
3714 if (x >= 0 && (geometry & XNegative))
3715 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
3716 else if (x < 0 && ! (geometry & XNegative))
3717 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
3718 else
3719 element = Fcons (Qleft, make_number (x));
3720 result = Fcons (element, result);
3723 if (geometry & YValue)
3725 Lisp_Object element;
3727 if (y >= 0 && (geometry & YNegative))
3728 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
3729 else if (y < 0 && ! (geometry & YNegative))
3730 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
3731 else
3732 element = Fcons (Qtop, make_number (y));
3733 result = Fcons (element, result);
3736 if (geometry & WidthValue)
3737 result = Fcons (Fcons (Qwidth, make_number (width)), result);
3738 if (geometry & HeightValue)
3739 result = Fcons (Fcons (Qheight, make_number (height)), result);
3741 return result;
3744 /* Calculate the desired size and position of frame F.
3745 Return the flags saying which aspects were specified.
3747 Also set the win_gravity and size_hint_flags of F.
3749 Adjust height for toolbar if TOOLBAR_P is 1.
3751 This function does not make the coordinates positive. */
3753 #define DEFAULT_ROWS 40
3754 #define DEFAULT_COLS 80
3757 x_figure_window_size (f, parms, toolbar_p)
3758 struct frame *f;
3759 Lisp_Object parms;
3760 int toolbar_p;
3762 register Lisp_Object tem0, tem1, tem2;
3763 long window_prompting = 0;
3764 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3766 /* Default values if we fall through.
3767 Actually, if that happens we should get
3768 window manager prompting. */
3769 SET_FRAME_COLS (f, DEFAULT_COLS);
3770 FRAME_LINES (f) = DEFAULT_ROWS;
3771 /* Window managers expect that if program-specified
3772 positions are not (0,0), they're intentional, not defaults. */
3773 f->top_pos = 0;
3774 f->left_pos = 0;
3776 /* Ensure that old new_text_cols and new_text_lines will not override the
3777 values set here. */
3778 /* ++KFS: This was specific to W32, but seems ok for all platforms */
3779 f->new_text_cols = f->new_text_lines = 0;
3781 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
3782 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
3783 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
3784 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3786 if (!EQ (tem0, Qunbound))
3788 CHECK_NUMBER (tem0);
3789 FRAME_LINES (f) = XINT (tem0);
3791 if (!EQ (tem1, Qunbound))
3793 CHECK_NUMBER (tem1);
3794 SET_FRAME_COLS (f, XINT (tem1));
3796 if (!NILP (tem2) && !EQ (tem2, Qunbound))
3797 window_prompting |= USSize;
3798 else
3799 window_prompting |= PSize;
3802 f->scroll_bar_actual_width
3803 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
3805 /* This used to be done _before_ calling x_figure_window_size, but
3806 since the height is reset here, this was really a no-op. I
3807 assume that moving it here does what Gerd intended (although he
3808 no longer can remember what that was... ++KFS, 2003-03-25. */
3810 /* Add the tool-bar height to the initial frame height so that the
3811 user gets a text display area of the size he specified with -g or
3812 via .Xdefaults. Later changes of the tool-bar height don't
3813 change the frame size. This is done so that users can create
3814 tall Emacs frames without having to guess how tall the tool-bar
3815 will get. */
3816 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
3818 int margin, relief, bar_height;
3820 relief = (tool_bar_button_relief >= 0
3821 ? tool_bar_button_relief
3822 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
3824 if (INTEGERP (Vtool_bar_button_margin)
3825 && XINT (Vtool_bar_button_margin) > 0)
3826 margin = XFASTINT (Vtool_bar_button_margin);
3827 else if (CONSP (Vtool_bar_button_margin)
3828 && INTEGERP (XCDR (Vtool_bar_button_margin))
3829 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
3830 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
3831 else
3832 margin = 0;
3834 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
3835 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
3838 compute_fringe_widths (f, 0);
3840 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
3841 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
3843 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
3844 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
3845 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
3846 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3848 if (EQ (tem0, Qminus))
3850 f->top_pos = 0;
3851 window_prompting |= YNegative;
3853 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
3854 && CONSP (XCDR (tem0))
3855 && INTEGERP (XCAR (XCDR (tem0))))
3857 f->top_pos = - XINT (XCAR (XCDR (tem0)));
3858 window_prompting |= YNegative;
3860 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
3861 && CONSP (XCDR (tem0))
3862 && INTEGERP (XCAR (XCDR (tem0))))
3864 f->top_pos = XINT (XCAR (XCDR (tem0)));
3866 else if (EQ (tem0, Qunbound))
3867 f->top_pos = 0;
3868 else
3870 CHECK_NUMBER (tem0);
3871 f->top_pos = XINT (tem0);
3872 if (f->top_pos < 0)
3873 window_prompting |= YNegative;
3876 if (EQ (tem1, Qminus))
3878 f->left_pos = 0;
3879 window_prompting |= XNegative;
3881 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
3882 && CONSP (XCDR (tem1))
3883 && INTEGERP (XCAR (XCDR (tem1))))
3885 f->left_pos = - XINT (XCAR (XCDR (tem1)));
3886 window_prompting |= XNegative;
3888 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
3889 && CONSP (XCDR (tem1))
3890 && INTEGERP (XCAR (XCDR (tem1))))
3892 f->left_pos = XINT (XCAR (XCDR (tem1)));
3894 else if (EQ (tem1, Qunbound))
3895 f->left_pos = 0;
3896 else
3898 CHECK_NUMBER (tem1);
3899 f->left_pos = XINT (tem1);
3900 if (f->left_pos < 0)
3901 window_prompting |= XNegative;
3904 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
3905 window_prompting |= USPosition;
3906 else
3907 window_prompting |= PPosition;
3910 if (f->want_fullscreen != FULLSCREEN_NONE)
3912 int left, top;
3913 int width, height;
3915 /* It takes both for some WM:s to place it where we want */
3916 window_prompting = USPosition | PPosition;
3917 x_fullscreen_adjust (f, &width, &height, &top, &left);
3918 FRAME_COLS (f) = width;
3919 FRAME_LINES (f) = height;
3920 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
3921 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
3922 f->left_pos = left;
3923 f->top_pos = top;
3926 if (window_prompting & XNegative)
3928 if (window_prompting & YNegative)
3929 f->win_gravity = SouthEastGravity;
3930 else
3931 f->win_gravity = NorthEastGravity;
3933 else
3935 if (window_prompting & YNegative)
3936 f->win_gravity = SouthWestGravity;
3937 else
3938 f->win_gravity = NorthWestGravity;
3941 f->size_hint_flags = window_prompting;
3943 return window_prompting;
3948 #endif /* HAVE_WINDOW_SYSTEM */
3952 /***********************************************************************
3953 Initialization
3954 ***********************************************************************/
3956 void
3957 syms_of_frame ()
3959 Qframep = intern ("framep");
3960 staticpro (&Qframep);
3961 Qframe_live_p = intern ("frame-live-p");
3962 staticpro (&Qframe_live_p);
3963 Qheight = intern ("height");
3964 staticpro (&Qheight);
3965 Qicon = intern ("icon");
3966 staticpro (&Qicon);
3967 Qminibuffer = intern ("minibuffer");
3968 staticpro (&Qminibuffer);
3969 Qmodeline = intern ("modeline");
3970 staticpro (&Qmodeline);
3971 Qonly = intern ("only");
3972 staticpro (&Qonly);
3973 Qwidth = intern ("width");
3974 staticpro (&Qwidth);
3975 Qgeometry = intern ("geometry");
3976 staticpro (&Qgeometry);
3977 Qicon_left = intern ("icon-left");
3978 staticpro (&Qicon_left);
3979 Qicon_top = intern ("icon-top");
3980 staticpro (&Qicon_top);
3981 Qleft = intern ("left");
3982 staticpro (&Qleft);
3983 Qright = intern ("right");
3984 staticpro (&Qright);
3985 Quser_position = intern ("user-position");
3986 staticpro (&Quser_position);
3987 Quser_size = intern ("user-size");
3988 staticpro (&Quser_size);
3989 Qwindow_id = intern ("window-id");
3990 staticpro (&Qwindow_id);
3991 #ifdef HAVE_X_WINDOWS
3992 Qouter_window_id = intern ("outer-window-id");
3993 staticpro (&Qouter_window_id);
3994 #endif
3995 Qparent_id = intern ("parent-id");
3996 staticpro (&Qparent_id);
3997 Qx = intern ("x");
3998 staticpro (&Qx);
3999 Qw32 = intern ("w32");
4000 staticpro (&Qw32);
4001 Qpc = intern ("pc");
4002 staticpro (&Qpc);
4003 Qmac = intern ("mac");
4004 staticpro (&Qmac);
4005 Qvisible = intern ("visible");
4006 staticpro (&Qvisible);
4007 Qbuffer_predicate = intern ("buffer-predicate");
4008 staticpro (&Qbuffer_predicate);
4009 Qbuffer_list = intern ("buffer-list");
4010 staticpro (&Qbuffer_list);
4011 Qdisplay_type = intern ("display-type");
4012 staticpro (&Qdisplay_type);
4013 Qbackground_mode = intern ("background-mode");
4014 staticpro (&Qbackground_mode);
4015 Qtty_color_mode = intern ("tty-color-mode");
4016 staticpro (&Qtty_color_mode);
4017 Qtty = intern ("tty");
4018 staticpro (&Qtty);
4019 Qtty_type = intern ("tty-type");
4020 staticpro (&Qtty_type);
4022 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
4023 staticpro (&Qface_set_after_frame_default);
4025 Qfullwidth = intern ("fullwidth");
4026 staticpro (&Qfullwidth);
4027 Qfullheight = intern ("fullheight");
4028 staticpro (&Qfullheight);
4029 Qfullboth = intern ("fullboth");
4030 staticpro (&Qfullboth);
4031 Qx_resource_name = intern ("x-resource-name");
4032 staticpro (&Qx_resource_name);
4034 Qx_frame_parameter = intern ("x-frame-parameter");
4035 staticpro (&Qx_frame_parameter);
4038 int i;
4040 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4042 Lisp_Object v = intern (frame_parms[i].name);
4043 if (frame_parms[i].variable)
4045 *frame_parms[i].variable = v;
4046 staticpro (frame_parms[i].variable);
4048 Fput (v, Qx_frame_parameter, make_number (i));
4052 #ifdef HAVE_WINDOW_SYSTEM
4053 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4054 doc: /* The name Emacs uses to look up X resources.
4055 `x-get-resource' uses this as the first component of the instance name
4056 when requesting resource values.
4057 Emacs initially sets `x-resource-name' to the name under which Emacs
4058 was invoked, or to the value specified with the `-name' or `-rn'
4059 switches, if present.
4061 It may be useful to bind this variable locally around a call
4062 to `x-get-resource'. See also the variable `x-resource-class'. */);
4063 Vx_resource_name = Qnil;
4065 DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4066 doc: /* The class Emacs uses to look up X resources.
4067 `x-get-resource' uses this as the first component of the instance class
4068 when requesting resource values.
4070 Emacs initially sets `x-resource-class' to "Emacs".
4072 Setting this variable permanently is not a reasonable thing to do,
4073 but binding this variable locally around a call to `x-get-resource'
4074 is a reasonable practice. See also the variable `x-resource-name'. */);
4075 Vx_resource_class = build_string (EMACS_CLASS);
4076 #endif
4078 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
4079 doc: /* Alist of default values for frame creation.
4080 These may be set in your init file, like this:
4081 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))
4082 These override values given in window system configuration data,
4083 including X Windows' defaults database.
4084 For values specific to the first Emacs frame, see `initial-frame-alist'.
4085 For values specific to the separate minibuffer frame, see
4086 `minibuffer-frame-alist'.
4087 The `menu-bar-lines' element of the list controls whether new frames
4088 have menu bars; `menu-bar-mode' works by altering this element.
4089 Setting this variable does not affect existing frames, only new ones. */);
4090 Vdefault_frame_alist = Qnil;
4092 DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
4093 doc: /* Default position of scroll bars on this window-system. */);
4094 #ifdef HAVE_WINDOW_SYSTEM
4095 #if defined(HAVE_NTGUI) || defined(HAVE_CARBON)
4096 /* MS-Windows has scroll bars on the right by default. */
4097 Vdefault_frame_scroll_bars = Qright;
4098 #else
4099 Vdefault_frame_scroll_bars = Qleft;
4100 #endif
4101 #else
4102 Vdefault_frame_scroll_bars = Qnil;
4103 #endif
4105 Qinhibit_default_face_x_resources
4106 = intern ("inhibit-default-face-x-resources");
4107 staticpro (&Qinhibit_default_face_x_resources);
4109 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
4110 doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */);
4111 Vemacs_iconified = Qnil;
4113 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
4114 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4115 `mouse-position' calls this function, passing its usual return value as
4116 argument, and returns whatever this function returns.
4117 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4118 which need to do mouse handling at the Lisp level. */);
4119 Vmouse_position_function = Qnil;
4121 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
4122 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4123 If the value is an integer, highlighting is only shown after moving the
4124 mouse, while keyboard input turns off the highlight even when the mouse
4125 is over the clickable text. However, the mouse shape still indicates
4126 when the mouse is over clickable text. */);
4127 Vmouse_highlight = Qt;
4129 DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
4130 doc: /* Functions to be run before deleting a frame.
4131 The functions are run with one arg, the frame to be deleted.
4132 See `delete-frame'. */);
4133 Vdelete_frame_functions = Qnil;
4135 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4136 doc: /* Minibufferless frames use this frame's minibuffer.
4138 Emacs cannot create minibufferless frames unless this is set to an
4139 appropriate surrogate.
4141 Emacs consults this variable only when creating minibufferless
4142 frames; once the frame is created, it sticks with its assigned
4143 minibuffer, no matter what this variable is set to. This means that
4144 this variable doesn't necessarily say anything meaningful about the
4145 current set of frames, or where the minibuffer is currently being
4146 displayed.
4148 This variable is local to the current terminal and cannot be buffer-local. */);
4150 staticpro (&Vframe_list);
4152 defsubr (&Sactive_minibuffer_window);
4153 defsubr (&Sframep);
4154 defsubr (&Sframe_live_p);
4155 defsubr (&Smake_terminal_frame);
4156 defsubr (&Shandle_switch_frame);
4157 defsubr (&Signore_event);
4158 defsubr (&Sselect_frame);
4159 defsubr (&Sselected_frame);
4160 defsubr (&Swindow_frame);
4161 defsubr (&Sframe_root_window);
4162 defsubr (&Sframe_first_window);
4163 defsubr (&Sframe_selected_window);
4164 defsubr (&Sset_frame_selected_window);
4165 defsubr (&Sframe_list);
4166 defsubr (&Snext_frame);
4167 defsubr (&Sprevious_frame);
4168 defsubr (&Sdelete_frame);
4169 defsubr (&Smouse_position);
4170 defsubr (&Smouse_pixel_position);
4171 defsubr (&Sset_mouse_position);
4172 defsubr (&Sset_mouse_pixel_position);
4173 #if 0
4174 defsubr (&Sframe_configuration);
4175 defsubr (&Srestore_frame_configuration);
4176 #endif
4177 defsubr (&Smake_frame_visible);
4178 defsubr (&Smake_frame_invisible);
4179 defsubr (&Siconify_frame);
4180 defsubr (&Sframe_visible_p);
4181 defsubr (&Svisible_frame_list);
4182 defsubr (&Sraise_frame);
4183 defsubr (&Slower_frame);
4184 defsubr (&Sredirect_frame_focus);
4185 defsubr (&Sframe_focus);
4186 defsubr (&Sframe_parameters);
4187 defsubr (&Sframe_parameter);
4188 defsubr (&Smodify_frame_parameters);
4189 defsubr (&Sframe_char_height);
4190 defsubr (&Sframe_char_width);
4191 defsubr (&Sframe_pixel_height);
4192 defsubr (&Sframe_pixel_width);
4193 defsubr (&Sset_frame_height);
4194 defsubr (&Sset_frame_width);
4195 defsubr (&Sset_frame_size);
4196 defsubr (&Sset_frame_position);
4198 #ifdef HAVE_WINDOW_SYSTEM
4199 defsubr (&Sx_get_resource);
4200 defsubr (&Sx_parse_geometry);
4201 #endif
4205 /* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039
4206 (do not change this comment) */