Merge from trunk
[emacs.git] / src / frame.c
blobe0c8ba7be11581a32a8aced1e22f7b935c4207c1
1 /* Generic frame functions.
3 Copyright (C) 1993-1995, 1997, 1999-2011 Free Software Foundation, Inc.
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 3 of the License, or
10 (at your option) 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. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
22 #include <stdio.h>
23 #include <ctype.h>
24 #include <errno.h>
25 #include <limits.h>
26 #include <setjmp.h>
27 #include "lisp.h"
28 #include "character.h"
29 #ifdef HAVE_X_WINDOWS
30 #include "xterm.h"
31 #endif
32 #ifdef WINDOWSNT
33 #include "w32term.h"
34 #endif
35 #ifdef HAVE_NS
36 #include "nsterm.h"
37 #endif
38 #include "buffer.h"
39 /* These help us bind and responding to switch-frame events. */
40 #include "commands.h"
41 #include "keyboard.h"
42 #include "frame.h"
43 #include "blockinput.h"
44 #include "termchar.h"
45 #include "termhooks.h"
46 #include "dispextern.h"
47 #include "window.h"
48 #include "font.h"
49 #ifdef HAVE_WINDOW_SYSTEM
50 #include "fontset.h"
51 #endif
52 #ifdef MSDOS
53 #include "msdos.h"
54 #include "dosfns.h"
55 #endif
58 #ifdef HAVE_WINDOW_SYSTEM
60 #endif
62 #ifdef HAVE_NS
63 Lisp_Object Qns_parse_geometry;
64 #endif
66 Lisp_Object Qframep, Qframe_live_p;
67 Lisp_Object Qicon, Qmodeline;
68 Lisp_Object Qonly;
69 Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
70 Lisp_Object Qvisible;
71 Lisp_Object Qdisplay_type;
72 static Lisp_Object Qbackground_mode;
73 Lisp_Object Qnoelisp;
75 static Lisp_Object Qx_frame_parameter;
76 Lisp_Object Qx_resource_name;
77 Lisp_Object Qterminal;
78 Lisp_Object Qterminal_live_p;
80 /* Frame parameters (set or reported). */
82 Lisp_Object Qauto_raise, Qauto_lower;
83 Lisp_Object Qborder_color, Qborder_width;
84 Lisp_Object Qcursor_color, Qcursor_type;
85 static Lisp_Object Qgeometry; /* Not used */
86 Lisp_Object Qheight, Qwidth;
87 Lisp_Object Qleft, Qright;
88 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
89 Lisp_Object Qtooltip;
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 static Lisp_Object Quser_position, Quser_size;
99 Lisp_Object Qwait_for_wm;
100 static Lisp_Object Qwindow_id;
101 #ifdef HAVE_X_WINDOWS
102 static Lisp_Object Qouter_window_id;
103 #endif
104 Lisp_Object Qparent_id;
105 Lisp_Object Qtitle, Qname;
106 static Lisp_Object Qexplicit_name;
107 Lisp_Object Qunsplittable;
108 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
109 Lisp_Object Qleft_fringe, Qright_fringe;
110 Lisp_Object Qbuffer_predicate;
111 static Lisp_Object Qbuffer_list, Qburied_buffer_list;
112 Lisp_Object Qtty_color_mode;
113 Lisp_Object Qtty, Qtty_type;
115 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
116 Lisp_Object Qsticky;
117 Lisp_Object Qfont_backend;
118 Lisp_Object Qalpha;
120 Lisp_Object Qface_set_after_frame_default;
122 static Lisp_Object Qdelete_frame_functions;
124 #ifdef HAVE_WINDOW_SYSTEM
125 static void x_report_frame_params (struct frame *, Lisp_Object *);
126 #endif
129 static void
130 set_menu_bar_lines_1 (Lisp_Object window, int n)
132 struct window *w = XWINDOW (window);
134 XSETFASTINT (w->last_modified, 0);
135 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
136 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
138 /* Handle just the top child in a vertical split. */
139 if (!NILP (w->vchild))
140 set_menu_bar_lines_1 (w->vchild, n);
142 /* Adjust all children in a horizontal split. */
143 for (window = w->hchild; !NILP (window); window = w->next)
145 w = XWINDOW (window);
146 set_menu_bar_lines_1 (window, n);
150 void
151 set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
153 int nlines;
154 int olines = FRAME_MENU_BAR_LINES (f);
156 /* Right now, menu bars don't work properly in minibuf-only frames;
157 most of the commands try to apply themselves to the minibuffer
158 frame itself, and get an error because you can't switch buffers
159 in or split the minibuffer window. */
160 if (FRAME_MINIBUF_ONLY_P (f))
161 return;
163 if (INTEGERP (value))
164 nlines = XINT (value);
165 else
166 nlines = 0;
168 if (nlines != olines)
170 windows_or_buffers_changed++;
171 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
172 FRAME_MENU_BAR_LINES (f) = nlines;
173 set_menu_bar_lines_1 (f->root_window, nlines - olines);
174 adjust_glyphs (f);
178 Lisp_Object Vframe_list;
181 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
182 doc: /* Return non-nil if OBJECT is a frame.
183 Value is:
184 t for a termcap frame (a character-only terminal),
185 'x' for an Emacs frame that is really an X window,
186 'w32' for an Emacs frame that is a window on MS-Windows display,
187 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
188 'pc' for a direct-write MS-DOS frame.
189 See also `frame-live-p'. */)
190 (Lisp_Object object)
192 if (!FRAMEP (object))
193 return Qnil;
194 switch (XFRAME (object)->output_method)
196 case output_initial: /* The initial frame is like a termcap frame. */
197 case output_termcap:
198 return Qt;
199 case output_x_window:
200 return Qx;
201 case output_w32:
202 return Qw32;
203 case output_msdos_raw:
204 return Qpc;
205 case output_mac:
206 return Qmac;
207 case output_ns:
208 return Qns;
209 default:
210 abort ();
214 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
215 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
216 Value is nil if OBJECT is not a live frame. If object is a live
217 frame, the return value indicates what sort of terminal device it is
218 displayed on. See the documentation of `framep' for possible
219 return values. */)
220 (Lisp_Object object)
222 return ((FRAMEP (object)
223 && FRAME_LIVE_P (XFRAME (object)))
224 ? Fframep (object)
225 : Qnil);
228 DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
229 doc: /* The name of the window system that FRAME is displaying through.
230 The value is a symbol:
231 nil for a termcap frame (a character-only terminal),
232 'x' for an Emacs frame that is really an X window,
233 'w32' for an Emacs frame that is a window on MS-Windows display,
234 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
235 'pc' for a direct-write MS-DOS frame.
237 FRAME defaults to the currently selected frame.
239 Use of this function as a predicate is deprecated. Instead,
240 use `display-graphic-p' or any of the other `display-*-p'
241 predicates which report frame's specific UI-related capabilities. */)
242 (Lisp_Object frame)
244 Lisp_Object type;
245 if (NILP (frame))
246 frame = selected_frame;
248 type = Fframep (frame);
250 if (NILP (type))
251 wrong_type_argument (Qframep, frame);
253 if (EQ (type, Qt))
254 return Qnil;
255 else
256 return type;
259 struct frame *
260 make_frame (int mini_p)
262 Lisp_Object frame;
263 register struct frame *f;
264 register Lisp_Object root_window;
265 register Lisp_Object mini_window;
267 f = allocate_frame ();
268 XSETFRAME (frame, f);
270 f->desired_matrix = 0;
271 f->current_matrix = 0;
272 f->desired_pool = 0;
273 f->current_pool = 0;
274 f->glyphs_initialized_p = 0;
275 f->decode_mode_spec_buffer = 0;
276 f->visible = 0;
277 f->async_visible = 0;
278 f->output_data.nothing = 0;
279 f->iconified = 0;
280 f->async_iconified = 0;
281 f->wants_modeline = 1;
282 f->auto_raise = 0;
283 f->auto_lower = 0;
284 f->no_split = 0;
285 f->garbaged = 1;
286 f->has_minibuffer = mini_p;
287 f->focus_frame = Qnil;
288 f->explicit_name = 0;
289 f->can_have_scroll_bars = 0;
290 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
291 f->param_alist = Qnil;
292 f->scroll_bars = Qnil;
293 f->condemned_scroll_bars = Qnil;
294 f->face_alist = Qnil;
295 f->face_cache = NULL;
296 f->menu_bar_items = Qnil;
297 f->menu_bar_vector = Qnil;
298 f->menu_bar_items_used = 0;
299 f->buffer_predicate = Qnil;
300 f->buffer_list = Qnil;
301 f->buried_buffer_list = Qnil;
302 f->namebuf = 0;
303 f->title = Qnil;
304 f->menu_bar_window = Qnil;
305 f->tool_bar_window = Qnil;
306 f->tool_bar_items = Qnil;
307 f->tool_bar_position = Qtop;
308 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
309 f->n_tool_bar_items = 0;
310 f->left_fringe_width = f->right_fringe_width = 0;
311 f->fringe_cols = 0;
312 f->menu_bar_lines = 0;
313 f->tool_bar_lines = 0;
314 f->scroll_bar_actual_width = 0;
315 f->border_width = 0;
316 f->internal_border_width = 0;
317 f->column_width = 1; /* !FRAME_WINDOW_P value */
318 f->line_height = 1; /* !FRAME_WINDOW_P value */
319 f->x_pixels_diff = f->y_pixels_diff = 0;
320 #ifdef HAVE_WINDOW_SYSTEM
321 f->want_fullscreen = FULLSCREEN_NONE;
322 #endif
323 f->size_hint_flags = 0;
324 f->win_gravity = 0;
325 f->font_driver_list = NULL;
326 f->font_data_list = NULL;
328 root_window = make_window ();
329 if (mini_p)
331 mini_window = make_window ();
332 XWINDOW (root_window)->next = mini_window;
333 XWINDOW (mini_window)->prev = root_window;
334 XWINDOW (mini_window)->mini_p = Qt;
335 XWINDOW (mini_window)->frame = frame;
336 f->minibuffer_window = mini_window;
338 else
340 mini_window = Qnil;
341 XWINDOW (root_window)->next = Qnil;
342 f->minibuffer_window = Qnil;
345 XWINDOW (root_window)->frame = frame;
347 /* 10 is arbitrary,
348 just so that there is "something there."
349 Correct size will be set up later with change_frame_size. */
351 SET_FRAME_COLS (f, 10);
352 FRAME_LINES (f) = 10;
354 XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
355 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10));
357 if (mini_p)
359 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
360 XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
361 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1);
364 /* Choose a buffer for the frame's root window. */
366 Lisp_Object buf;
368 XWINDOW (root_window)->buffer = Qt;
369 buf = Fcurrent_buffer ();
370 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
371 a space), try to find another one. */
372 if (SREF (Fbuffer_name (buf), 0) == ' ')
373 buf = other_buffer_safely (buf);
375 /* Use set_window_buffer, not Fset_window_buffer, and don't let
376 hooks be run by it. The reason is that the whole frame/window
377 arrangement is not yet fully intialized at this point. Windows
378 don't have the right size, glyph matrices aren't initialized
379 etc. Running Lisp functions at this point surely ends in a
380 SEGV. */
381 set_window_buffer (root_window, buf, 0, 0);
382 f->buffer_list = Fcons (buf, Qnil);
385 if (mini_p)
387 XWINDOW (mini_window)->buffer = Qt;
388 set_window_buffer (mini_window,
389 (NILP (Vminibuffer_list)
390 ? get_minibuffer (0)
391 : Fcar (Vminibuffer_list)),
392 0, 0);
395 f->root_window = root_window;
396 f->selected_window = root_window;
397 /* Make sure this window seems more recently used than
398 a newly-created, never-selected window. */
399 ++window_select_count;
400 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
402 f->default_face_done_p = 0;
404 return f;
407 #ifdef HAVE_WINDOW_SYSTEM
408 /* Make a frame using a separate minibuffer window on another frame.
409 MINI_WINDOW is the minibuffer window to use. nil means use the
410 default (the global minibuffer). */
412 struct frame *
413 make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lisp_Object display)
415 register struct frame *f;
416 struct gcpro gcpro1;
418 if (!NILP (mini_window))
419 CHECK_LIVE_WINDOW (mini_window);
421 if (!NILP (mini_window)
422 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
423 error ("Frame and minibuffer must be on the same terminal");
425 /* Make a frame containing just a root window. */
426 f = make_frame (0);
428 if (NILP (mini_window))
430 /* Use default-minibuffer-frame if possible. */
431 if (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
432 || ! FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame))))
434 Lisp_Object frame_dummy;
436 XSETFRAME (frame_dummy, f);
437 GCPRO1 (frame_dummy);
438 /* If there's no minibuffer frame to use, create one. */
439 KVAR (kb, Vdefault_minibuffer_frame) =
440 call1 (intern ("make-initial-minibuffer-frame"), display);
441 UNGCPRO;
444 mini_window = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
447 f->minibuffer_window = mini_window;
449 /* Make the chosen minibuffer window display the proper minibuffer,
450 unless it is already showing a minibuffer. */
451 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
452 Fset_window_buffer (mini_window,
453 (NILP (Vminibuffer_list)
454 ? get_minibuffer (0)
455 : Fcar (Vminibuffer_list)), Qnil);
456 return f;
459 /* Make a frame containing only a minibuffer window. */
461 struct frame *
462 make_minibuffer_frame (void)
464 /* First make a frame containing just a root window, no minibuffer. */
466 register struct frame *f = make_frame (0);
467 register Lisp_Object mini_window;
468 register Lisp_Object frame;
470 XSETFRAME (frame, f);
472 f->auto_raise = 0;
473 f->auto_lower = 0;
474 f->no_split = 1;
475 f->wants_modeline = 0;
476 f->has_minibuffer = 1;
478 /* Now label the root window as also being the minibuffer.
479 Avoid infinite looping on the window chain by marking next pointer
480 as nil. */
482 mini_window = f->minibuffer_window = f->root_window;
483 XWINDOW (mini_window)->mini_p = Qt;
484 XWINDOW (mini_window)->next = Qnil;
485 XWINDOW (mini_window)->prev = Qnil;
486 XWINDOW (mini_window)->frame = frame;
488 /* Put the proper buffer in that window. */
490 Fset_window_buffer (mini_window,
491 (NILP (Vminibuffer_list)
492 ? get_minibuffer (0)
493 : Fcar (Vminibuffer_list)), Qnil);
494 return f;
496 #endif /* HAVE_WINDOW_SYSTEM */
498 /* Construct a frame that refers to a terminal. */
500 static int tty_frame_count;
502 struct frame *
503 make_initial_frame (void)
505 struct frame *f;
506 struct terminal *terminal;
507 Lisp_Object frame;
509 eassert (initial_kboard);
511 /* The first call must initialize Vframe_list. */
512 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
513 Vframe_list = Qnil;
515 terminal = init_initial_terminal ();
517 f = make_frame (1);
518 XSETFRAME (frame, f);
520 Vframe_list = Fcons (frame, Vframe_list);
522 tty_frame_count = 1;
523 f->name = make_pure_c_string ("F1");
525 f->visible = 1;
526 f->async_visible = 1;
528 f->output_method = terminal->type;
529 f->terminal = terminal;
530 f->terminal->reference_count++;
531 f->output_data.nothing = 0;
533 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
534 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
536 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
537 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
539 /* The default value of menu-bar-mode is t. */
540 set_menu_bar_lines (f, make_number (1), Qnil);
542 #ifdef CANNOT_DUMP
543 if (!noninteractive)
544 init_frame_faces (f);
545 #endif
547 return f;
551 static struct frame *
552 make_terminal_frame (struct terminal *terminal)
554 register struct frame *f;
555 Lisp_Object frame;
556 char name[20];
558 if (!terminal->name)
559 error ("Terminal is not live, can't create new frames on it");
561 f = make_frame (1);
563 XSETFRAME (frame, f);
564 Vframe_list = Fcons (frame, Vframe_list);
566 tty_frame_count++;
567 sprintf (name, "F%d", tty_frame_count);
568 f->name = build_string (name);
570 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
571 f->async_visible = 1; /* Don't let visible be cleared later. */
572 f->terminal = terminal;
573 f->terminal->reference_count++;
574 #ifdef MSDOS
575 f->output_data.tty->display_info = &the_only_display_info;
576 if (!inhibit_window_system
577 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
578 || XFRAME (selected_frame)->output_method == output_msdos_raw))
579 f->output_method = output_msdos_raw;
580 else
581 f->output_method = output_termcap;
582 #else /* not MSDOS */
583 f->output_method = output_termcap;
584 create_tty_output (f);
585 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
586 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
587 #endif /* not MSDOS */
589 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
590 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
591 FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
593 /* Set the top frame to the newly created frame. */
594 if (FRAMEP (FRAME_TTY (f)->top_frame)
595 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
596 XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
598 FRAME_TTY (f)->top_frame = frame;
600 if (!noninteractive)
601 init_frame_faces (f);
603 return f;
606 /* Get a suitable value for frame parameter PARAMETER for a newly
607 created frame, based on (1) the user-supplied frame parameter
608 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
610 static Lisp_Object
611 get_future_frame_param (Lisp_Object parameter,
612 Lisp_Object supplied_parms,
613 char *current_value)
615 Lisp_Object result;
617 result = Fassq (parameter, supplied_parms);
618 if (NILP (result))
619 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
620 if (NILP (result) && current_value != NULL)
621 result = build_string (current_value);
622 if (!NILP (result) && !STRINGP (result))
623 result = XCDR (result);
624 if (NILP (result) || !STRINGP (result))
625 result = Qnil;
627 return result;
630 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
631 1, 1, 0,
632 doc: /* Create an additional terminal frame, possibly on another terminal.
633 This function takes one argument, an alist specifying frame parameters.
635 You can create multiple frames on a single text-only terminal, but
636 only one of them (the selected terminal frame) is actually displayed.
638 In practice, generally you don't need to specify any parameters,
639 except when you want to create a new frame on another terminal.
640 In that case, the `tty' parameter specifies the device file to open,
641 and the `tty-type' parameter specifies the terminal type. Example:
643 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
645 Note that changing the size of one terminal frame automatically
646 affects all frames on the same terminal device. */)
647 (Lisp_Object parms)
649 struct frame *f;
650 struct terminal *t = NULL;
651 Lisp_Object frame, tem;
652 struct frame *sf = SELECTED_FRAME ();
654 #ifdef MSDOS
655 if (sf->output_method != output_msdos_raw
656 && sf->output_method != output_termcap)
657 abort ();
658 #else /* not MSDOS */
660 #ifdef WINDOWSNT /* This should work now! */
661 if (sf->output_method != output_termcap)
662 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
663 #endif
664 #endif /* not MSDOS */
667 Lisp_Object terminal;
669 terminal = Fassq (Qterminal, parms);
670 if (!NILP (terminal))
672 terminal = XCDR (terminal);
673 t = get_terminal (terminal, 1);
675 #ifdef MSDOS
676 if (t && t != the_only_display_info.terminal)
677 /* msdos.c assumes a single tty_display_info object. */
678 error ("Multiple terminals are not supported on this platform");
679 if (!t)
680 t = the_only_display_info.terminal;
681 #endif
684 if (!t)
686 char *name = 0, *type = 0;
687 Lisp_Object tty, tty_type;
689 tty = get_future_frame_param
690 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
691 ? FRAME_TTY (XFRAME (selected_frame))->name
692 : NULL));
693 if (!NILP (tty))
695 name = (char *) alloca (SBYTES (tty) + 1);
696 strncpy (name, SSDATA (tty), SBYTES (tty));
697 name[SBYTES (tty)] = 0;
700 tty_type = get_future_frame_param
701 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
702 ? FRAME_TTY (XFRAME (selected_frame))->type
703 : NULL));
704 if (!NILP (tty_type))
706 type = (char *) alloca (SBYTES (tty_type) + 1);
707 strncpy (type, SSDATA (tty_type), SBYTES (tty_type));
708 type[SBYTES (tty_type)] = 0;
711 t = init_tty (name, type, 0); /* Errors are not fatal. */
714 f = make_terminal_frame (t);
717 int width, height;
718 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
719 change_frame_size (f, height, width, 0, 0, 0);
722 adjust_glyphs (f);
723 calculate_costs (f);
724 XSETFRAME (frame, f);
725 Fmodify_frame_parameters (frame, parms);
726 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
727 build_string (t->display_info.tty->type)),
728 Qnil));
729 if (t->display_info.tty->name != NULL)
730 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
731 build_string (t->display_info.tty->name)),
732 Qnil));
733 else
734 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
736 /* Make the frame face alist be frame-specific, so that each
737 frame could change its face definitions independently. */
738 f->face_alist = Fcopy_alist (sf->face_alist);
739 /* Simple Fcopy_alist isn't enough, because we need the contents of
740 the vectors which are the CDRs of associations in face_alist to
741 be copied as well. */
742 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
743 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
744 return frame;
748 /* Perform the switch to frame FRAME.
750 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
751 FRAME1 as frame.
753 If TRACK is non-zero and the frame that currently has the focus
754 redirects its focus to the selected frame, redirect that focused
755 frame's focus to FRAME instead.
757 FOR_DELETION non-zero means that the selected frame is being
758 deleted, which includes the possibility that the frame's terminal
759 is dead.
761 The value of NORECORD is passed as argument to Fselect_window. */
763 Lisp_Object
764 do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
766 struct frame *sf = SELECTED_FRAME ();
768 /* If FRAME is a switch-frame event, extract the frame we should
769 switch to. */
770 if (CONSP (frame)
771 && EQ (XCAR (frame), Qswitch_frame)
772 && CONSP (XCDR (frame)))
773 frame = XCAR (XCDR (frame));
775 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
776 a switch-frame event to arrive after a frame is no longer live,
777 especially when deleting the initial frame during startup. */
778 CHECK_FRAME (frame);
779 if (! FRAME_LIVE_P (XFRAME (frame)))
780 return Qnil;
782 if (sf == XFRAME (frame))
783 return frame;
785 /* This is too greedy; it causes inappropriate focus redirection
786 that's hard to get rid of. */
787 #if 0
788 /* If a frame's focus has been redirected toward the currently
789 selected frame, we should change the redirection to point to the
790 newly selected frame. This means that if the focus is redirected
791 from a minibufferless frame to a surrogate minibuffer frame, we
792 can use `other-window' to switch between all the frames using
793 that minibuffer frame, and the focus redirection will follow us
794 around. */
795 if (track)
797 Lisp_Object tail;
799 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
801 Lisp_Object focus;
803 if (!FRAMEP (XCAR (tail)))
804 abort ();
806 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
808 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
809 Fredirect_frame_focus (XCAR (tail), frame);
812 #else /* ! 0 */
813 /* Instead, apply it only to the frame we're pointing to. */
814 #ifdef HAVE_WINDOW_SYSTEM
815 if (track && FRAME_WINDOW_P (XFRAME (frame)))
817 Lisp_Object focus, xfocus;
819 xfocus = x_get_focus_frame (XFRAME (frame));
820 if (FRAMEP (xfocus))
822 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
823 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
824 Fredirect_frame_focus (xfocus, frame);
827 #endif /* HAVE_X_WINDOWS */
828 #endif /* ! 0 */
830 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
831 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
833 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
835 if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
836 /* Mark previously displayed frame as now obscured. */
837 XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2;
838 XFRAME (frame)->async_visible = 1;
839 FRAME_TTY (XFRAME (frame))->top_frame = frame;
842 selected_frame = frame;
843 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
844 last_nonminibuf_frame = XFRAME (selected_frame);
846 Fselect_window (XFRAME (frame)->selected_window, norecord);
848 /* We want to make sure that the next event generates a frame-switch
849 event to the appropriate frame. This seems kludgy to me, but
850 before you take it out, make sure that evaluating something like
851 (select-window (frame-root-window (new-frame))) doesn't end up
852 with your typing being interpreted in the new frame instead of
853 the one you're actually typing in. */
854 internal_last_event_frame = Qnil;
856 return frame;
859 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
860 doc: /* Select FRAME.
861 Subsequent editing commands apply to its selected window.
862 Optional argument NORECORD means to neither change the order of
863 recently selected windows nor the buffer list.
865 The selection of FRAME lasts until the next time the user does
866 something to select a different frame, or until the next time
867 this function is called. If you are using a window system, the
868 previously selected frame may be restored as the selected frame
869 when returning to the command loop, because it still may have
870 the window system's input focus. On a text-only terminal, the
871 next redisplay will display FRAME.
873 This function returns FRAME, or nil if FRAME has been deleted. */)
874 (Lisp_Object frame, Lisp_Object norecord)
876 return do_switch_frame (frame, 1, 0, norecord);
880 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
881 doc: /* Handle a switch-frame event EVENT.
882 Switch-frame events are usually bound to this function.
883 A switch-frame event tells Emacs that the window manager has requested
884 that the user's events be directed to the frame mentioned in the event.
885 This function selects the selected window of the frame of EVENT.
887 If EVENT is frame object, handle it as if it were a switch-frame event
888 to that frame. */)
889 (Lisp_Object event)
891 /* Preserve prefix arg that the command loop just cleared. */
892 KVAR (current_kboard, Vprefix_arg) = Vcurrent_prefix_arg;
893 Frun_hooks (1, &Qmouse_leave_buffer_hook);
894 return do_switch_frame (event, 0, 0, Qnil);
897 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
898 doc: /* Return the frame that is now selected. */)
899 (void)
901 return selected_frame;
904 DEFUN ("frame-list", Fframe_list, Sframe_list,
905 0, 0, 0,
906 doc: /* Return a list of all live frames. */)
907 (void)
909 Lisp_Object frames;
910 frames = Fcopy_sequence (Vframe_list);
911 #ifdef HAVE_WINDOW_SYSTEM
912 if (FRAMEP (tip_frame))
913 frames = Fdelq (tip_frame, frames);
914 #endif
915 return frames;
918 /* Return the next frame in the frame list after FRAME.
919 If MINIBUF is nil, exclude minibuffer-only frames.
920 If MINIBUF is a window, include only its own frame
921 and any frame now using that window as the minibuffer.
922 If MINIBUF is `visible', include all visible frames.
923 If MINIBUF is 0, include all visible and iconified frames.
924 Otherwise, include all frames. */
926 static Lisp_Object
927 next_frame (Lisp_Object frame, Lisp_Object minibuf)
929 Lisp_Object tail;
930 int passed = 0;
932 /* There must always be at least one frame in Vframe_list. */
933 if (! CONSP (Vframe_list))
934 abort ();
936 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
937 forever. Forestall that. */
938 CHECK_LIVE_FRAME (frame);
940 while (1)
941 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
943 Lisp_Object f;
945 f = XCAR (tail);
947 if (passed
948 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
949 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
950 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
951 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
953 /* Decide whether this frame is eligible to be returned. */
955 /* If we've looped all the way around without finding any
956 eligible frames, return the original frame. */
957 if (EQ (f, frame))
958 return f;
960 /* Let minibuf decide if this frame is acceptable. */
961 if (NILP (minibuf))
963 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
964 return f;
966 else if (EQ (minibuf, Qvisible))
968 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
969 if (FRAME_VISIBLE_P (XFRAME (f)))
970 return f;
972 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
974 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
975 if (FRAME_VISIBLE_P (XFRAME (f))
976 || FRAME_ICONIFIED_P (XFRAME (f)))
977 return f;
979 else if (WINDOWP (minibuf))
981 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
982 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
983 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
984 FRAME_FOCUS_FRAME (XFRAME (f))))
985 return f;
987 else
988 return f;
991 if (EQ (frame, f))
992 passed++;
996 /* Return the previous frame in the frame list before FRAME.
997 If MINIBUF is nil, exclude minibuffer-only frames.
998 If MINIBUF is a window, include only its own frame
999 and any frame now using that window as the minibuffer.
1000 If MINIBUF is `visible', include all visible frames.
1001 If MINIBUF is 0, include all visible and iconified frames.
1002 Otherwise, include all frames. */
1004 static Lisp_Object
1005 prev_frame (Lisp_Object frame, Lisp_Object minibuf)
1007 Lisp_Object tail;
1008 Lisp_Object prev;
1010 /* There must always be at least one frame in Vframe_list. */
1011 if (! CONSP (Vframe_list))
1012 abort ();
1014 prev = Qnil;
1015 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1017 Lisp_Object f;
1019 f = XCAR (tail);
1020 if (!FRAMEP (f))
1021 abort ();
1023 if (EQ (frame, f) && !NILP (prev))
1024 return prev;
1026 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1027 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1028 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1029 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
1031 /* Decide whether this frame is eligible to be returned,
1032 according to minibuf. */
1033 if (NILP (minibuf))
1035 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1036 prev = f;
1038 else if (WINDOWP (minibuf))
1040 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1041 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1042 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1043 FRAME_FOCUS_FRAME (XFRAME (f))))
1044 prev = f;
1046 else if (EQ (minibuf, Qvisible))
1048 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1049 if (FRAME_VISIBLE_P (XFRAME (f)))
1050 prev = f;
1052 else if (XFASTINT (minibuf) == 0)
1054 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1055 if (FRAME_VISIBLE_P (XFRAME (f))
1056 || FRAME_ICONIFIED_P (XFRAME (f)))
1057 prev = f;
1059 else
1060 prev = f;
1064 /* We've scanned the entire list. */
1065 if (NILP (prev))
1066 /* We went through the whole frame list without finding a single
1067 acceptable frame. Return the original frame. */
1068 return frame;
1069 else
1070 /* There were no acceptable frames in the list before FRAME; otherwise,
1071 we would have returned directly from the loop. Since PREV is the last
1072 acceptable frame in the list, return it. */
1073 return prev;
1077 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1078 doc: /* Return the next frame in the frame list after FRAME.
1079 It considers only frames on the same terminal as FRAME.
1080 By default, skip minibuffer-only frames.
1081 If omitted, FRAME defaults to the selected frame.
1082 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1083 If MINIFRAME is a window, include only its own frame
1084 and any frame now using that window as the minibuffer.
1085 If MINIFRAME is `visible', include all visible frames.
1086 If MINIFRAME is 0, include all visible and iconified frames.
1087 Otherwise, include all frames. */)
1088 (Lisp_Object frame, Lisp_Object miniframe)
1090 if (NILP (frame))
1091 frame = selected_frame;
1093 CHECK_LIVE_FRAME (frame);
1094 return next_frame (frame, miniframe);
1097 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1098 doc: /* Return the previous frame in the frame list before FRAME.
1099 It considers only frames on the same terminal as FRAME.
1100 By default, skip minibuffer-only frames.
1101 If omitted, FRAME defaults to the selected frame.
1102 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1103 If MINIFRAME is a window, include only its own frame
1104 and any frame now using that window as the minibuffer.
1105 If MINIFRAME is `visible', include all visible frames.
1106 If MINIFRAME is 0, include all visible and iconified frames.
1107 Otherwise, include all frames. */)
1108 (Lisp_Object frame, Lisp_Object miniframe)
1110 if (NILP (frame))
1111 frame = selected_frame;
1112 CHECK_LIVE_FRAME (frame);
1113 return prev_frame (frame, miniframe);
1116 /* Return 1 if it is ok to delete frame F;
1117 0 if all frames aside from F are invisible.
1118 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1121 other_visible_frames (FRAME_PTR f)
1123 /* We know the selected frame is visible,
1124 so if F is some other frame, it can't be the sole visible one. */
1125 if (f == SELECTED_FRAME ())
1127 Lisp_Object frames;
1128 int count = 0;
1130 for (frames = Vframe_list;
1131 CONSP (frames);
1132 frames = XCDR (frames))
1134 Lisp_Object this;
1136 this = XCAR (frames);
1137 /* Verify that the frame's window still exists
1138 and we can still talk to it. And note any recent change
1139 in visibility. */
1140 #ifdef HAVE_WINDOW_SYSTEM
1141 if (FRAME_WINDOW_P (XFRAME (this)))
1143 x_sync (XFRAME (this));
1144 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1146 #endif
1148 if (FRAME_VISIBLE_P (XFRAME (this))
1149 || FRAME_ICONIFIED_P (XFRAME (this))
1150 /* Allow deleting the terminal frame when at least
1151 one X frame exists! */
1152 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1153 count++;
1155 return count > 1;
1157 return 1;
1160 DEFUN ("other-visible-frames-p", Fother_visible_frames_p, Sother_visible_frames_p, 0, 1, 0,
1161 doc: /* Return t if there are other visible frames beside FRAME.
1162 FRAME defaults to the selected frame. */)
1163 (Lisp_Object frame)
1165 if (NILP (frame))
1166 frame = selected_frame;
1167 CHECK_LIVE_FRAME (frame);
1168 return other_visible_frames (XFRAME (frame)) ? Qt : Qnil;
1171 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1172 unconditionally. x_connection_closed and delete_terminal use
1173 this. Any other value of FORCE implements the semantics
1174 described for Fdelete_frame. */
1175 Lisp_Object
1176 delete_frame (Lisp_Object frame, Lisp_Object force)
1177 /* If we use `register' here, gcc-4.0.2 on amd64 using
1178 -DUSE_LISP_UNION_TYPE complains further down that we're getting the
1179 address of `force'. Go figure. */
1182 struct frame *f;
1183 struct frame *sf = SELECTED_FRAME ();
1184 struct kboard *kb;
1186 int minibuffer_selected, tooltip_frame;
1188 if (EQ (frame, Qnil))
1190 f = sf;
1191 XSETFRAME (frame, f);
1193 else
1195 CHECK_FRAME (frame);
1196 f = XFRAME (frame);
1199 if (! FRAME_LIVE_P (f))
1200 return Qnil;
1202 if (NILP (force) && !other_visible_frames (f))
1203 error ("Attempt to delete the sole visible or iconified frame");
1205 /* x_connection_closed must have set FORCE to `noelisp' in order
1206 to delete the last frame, if it is gone. */
1207 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1208 error ("Attempt to delete the only frame");
1210 /* Does this frame have a minibuffer, and is it the surrogate
1211 minibuffer for any other frame? */
1212 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1214 Lisp_Object frames;
1216 for (frames = Vframe_list;
1217 CONSP (frames);
1218 frames = XCDR (frames))
1220 Lisp_Object this;
1221 this = XCAR (frames);
1223 if (! EQ (this, frame)
1224 && EQ (frame,
1225 WINDOW_FRAME (XWINDOW
1226 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1228 /* If we MUST delete this frame, delete the other first.
1229 But do this only if FORCE equals `noelisp'. */
1230 if (EQ (force, Qnoelisp))
1231 delete_frame (this, Qnoelisp);
1232 else
1233 error ("Attempt to delete a surrogate minibuffer frame");
1238 tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
1240 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1241 frame is a tooltip. FORCE is set to `noelisp' when handling
1242 a disconnect from the terminal, so we don't dare call Lisp
1243 code. */
1244 if (NILP (Vrun_hooks) || tooltip_frame)
1246 else if (EQ (force, Qnoelisp))
1247 pending_funcalls
1248 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1249 pending_funcalls);
1250 else
1252 #ifdef HAVE_X_WINDOWS
1253 /* Also, save clipboard to the the clipboard manager. */
1254 x_clipboard_manager_save_frame (frame);
1255 #endif
1257 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1260 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1261 if (! FRAME_LIVE_P (f))
1262 return Qnil;
1264 /* At this point, we are committed to deleting the frame.
1265 There is no more chance for errors to prevent it. */
1267 minibuffer_selected = EQ (minibuf_window, selected_window);
1269 /* Don't let the frame remain selected. */
1270 if (f == sf)
1272 Lisp_Object tail, frame1;
1274 /* Look for another visible frame on the same terminal. */
1275 frame1 = next_frame (frame, Qvisible);
1277 /* If there is none, find *some* other frame. */
1278 if (NILP (frame1) || EQ (frame1, frame))
1280 FOR_EACH_FRAME (tail, frame1)
1282 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1283 break;
1286 #ifdef NS_IMPL_COCOA
1287 else
1288 /* Under NS, there is no system mechanism for choosing a new
1289 window to get focus -- it is left to application code.
1290 So the portion of THIS application interfacing with NS
1291 needs to know about it. We call Fraise_frame, but the
1292 purpose is really to transfer focus. */
1293 Fraise_frame (frame1);
1294 #endif
1296 do_switch_frame (frame1, 0, 1, Qnil);
1297 sf = SELECTED_FRAME ();
1300 /* Don't allow minibuf_window to remain on a deleted frame. */
1301 if (EQ (f->minibuffer_window, minibuf_window))
1303 Fset_window_buffer (sf->minibuffer_window,
1304 XWINDOW (minibuf_window)->buffer, Qnil);
1305 minibuf_window = sf->minibuffer_window;
1307 /* If the dying minibuffer window was selected,
1308 select the new one. */
1309 if (minibuffer_selected)
1310 Fselect_window (minibuf_window, Qnil);
1313 /* Don't let echo_area_window to remain on a deleted frame. */
1314 if (EQ (f->minibuffer_window, echo_area_window))
1315 echo_area_window = sf->minibuffer_window;
1317 /* Clear any X selections for this frame. */
1318 #ifdef HAVE_X_WINDOWS
1319 if (FRAME_X_P (f))
1320 x_clear_frame_selections (f);
1321 #endif
1323 /* Free glyphs.
1324 This function must be called before the window tree of the
1325 frame is deleted because windows contain dynamically allocated
1326 memory. */
1327 free_glyphs (f);
1329 #ifdef HAVE_WINDOW_SYSTEM
1330 /* Give chance to each font driver to free a frame specific data. */
1331 font_update_drivers (f, Qnil);
1332 #endif
1334 /* Mark all the windows that used to be on FRAME as deleted, and then
1335 remove the reference to them. */
1336 delete_all_subwindows (f->root_window);
1337 f->root_window = Qnil;
1339 Vframe_list = Fdelq (frame, Vframe_list);
1340 FRAME_SET_VISIBLE (f, 0);
1342 /* Allow the vector of menu bar contents to be freed in the next
1343 garbage collection. The frame object itself may not be garbage
1344 collected until much later, because recent_keys and other data
1345 structures can still refer to it. */
1346 f->menu_bar_vector = Qnil;
1348 free_font_driver_list (f);
1349 xfree (f->namebuf);
1350 xfree (f->decode_mode_spec_buffer);
1351 xfree (FRAME_INSERT_COST (f));
1352 xfree (FRAME_DELETEN_COST (f));
1353 xfree (FRAME_INSERTN_COST (f));
1354 xfree (FRAME_DELETE_COST (f));
1355 xfree (FRAME_MESSAGE_BUF (f));
1357 /* Since some events are handled at the interrupt level, we may get
1358 an event for f at any time; if we zero out the frame's terminal
1359 now, then we may trip up the event-handling code. Instead, we'll
1360 promise that the terminal of the frame must be valid until we
1361 have called the window-system-dependent frame destruction
1362 routine. */
1364 if (FRAME_TERMINAL (f)->delete_frame_hook)
1365 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
1368 struct terminal *terminal = FRAME_TERMINAL (f);
1369 f->output_data.nothing = 0;
1370 f->terminal = 0; /* Now the frame is dead. */
1372 /* If needed, delete the terminal that this frame was on.
1373 (This must be done after the frame is killed.) */
1374 terminal->reference_count--;
1375 if (terminal->reference_count == 0)
1377 Lisp_Object tmp;
1378 XSETTERMINAL (tmp, terminal);
1380 kb = NULL;
1381 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
1383 else
1384 kb = terminal->kboard;
1387 /* If we've deleted the last_nonminibuf_frame, then try to find
1388 another one. */
1389 if (f == last_nonminibuf_frame)
1391 Lisp_Object frames;
1393 last_nonminibuf_frame = 0;
1395 for (frames = Vframe_list;
1396 CONSP (frames);
1397 frames = XCDR (frames))
1399 f = XFRAME (XCAR (frames));
1400 if (!FRAME_MINIBUF_ONLY_P (f))
1402 last_nonminibuf_frame = f;
1403 break;
1408 /* If there's no other frame on the same kboard, get out of
1409 single-kboard state if we're in it for this kboard. */
1410 if (kb != NULL)
1412 Lisp_Object frames;
1413 /* Some frame we found on the same kboard, or nil if there are none. */
1414 Lisp_Object frame_on_same_kboard;
1416 frame_on_same_kboard = Qnil;
1418 for (frames = Vframe_list;
1419 CONSP (frames);
1420 frames = XCDR (frames))
1422 Lisp_Object this;
1423 struct frame *f1;
1425 this = XCAR (frames);
1426 if (!FRAMEP (this))
1427 abort ();
1428 f1 = XFRAME (this);
1430 if (kb == FRAME_KBOARD (f1))
1431 frame_on_same_kboard = this;
1434 if (NILP (frame_on_same_kboard))
1435 not_single_kboard_state (kb);
1439 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1440 find another one. Prefer minibuffer-only frames, but also notice
1441 frames with other windows. */
1442 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1444 Lisp_Object frames;
1446 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1447 Lisp_Object frame_with_minibuf;
1448 /* Some frame we found on the same kboard, or nil if there are none. */
1449 Lisp_Object frame_on_same_kboard;
1451 frame_on_same_kboard = Qnil;
1452 frame_with_minibuf = Qnil;
1454 for (frames = Vframe_list;
1455 CONSP (frames);
1456 frames = XCDR (frames))
1458 Lisp_Object this;
1459 struct frame *f1;
1461 this = XCAR (frames);
1462 if (!FRAMEP (this))
1463 abort ();
1464 f1 = XFRAME (this);
1466 /* Consider only frames on the same kboard
1467 and only those with minibuffers. */
1468 if (kb == FRAME_KBOARD (f1)
1469 && FRAME_HAS_MINIBUF_P (f1))
1471 frame_with_minibuf = this;
1472 if (FRAME_MINIBUF_ONLY_P (f1))
1473 break;
1476 if (kb == FRAME_KBOARD (f1))
1477 frame_on_same_kboard = this;
1480 if (!NILP (frame_on_same_kboard))
1482 /* We know that there must be some frame with a minibuffer out
1483 there. If this were not true, all of the frames present
1484 would have to be minibufferless, which implies that at some
1485 point their minibuffer frames must have been deleted, but
1486 that is prohibited at the top; you can't delete surrogate
1487 minibuffer frames. */
1488 if (NILP (frame_with_minibuf))
1489 abort ();
1491 KVAR (kb, Vdefault_minibuffer_frame) = frame_with_minibuf;
1493 else
1494 /* No frames left on this kboard--say no minibuffer either. */
1495 KVAR (kb, Vdefault_minibuffer_frame) = Qnil;
1498 /* Cause frame titles to update--necessary if we now have just one frame. */
1499 if (!tooltip_frame)
1500 update_mode_lines = 1;
1502 return Qnil;
1505 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1506 doc: /* Delete FRAME, permanently eliminating it from use.
1507 FRAME defaults to the selected frame.
1509 A frame may not be deleted if its minibuffer is used by other frames.
1510 Normally, you may not delete a frame if all other frames are invisible,
1511 but if the second optional argument FORCE is non-nil, you may do so.
1513 This function runs `delete-frame-functions' before actually
1514 deleting the frame, unless the frame is a tooltip.
1515 The functions are run with one argument, the frame to be deleted. */)
1516 (Lisp_Object frame, Lisp_Object force)
1518 return delete_frame (frame, !NILP (force) ? Qt : Qnil);
1522 /* Return mouse position in character cell units. */
1524 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1525 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1526 The position is given in character cells, where (0, 0) is the
1527 upper-left corner of the frame, X is the horizontal offset, and Y is
1528 the vertical offset.
1529 If Emacs is running on a mouseless terminal or hasn't been programmed
1530 to read the mouse position, it returns the selected frame for FRAME
1531 and nil for X and Y.
1532 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1533 passing the normal return value to that function as an argument,
1534 and returns whatever that function returns. */)
1535 (void)
1537 FRAME_PTR f;
1538 Lisp_Object lispy_dummy;
1539 enum scroll_bar_part party_dummy;
1540 Lisp_Object x, y, retval;
1541 int col, row;
1542 Time long_dummy;
1543 struct gcpro gcpro1;
1545 f = SELECTED_FRAME ();
1546 x = y = Qnil;
1548 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1549 /* It's okay for the hook to refrain from storing anything. */
1550 if (FRAME_TERMINAL (f)->mouse_position_hook)
1551 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1552 &lispy_dummy, &party_dummy,
1553 &x, &y,
1554 &long_dummy);
1555 if (! NILP (x))
1557 col = XINT (x);
1558 row = XINT (y);
1559 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1560 XSETINT (x, col);
1561 XSETINT (y, row);
1563 #endif
1564 XSETFRAME (lispy_dummy, f);
1565 retval = Fcons (lispy_dummy, Fcons (x, y));
1566 GCPRO1 (retval);
1567 if (!NILP (Vmouse_position_function))
1568 retval = call1 (Vmouse_position_function, retval);
1569 RETURN_UNGCPRO (retval);
1572 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1573 Smouse_pixel_position, 0, 0, 0,
1574 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1575 The position is given in pixel units, where (0, 0) is the
1576 upper-left corner of the frame, X is the horizontal offset, and Y is
1577 the vertical offset.
1578 If Emacs is running on a mouseless terminal or hasn't been programmed
1579 to read the mouse position, it returns the selected frame for FRAME
1580 and nil for X and Y. */)
1581 (void)
1583 FRAME_PTR f;
1584 Lisp_Object lispy_dummy;
1585 enum scroll_bar_part party_dummy;
1586 Lisp_Object x, y;
1587 Time long_dummy;
1589 f = SELECTED_FRAME ();
1590 x = y = Qnil;
1592 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1593 /* It's okay for the hook to refrain from storing anything. */
1594 if (FRAME_TERMINAL (f)->mouse_position_hook)
1595 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1596 &lispy_dummy, &party_dummy,
1597 &x, &y,
1598 &long_dummy);
1599 #endif
1600 XSETFRAME (lispy_dummy, f);
1601 return Fcons (lispy_dummy, Fcons (x, y));
1604 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1605 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1606 Coordinates are relative to the frame, not a window,
1607 so the coordinates of the top left character in the frame
1608 may be nonzero due to left-hand scroll bars or the menu bar.
1610 The position is given in character cells, where (0, 0) is the
1611 upper-left corner of the frame, X is the horizontal offset, and Y is
1612 the vertical offset.
1614 This function is a no-op for an X frame that is not visible.
1615 If you have just created a frame, you must wait for it to become visible
1616 before calling this function on it, like this.
1617 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1618 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1620 CHECK_LIVE_FRAME (frame);
1621 CHECK_NUMBER (x);
1622 CHECK_NUMBER (y);
1624 /* I think this should be done with a hook. */
1625 #ifdef HAVE_WINDOW_SYSTEM
1626 if (FRAME_WINDOW_P (XFRAME (frame)))
1627 /* Warping the mouse will cause enternotify and focus events. */
1628 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1629 #else
1630 #if defined (MSDOS) && defined (HAVE_MOUSE)
1631 if (FRAME_MSDOS_P (XFRAME (frame)))
1633 Fselect_frame (frame, Qnil);
1634 mouse_moveto (XINT (x), XINT (y));
1636 #else
1637 #ifdef HAVE_GPM
1639 Fselect_frame (frame, Qnil);
1640 term_mouse_moveto (XINT (x), XINT (y));
1642 #endif
1643 #endif
1644 #endif
1646 return Qnil;
1649 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1650 Sset_mouse_pixel_position, 3, 3, 0,
1651 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1652 The position is given in pixels, where (0, 0) is the upper-left corner
1653 of the frame, X is the horizontal offset, and Y is the vertical offset.
1655 Note, this is a no-op for an X frame that is not visible.
1656 If you have just created a frame, you must wait for it to become visible
1657 before calling this function on it, like this.
1658 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1659 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1661 CHECK_LIVE_FRAME (frame);
1662 CHECK_NUMBER (x);
1663 CHECK_NUMBER (y);
1665 /* I think this should be done with a hook. */
1666 #ifdef HAVE_WINDOW_SYSTEM
1667 if (FRAME_WINDOW_P (XFRAME (frame)))
1668 /* Warping the mouse will cause enternotify and focus events. */
1669 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1670 #else
1671 #if defined (MSDOS) && defined (HAVE_MOUSE)
1672 if (FRAME_MSDOS_P (XFRAME (frame)))
1674 Fselect_frame (frame, Qnil);
1675 mouse_moveto (XINT (x), XINT (y));
1677 #else
1678 #ifdef HAVE_GPM
1680 Fselect_frame (frame, Qnil);
1681 term_mouse_moveto (XINT (x), XINT (y));
1683 #endif
1684 #endif
1685 #endif
1687 return Qnil;
1690 static void make_frame_visible_1 (Lisp_Object);
1692 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1693 0, 1, "",
1694 doc: /* Make the frame FRAME visible (assuming it is an X window).
1695 If omitted, FRAME defaults to the currently selected frame. */)
1696 (Lisp_Object frame)
1698 if (NILP (frame))
1699 frame = selected_frame;
1701 CHECK_LIVE_FRAME (frame);
1703 /* I think this should be done with a hook. */
1704 #ifdef HAVE_WINDOW_SYSTEM
1705 if (FRAME_WINDOW_P (XFRAME (frame)))
1707 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1708 x_make_frame_visible (XFRAME (frame));
1710 #endif
1712 make_frame_visible_1 (XFRAME (frame)->root_window);
1714 /* Make menu bar update for the Buffers and Frames menus. */
1715 windows_or_buffers_changed++;
1717 return frame;
1720 /* Update the display_time slot of the buffers shown in WINDOW
1721 and all its descendents. */
1723 static void
1724 make_frame_visible_1 (Lisp_Object window)
1726 struct window *w;
1728 for (;!NILP (window); window = w->next)
1730 w = XWINDOW (window);
1732 if (!NILP (w->buffer))
1733 BVAR (XBUFFER (w->buffer), display_time) = Fcurrent_time ();
1735 if (!NILP (w->vchild))
1736 make_frame_visible_1 (w->vchild);
1737 if (!NILP (w->hchild))
1738 make_frame_visible_1 (w->hchild);
1742 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1743 0, 2, "",
1744 doc: /* Make the frame FRAME invisible.
1745 If omitted, FRAME defaults to the currently selected frame.
1746 On graphical displays, invisible frames are not updated and are
1747 usually not displayed at all, even in a window system's \"taskbar\".
1749 Normally you may not make FRAME invisible if all other frames are invisible,
1750 but if the second optional argument FORCE is non-nil, you may do so.
1752 This function has no effect on text-only terminal frames. Such frames
1753 are always considered visible, whether or not they are currently being
1754 displayed in the terminal. */)
1755 (Lisp_Object frame, Lisp_Object force)
1757 if (NILP (frame))
1758 frame = selected_frame;
1760 CHECK_LIVE_FRAME (frame);
1762 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1763 error ("Attempt to make invisible the sole visible or iconified frame");
1765 #if 0 /* This isn't logically necessary, and it can do GC. */
1766 /* Don't let the frame remain selected. */
1767 if (EQ (frame, selected_frame))
1768 do_switch_frame (next_frame (frame, Qt), 0, 0, Qnil)
1769 #endif
1771 /* Don't allow minibuf_window to remain on a deleted frame. */
1772 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1774 struct frame *sf = XFRAME (selected_frame);
1775 Fset_window_buffer (sf->minibuffer_window,
1776 XWINDOW (minibuf_window)->buffer, Qnil);
1777 minibuf_window = sf->minibuffer_window;
1780 /* I think this should be done with a hook. */
1781 #ifdef HAVE_WINDOW_SYSTEM
1782 if (FRAME_WINDOW_P (XFRAME (frame)))
1783 x_make_frame_invisible (XFRAME (frame));
1784 #endif
1786 /* Make menu bar update for the Buffers and Frames menus. */
1787 windows_or_buffers_changed++;
1789 return Qnil;
1792 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1793 0, 1, "",
1794 doc: /* Make the frame FRAME into an icon.
1795 If omitted, FRAME defaults to the currently selected frame. */)
1796 (Lisp_Object frame)
1798 if (NILP (frame))
1799 frame = selected_frame;
1801 CHECK_LIVE_FRAME (frame);
1803 #if 0 /* This isn't logically necessary, and it can do GC. */
1804 /* Don't let the frame remain selected. */
1805 if (EQ (frame, selected_frame))
1806 Fhandle_switch_frame (next_frame (frame, Qt));
1807 #endif
1809 /* Don't allow minibuf_window to remain on a deleted frame. */
1810 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1812 struct frame *sf = XFRAME (selected_frame);
1813 Fset_window_buffer (sf->minibuffer_window,
1814 XWINDOW (minibuf_window)->buffer, Qnil);
1815 minibuf_window = sf->minibuffer_window;
1818 /* I think this should be done with a hook. */
1819 #ifdef HAVE_WINDOW_SYSTEM
1820 if (FRAME_WINDOW_P (XFRAME (frame)))
1821 x_iconify_frame (XFRAME (frame));
1822 #endif
1824 /* Make menu bar update for the Buffers and Frames menus. */
1825 windows_or_buffers_changed++;
1827 return Qnil;
1830 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1831 1, 1, 0,
1832 doc: /* Return t if FRAME is \"visible\" (actually in use for display).
1833 Return the symbol `icon' if FRAME is iconified or \"minimized\".
1834 Return nil if FRAME was made invisible, via `make-frame-invisible'.
1835 On graphical displays, invisible frames are not updated and are
1836 usually not displayed at all, even in a window system's \"taskbar\".
1838 If FRAME is a text-only terminal frame, this always returns t.
1839 Such frames are always considered visible, whether or not they are
1840 currently being displayed on the terminal. */)
1841 (Lisp_Object frame)
1843 CHECK_LIVE_FRAME (frame);
1845 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1847 if (FRAME_VISIBLE_P (XFRAME (frame)))
1848 return Qt;
1849 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1850 return Qicon;
1851 return Qnil;
1854 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1855 0, 0, 0,
1856 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1857 (void)
1859 Lisp_Object tail, frame;
1860 struct frame *f;
1861 Lisp_Object value;
1863 value = Qnil;
1864 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1866 frame = XCAR (tail);
1867 if (!FRAMEP (frame))
1868 continue;
1869 f = XFRAME (frame);
1870 if (FRAME_VISIBLE_P (f))
1871 value = Fcons (frame, value);
1873 return value;
1877 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1878 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
1879 If FRAME is invisible or iconified, make it visible.
1880 If you don't specify a frame, the selected frame is used.
1881 If Emacs is displaying on an ordinary terminal or some other device which
1882 doesn't support multiple overlapping frames, this function selects FRAME. */)
1883 (Lisp_Object frame)
1885 struct frame *f;
1886 if (NILP (frame))
1887 frame = selected_frame;
1889 CHECK_LIVE_FRAME (frame);
1891 f = XFRAME (frame);
1893 if (FRAME_TERMCAP_P (f))
1894 /* On a text-only terminal select FRAME. */
1895 Fselect_frame (frame, Qnil);
1896 else
1897 /* Do like the documentation says. */
1898 Fmake_frame_visible (frame);
1900 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1901 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
1903 return Qnil;
1906 /* Should we have a corresponding function called Flower_Power? */
1907 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1908 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
1909 If you don't specify a frame, the selected frame is used.
1910 If Emacs is displaying on an ordinary terminal or some other device which
1911 doesn't support multiple overlapping frames, this function does nothing. */)
1912 (Lisp_Object frame)
1914 struct frame *f;
1916 if (NILP (frame))
1917 frame = selected_frame;
1919 CHECK_LIVE_FRAME (frame);
1921 f = XFRAME (frame);
1923 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1924 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
1926 return Qnil;
1930 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1931 1, 2, 0,
1932 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
1933 In other words, switch-frame events caused by events in FRAME will
1934 request a switch to FOCUS-FRAME, and `last-event-frame' will be
1935 FOCUS-FRAME after reading an event typed at FRAME.
1937 If FOCUS-FRAME is omitted or nil, any existing redirection is
1938 cancelled, and the frame again receives its own keystrokes.
1940 Focus redirection is useful for temporarily redirecting keystrokes to
1941 a surrogate minibuffer frame when a frame doesn't have its own
1942 minibuffer window.
1944 A frame's focus redirection can be changed by `select-frame'. If frame
1945 FOO is selected, and then a different frame BAR is selected, any
1946 frames redirecting their focus to FOO are shifted to redirect their
1947 focus to BAR. This allows focus redirection to work properly when the
1948 user switches from one frame to another using `select-window'.
1950 This means that a frame whose focus is redirected to itself is treated
1951 differently from a frame whose focus is redirected to nil; the former
1952 is affected by `select-frame', while the latter is not.
1954 The redirection lasts until `redirect-frame-focus' is called to change it. */)
1955 (Lisp_Object frame, Lisp_Object focus_frame)
1957 struct frame *f;
1959 /* Note that we don't check for a live frame here. It's reasonable
1960 to redirect the focus of a frame you're about to delete, if you
1961 know what other frame should receive those keystrokes. */
1962 CHECK_FRAME (frame);
1964 if (! NILP (focus_frame))
1965 CHECK_LIVE_FRAME (focus_frame);
1967 f = XFRAME (frame);
1969 f->focus_frame = focus_frame;
1971 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
1972 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
1974 return Qnil;
1978 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1979 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
1980 This returns nil if FRAME's focus is not redirected.
1981 See `redirect-frame-focus'. */)
1982 (Lisp_Object frame)
1984 CHECK_LIVE_FRAME (frame);
1986 return FRAME_FOCUS_FRAME (XFRAME (frame));
1991 /* Return the value of frame parameter PROP in frame FRAME. */
1993 #if !HAVE_NS
1994 static
1995 #endif
1996 Lisp_Object
1997 get_frame_param (register struct frame *frame, Lisp_Object prop)
1999 register Lisp_Object tem;
2001 tem = Fassq (prop, frame->param_alist);
2002 if (EQ (tem, Qnil))
2003 return tem;
2004 return Fcdr (tem);
2007 /* Return the buffer-predicate of the selected frame. */
2009 Lisp_Object
2010 frame_buffer_predicate (Lisp_Object frame)
2012 return XFRAME (frame)->buffer_predicate;
2015 /* Return the buffer-list of the selected frame. */
2017 Lisp_Object
2018 frame_buffer_list (Lisp_Object frame)
2020 return XFRAME (frame)->buffer_list;
2023 /* Set the buffer-list of the selected frame. */
2025 void
2026 set_frame_buffer_list (Lisp_Object frame, Lisp_Object list)
2028 XFRAME (frame)->buffer_list = list;
2031 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2033 void
2034 frames_discard_buffer (Lisp_Object buffer)
2036 Lisp_Object frame, tail;
2038 FOR_EACH_FRAME (tail, frame)
2040 XFRAME (frame)->buffer_list
2041 = Fdelq (buffer, XFRAME (frame)->buffer_list);
2042 XFRAME (frame)->buried_buffer_list
2043 = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
2047 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2048 If the alist already has an element for PROP, we change it. */
2050 void
2051 store_in_alist (Lisp_Object *alistptr, Lisp_Object prop, Lisp_Object val)
2053 register Lisp_Object tem;
2055 tem = Fassq (prop, *alistptr);
2056 if (EQ (tem, Qnil))
2057 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2058 else
2059 Fsetcdr (tem, val);
2062 static int
2063 frame_name_fnn_p (char *str, EMACS_INT len)
2065 if (len > 1 && str[0] == 'F' && '0' <= str[1] && str[1] <= '9')
2067 char *p = str + 2;
2068 while ('0' <= *p && *p <= '9')
2069 p++;
2070 if (p == str + len)
2071 return 1;
2073 return 0;
2076 /* Set the name of the terminal frame. Also used by MSDOS frames.
2077 Modeled after x_set_name which is used for WINDOW frames. */
2079 static void
2080 set_term_frame_name (struct frame *f, Lisp_Object name)
2082 f->explicit_name = ! NILP (name);
2084 /* If NAME is nil, set the name to F<num>. */
2085 if (NILP (name))
2087 char namebuf[20];
2089 /* Check for no change needed in this very common case
2090 before we do any consing. */
2091 if (frame_name_fnn_p (SSDATA (f->name),
2092 SBYTES (f->name)))
2093 return;
2095 tty_frame_count++;
2096 sprintf (namebuf, "F%d", tty_frame_count);
2097 name = build_string (namebuf);
2099 else
2101 CHECK_STRING (name);
2103 /* Don't change the name if it's already NAME. */
2104 if (! NILP (Fstring_equal (name, f->name)))
2105 return;
2107 /* Don't allow the user to set the frame name to F<num>, so it
2108 doesn't clash with the names we generate for terminal frames. */
2109 if (frame_name_fnn_p (SSDATA (name), SBYTES (name)))
2110 error ("Frame names of the form F<num> are usurped by Emacs");
2113 f->name = name;
2114 update_mode_lines = 1;
2117 void
2118 store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
2120 register Lisp_Object old_alist_elt;
2122 /* The buffer-list parameters are stored in a special place and not
2123 in the alist. */
2124 if (EQ (prop, Qbuffer_list))
2126 f->buffer_list = val;
2127 return;
2129 if (EQ (prop, Qburied_buffer_list))
2131 f->buried_buffer_list = val;
2132 return;
2135 /* If PROP is a symbol which is supposed to have frame-local values,
2136 and it is set up based on this frame, switch to the global
2137 binding. That way, we can create or alter the frame-local binding
2138 without messing up the symbol's status. */
2139 if (SYMBOLP (prop))
2141 struct Lisp_Symbol *sym = XSYMBOL (prop);
2142 start:
2143 switch (sym->redirect)
2145 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2146 case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
2147 case SYMBOL_LOCALIZED:
2148 { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
2149 if (blv->frame_local && BLV_FOUND (blv) && XFRAME (blv->where) == f)
2150 swap_in_global_binding (sym);
2151 break;
2153 default: abort ();
2157 /* The tty color needed to be set before the frame's parameter
2158 alist was updated with the new value. This is not true any more,
2159 but we still do this test early on. */
2160 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2161 && f == FRAME_TTY (f)->previous_frame)
2162 /* Force redisplay of this tty. */
2163 FRAME_TTY (f)->previous_frame = NULL;
2165 /* Update the frame parameter alist. */
2166 old_alist_elt = Fassq (prop, f->param_alist);
2167 if (EQ (old_alist_elt, Qnil))
2168 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
2169 else
2170 Fsetcdr (old_alist_elt, val);
2172 /* Update some other special parameters in their special places
2173 in addition to the alist. */
2175 if (EQ (prop, Qbuffer_predicate))
2176 f->buffer_predicate = val;
2178 if (! FRAME_WINDOW_P (f))
2180 if (EQ (prop, Qmenu_bar_lines))
2181 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2182 else if (EQ (prop, Qname))
2183 set_term_frame_name (f, val);
2186 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2188 if (! MINI_WINDOW_P (XWINDOW (val)))
2189 error ("Surrogate minibuffer windows must be minibuffer windows");
2191 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2192 && !EQ (val, f->minibuffer_window))
2193 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2195 /* Install the chosen minibuffer window, with proper buffer. */
2196 f->minibuffer_window = val;
2200 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2201 doc: /* Return the parameters-alist of frame FRAME.
2202 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2203 The meaningful PARMs depend on the kind of frame.
2204 If FRAME is omitted, return information on the currently selected frame. */)
2205 (Lisp_Object frame)
2207 Lisp_Object alist;
2208 FRAME_PTR f;
2209 int height, width;
2210 struct gcpro gcpro1;
2212 if (NILP (frame))
2213 frame = selected_frame;
2215 CHECK_FRAME (frame);
2216 f = XFRAME (frame);
2218 if (!FRAME_LIVE_P (f))
2219 return Qnil;
2221 alist = Fcopy_alist (f->param_alist);
2222 GCPRO1 (alist);
2224 if (!FRAME_WINDOW_P (f))
2226 int fg = FRAME_FOREGROUND_PIXEL (f);
2227 int bg = FRAME_BACKGROUND_PIXEL (f);
2228 Lisp_Object elt;
2230 /* If the frame's parameter alist says the colors are
2231 unspecified and reversed, take the frame's background pixel
2232 for foreground and vice versa. */
2233 elt = Fassq (Qforeground_color, alist);
2234 if (CONSP (elt) && STRINGP (XCDR (elt)))
2236 if (strncmp (SSDATA (XCDR (elt)),
2237 unspecified_bg,
2238 SCHARS (XCDR (elt))) == 0)
2239 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2240 else if (strncmp (SSDATA (XCDR (elt)),
2241 unspecified_fg,
2242 SCHARS (XCDR (elt))) == 0)
2243 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2245 else
2246 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2247 elt = Fassq (Qbackground_color, alist);
2248 if (CONSP (elt) && STRINGP (XCDR (elt)))
2250 if (strncmp (SSDATA (XCDR (elt)),
2251 unspecified_fg,
2252 SCHARS (XCDR (elt))) == 0)
2253 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2254 else if (strncmp (SSDATA (XCDR (elt)),
2255 unspecified_bg,
2256 SCHARS (XCDR (elt))) == 0)
2257 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2259 else
2260 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2261 store_in_alist (&alist, intern ("font"),
2262 build_string (FRAME_MSDOS_P (f)
2263 ? "ms-dos"
2264 : FRAME_W32_P (f) ? "w32term"
2265 :"tty"));
2267 store_in_alist (&alist, Qname, f->name);
2268 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2269 store_in_alist (&alist, Qheight, make_number (height));
2270 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2271 store_in_alist (&alist, Qwidth, make_number (width));
2272 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2273 store_in_alist (&alist, Qminibuffer,
2274 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2275 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2276 : FRAME_MINIBUF_WINDOW (f)));
2277 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2278 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
2279 store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
2281 /* I think this should be done with a hook. */
2282 #ifdef HAVE_WINDOW_SYSTEM
2283 if (FRAME_WINDOW_P (f))
2284 x_report_frame_params (f, &alist);
2285 else
2286 #endif
2288 /* This ought to be correct in f->param_alist for an X frame. */
2289 Lisp_Object lines;
2290 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2291 store_in_alist (&alist, Qmenu_bar_lines, lines);
2294 UNGCPRO;
2295 return alist;
2299 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2300 doc: /* Return FRAME's value for parameter PARAMETER.
2301 If FRAME is nil, describe the currently selected frame. */)
2302 (Lisp_Object frame, Lisp_Object parameter)
2304 struct frame *f;
2305 Lisp_Object value;
2307 if (NILP (frame))
2308 frame = selected_frame;
2309 else
2310 CHECK_FRAME (frame);
2311 CHECK_SYMBOL (parameter);
2313 f = XFRAME (frame);
2314 value = Qnil;
2316 if (FRAME_LIVE_P (f))
2318 /* Avoid consing in frequent cases. */
2319 if (EQ (parameter, Qname))
2320 value = f->name;
2321 #ifdef HAVE_X_WINDOWS
2322 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2323 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2324 #endif /* HAVE_X_WINDOWS */
2325 else if (EQ (parameter, Qbackground_color)
2326 || EQ (parameter, Qforeground_color))
2328 value = Fassq (parameter, f->param_alist);
2329 if (CONSP (value))
2331 value = XCDR (value);
2332 /* Fframe_parameters puts the actual fg/bg color names,
2333 even if f->param_alist says otherwise. This is
2334 important when param_alist's notion of colors is
2335 "unspecified". We need to do the same here. */
2336 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2338 const char *color_name;
2339 EMACS_INT csz;
2341 if (EQ (parameter, Qbackground_color))
2343 color_name = SSDATA (value);
2344 csz = SCHARS (value);
2345 if (strncmp (color_name, unspecified_bg, csz) == 0)
2346 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2347 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2348 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2350 else if (EQ (parameter, Qforeground_color))
2352 color_name = SSDATA (value);
2353 csz = SCHARS (value);
2354 if (strncmp (color_name, unspecified_fg, csz) == 0)
2355 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2356 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2357 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2361 else
2362 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2364 else if (EQ (parameter, Qdisplay_type)
2365 || EQ (parameter, Qbackground_mode))
2366 value = Fcdr (Fassq (parameter, f->param_alist));
2367 else
2368 /* FIXME: Avoid this code path at all (as well as code duplication)
2369 by sharing more code with Fframe_parameters. */
2370 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2373 return value;
2377 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2378 Smodify_frame_parameters, 2, 2, 0,
2379 doc: /* Modify the parameters of frame FRAME according to ALIST.
2380 If FRAME is nil, it defaults to the selected frame.
2381 ALIST is an alist of parameters to change and their new values.
2382 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2383 The meaningful PARMs depend on the kind of frame.
2384 Undefined PARMs are ignored, but stored in the frame's parameter list
2385 so that `frame-parameters' will return them.
2387 The value of frame parameter FOO can also be accessed
2388 as a frame-local binding for the variable FOO, if you have
2389 enabled such bindings for that variable with `make-variable-frame-local'.
2390 Note that this functionality is obsolete as of Emacs 22.2, and its
2391 use is not recommended. Explicitly check for a frame-parameter instead. */)
2392 (Lisp_Object frame, Lisp_Object alist)
2394 FRAME_PTR f;
2395 register Lisp_Object tail, prop, val;
2397 if (EQ (frame, Qnil))
2398 frame = selected_frame;
2399 CHECK_LIVE_FRAME (frame);
2400 f = XFRAME (frame);
2402 /* I think this should be done with a hook. */
2403 #ifdef HAVE_WINDOW_SYSTEM
2404 if (FRAME_WINDOW_P (f))
2405 x_set_frame_parameters (f, alist);
2406 else
2407 #endif
2408 #ifdef MSDOS
2409 if (FRAME_MSDOS_P (f))
2410 IT_set_frame_parameters (f, alist);
2411 else
2412 #endif
2415 int length = XINT (Flength (alist));
2416 int i;
2417 Lisp_Object *parms
2418 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2419 Lisp_Object *values
2420 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2422 /* Extract parm names and values into those vectors. */
2424 i = 0;
2425 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2427 Lisp_Object elt;
2429 elt = XCAR (tail);
2430 parms[i] = Fcar (elt);
2431 values[i] = Fcdr (elt);
2432 i++;
2435 /* Now process them in reverse of specified order. */
2436 while (--i >= 0)
2438 prop = parms[i];
2439 val = values[i];
2440 store_frame_param (f, prop, val);
2442 /* Changing the background color might change the background
2443 mode, so that we have to load new defface specs.
2444 Call frame-set-background-mode to do that. */
2445 if (EQ (prop, Qbackground_color))
2446 call1 (Qframe_set_background_mode, frame);
2449 return Qnil;
2452 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2453 0, 1, 0,
2454 doc: /* Height in pixels of a line in the font in frame FRAME.
2455 If FRAME is omitted, the selected frame is used.
2456 For a terminal frame, the value is always 1. */)
2457 (Lisp_Object frame)
2459 struct frame *f;
2461 if (NILP (frame))
2462 frame = selected_frame;
2463 CHECK_FRAME (frame);
2464 f = XFRAME (frame);
2466 #ifdef HAVE_WINDOW_SYSTEM
2467 if (FRAME_WINDOW_P (f))
2468 return make_number (x_char_height (f));
2469 else
2470 #endif
2471 return make_number (1);
2475 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2476 0, 1, 0,
2477 doc: /* Width in pixels of characters in the font in frame FRAME.
2478 If FRAME is omitted, the selected frame is used.
2479 On a graphical screen, the width is the standard width of the default font.
2480 For a terminal screen, the value is always 1. */)
2481 (Lisp_Object frame)
2483 struct frame *f;
2485 if (NILP (frame))
2486 frame = selected_frame;
2487 CHECK_FRAME (frame);
2488 f = XFRAME (frame);
2490 #ifdef HAVE_WINDOW_SYSTEM
2491 if (FRAME_WINDOW_P (f))
2492 return make_number (x_char_width (f));
2493 else
2494 #endif
2495 return make_number (1);
2498 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2499 Sframe_pixel_height, 0, 1, 0,
2500 doc: /* Return a FRAME's height in pixels.
2501 If FRAME is omitted, the selected frame is used. The exact value
2502 of the result depends on the window-system and toolkit in use:
2504 In the Gtk+ version of Emacs, it includes only any window (including
2505 the minibuffer or eacho area), mode line, and header line. It does not
2506 include the tool bar or menu bar.
2508 With the Motif or Lucid toolkits, it also includes the tool bar (but
2509 not the menu bar).
2511 In a graphical version with no toolkit, it includes both the tool bar
2512 and menu bar.
2514 For a text-only terminal, it includes the menu bar. In this case, the
2515 result is really in characters rather than pixels (i.e., is identical
2516 to `frame-height'). */)
2517 (Lisp_Object frame)
2519 struct frame *f;
2521 if (NILP (frame))
2522 frame = selected_frame;
2523 CHECK_FRAME (frame);
2524 f = XFRAME (frame);
2526 #ifdef HAVE_WINDOW_SYSTEM
2527 if (FRAME_WINDOW_P (f))
2528 return make_number (x_pixel_height (f));
2529 else
2530 #endif
2531 return make_number (FRAME_LINES (f));
2534 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2535 Sframe_pixel_width, 0, 1, 0,
2536 doc: /* Return FRAME's width in pixels.
2537 For a terminal frame, the result really gives the width in characters.
2538 If FRAME is omitted, the selected frame is used. */)
2539 (Lisp_Object frame)
2541 struct frame *f;
2543 if (NILP (frame))
2544 frame = selected_frame;
2545 CHECK_FRAME (frame);
2546 f = XFRAME (frame);
2548 #ifdef HAVE_WINDOW_SYSTEM
2549 if (FRAME_WINDOW_P (f))
2550 return make_number (x_pixel_width (f));
2551 else
2552 #endif
2553 return make_number (FRAME_COLS (f));
2556 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
2557 Stool_bar_pixel_width, 0, 1, 0,
2558 doc: /* Return width in pixels of FRAME's tool bar.
2559 The result is greater than zero only when the tool bar is on the left
2560 or right side of FRAME. If FRAME is omitted, the selected frame is
2561 used. */)
2562 (Lisp_Object frame)
2564 struct frame *f;
2566 if (NILP (frame))
2567 frame = selected_frame;
2568 CHECK_FRAME (frame);
2569 f = XFRAME (frame);
2571 #ifdef FRAME_TOOLBAR_WIDTH
2572 if (FRAME_WINDOW_P (f))
2573 return make_number (FRAME_TOOLBAR_WIDTH (f));
2574 #endif
2575 return make_number (0);
2578 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2579 doc: /* Specify that the frame FRAME has LINES lines.
2580 Optional third arg non-nil means that redisplay should use LINES lines
2581 but that the idea of the actual height of the frame should not be changed. */)
2582 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
2584 register struct frame *f;
2586 CHECK_NUMBER (lines);
2587 if (NILP (frame))
2588 frame = selected_frame;
2589 CHECK_LIVE_FRAME (frame);
2590 f = XFRAME (frame);
2592 /* I think this should be done with a hook. */
2593 #ifdef HAVE_WINDOW_SYSTEM
2594 if (FRAME_WINDOW_P (f))
2596 if (XINT (lines) != FRAME_LINES (f))
2597 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
2598 do_pending_window_change (0);
2600 else
2601 #endif
2602 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2603 return Qnil;
2606 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2607 doc: /* Specify that the frame FRAME has COLS columns.
2608 Optional third arg non-nil means that redisplay should use COLS columns
2609 but that the idea of the actual width of the frame should not be changed. */)
2610 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
2612 register struct frame *f;
2613 CHECK_NUMBER (cols);
2614 if (NILP (frame))
2615 frame = selected_frame;
2616 CHECK_LIVE_FRAME (frame);
2617 f = XFRAME (frame);
2619 /* I think this should be done with a hook. */
2620 #ifdef HAVE_WINDOW_SYSTEM
2621 if (FRAME_WINDOW_P (f))
2623 if (XINT (cols) != FRAME_COLS (f))
2624 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
2625 do_pending_window_change (0);
2627 else
2628 #endif
2629 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2630 return Qnil;
2633 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2634 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2635 (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows)
2637 register struct frame *f;
2639 CHECK_LIVE_FRAME (frame);
2640 CHECK_NUMBER (cols);
2641 CHECK_NUMBER (rows);
2642 f = XFRAME (frame);
2644 /* I think this should be done with a hook. */
2645 #ifdef HAVE_WINDOW_SYSTEM
2646 if (FRAME_WINDOW_P (f))
2648 if (XINT (rows) != FRAME_LINES (f)
2649 || XINT (cols) != FRAME_COLS (f)
2650 || f->new_text_lines || f->new_text_cols)
2651 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2652 do_pending_window_change (0);
2654 else
2655 #endif
2656 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2658 return Qnil;
2661 DEFUN ("set-frame-position", Fset_frame_position,
2662 Sset_frame_position, 3, 3, 0,
2663 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2664 This is actually the position of the upper left corner of the frame.
2665 Negative values for XOFFSET or YOFFSET are interpreted relative to
2666 the rightmost or bottommost possible position (that stays within the screen). */)
2667 (Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset)
2669 register struct frame *f;
2671 CHECK_LIVE_FRAME (frame);
2672 CHECK_NUMBER (xoffset);
2673 CHECK_NUMBER (yoffset);
2674 f = XFRAME (frame);
2676 /* I think this should be done with a hook. */
2677 #ifdef HAVE_WINDOW_SYSTEM
2678 if (FRAME_WINDOW_P (f))
2679 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2680 #endif
2682 return Qt;
2686 /***********************************************************************
2687 Frame Parameters
2688 ***********************************************************************/
2690 /* Connect the frame-parameter names for X frames
2691 to the ways of passing the parameter values to the window system.
2693 The name of a parameter, as a Lisp symbol,
2694 has an `x-frame-parameter' property which is an integer in Lisp
2695 that is an index in this table. */
2697 struct frame_parm_table {
2698 const char *name;
2699 Lisp_Object *variable;
2702 static const struct frame_parm_table frame_parms[] =
2704 {"auto-raise", &Qauto_raise},
2705 {"auto-lower", &Qauto_lower},
2706 {"background-color", 0},
2707 {"border-color", &Qborder_color},
2708 {"border-width", &Qborder_width},
2709 {"cursor-color", &Qcursor_color},
2710 {"cursor-type", &Qcursor_type},
2711 {"font", 0},
2712 {"foreground-color", 0},
2713 {"icon-name", &Qicon_name},
2714 {"icon-type", &Qicon_type},
2715 {"internal-border-width", &Qinternal_border_width},
2716 {"menu-bar-lines", &Qmenu_bar_lines},
2717 {"mouse-color", &Qmouse_color},
2718 {"name", &Qname},
2719 {"scroll-bar-width", &Qscroll_bar_width},
2720 {"title", &Qtitle},
2721 {"unsplittable", &Qunsplittable},
2722 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2723 {"visibility", &Qvisibility},
2724 {"tool-bar-lines", &Qtool_bar_lines},
2725 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2726 {"scroll-bar-background", &Qscroll_bar_background},
2727 {"screen-gamma", &Qscreen_gamma},
2728 {"line-spacing", &Qline_spacing},
2729 {"left-fringe", &Qleft_fringe},
2730 {"right-fringe", &Qright_fringe},
2731 {"wait-for-wm", &Qwait_for_wm},
2732 {"fullscreen", &Qfullscreen},
2733 {"font-backend", &Qfont_backend},
2734 {"alpha", &Qalpha},
2735 {"sticky", &Qsticky},
2736 {"tool-bar-position", &Qtool_bar_position},
2739 #ifdef WINDOWSNT
2741 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2742 wanted positions of the WM window (not Emacs window).
2743 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2744 window (FRAME_X_WINDOW).
2747 void
2748 x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos)
2750 int newwidth = FRAME_COLS (f);
2751 int newheight = FRAME_LINES (f);
2752 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2754 *top_pos = f->top_pos;
2755 *left_pos = f->left_pos;
2757 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
2759 int ph;
2761 ph = x_display_pixel_height (dpyinfo);
2762 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2763 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2764 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2765 *top_pos = 0;
2768 if (f->want_fullscreen & FULLSCREEN_WIDTH)
2770 int pw;
2772 pw = x_display_pixel_width (dpyinfo);
2773 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2774 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2775 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2776 *left_pos = 0;
2779 *width = newwidth;
2780 *height = newheight;
2783 #endif /* WINDOWSNT */
2785 #ifdef HAVE_WINDOW_SYSTEM
2787 /* Change the parameters of frame F as specified by ALIST.
2788 If a parameter is not specially recognized, do nothing special;
2789 otherwise call the `x_set_...' function for that parameter.
2790 Except for certain geometry properties, always call store_frame_param
2791 to store the new value in the parameter alist. */
2793 void
2794 x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
2796 Lisp_Object tail;
2798 /* If both of these parameters are present, it's more efficient to
2799 set them both at once. So we wait until we've looked at the
2800 entire list before we set them. */
2801 int width, height;
2803 /* Same here. */
2804 Lisp_Object left, top;
2806 /* Same with these. */
2807 Lisp_Object icon_left, icon_top;
2809 /* Record in these vectors all the parms specified. */
2810 Lisp_Object *parms;
2811 Lisp_Object *values;
2812 size_t i, p;
2813 int left_no_change = 0, top_no_change = 0;
2814 int icon_left_no_change = 0, icon_top_no_change = 0;
2815 int size_changed = 0;
2816 struct gcpro gcpro1, gcpro2;
2818 i = 0;
2819 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2820 i++;
2822 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2823 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2825 /* Extract parm names and values into those vectors. */
2827 i = 0;
2828 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2830 Lisp_Object elt;
2832 elt = XCAR (tail);
2833 parms[i] = Fcar (elt);
2834 values[i] = Fcdr (elt);
2835 i++;
2837 /* TAIL and ALIST are not used again below here. */
2838 alist = tail = Qnil;
2840 GCPRO2 (*parms, *values);
2841 gcpro1.nvars = i;
2842 gcpro2.nvars = i;
2844 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2845 because their values appear in VALUES and strings are not valid. */
2846 top = left = Qunbound;
2847 icon_left = icon_top = Qunbound;
2849 /* Provide default values for HEIGHT and WIDTH. */
2850 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2851 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2853 /* Process foreground_color and background_color before anything else.
2854 They are independent of other properties, but other properties (e.g.,
2855 cursor_color) are dependent upon them. */
2856 /* Process default font as well, since fringe widths depends on it. */
2857 for (p = 0; p < i; p++)
2859 Lisp_Object prop, val;
2861 prop = parms[p];
2862 val = values[p];
2863 if (EQ (prop, Qforeground_color)
2864 || EQ (prop, Qbackground_color)
2865 || EQ (prop, Qfont))
2867 register Lisp_Object param_index, old_value;
2869 old_value = get_frame_param (f, prop);
2870 if (NILP (Fequal (val, old_value)))
2872 store_frame_param (f, prop, val);
2874 param_index = Fget (prop, Qx_frame_parameter);
2875 if (NATNUMP (param_index)
2876 && (XFASTINT (param_index)
2877 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2878 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2879 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2884 /* Now process them in reverse of specified order. */
2885 while (i-- != 0)
2887 Lisp_Object prop, val;
2889 prop = parms[i];
2890 val = values[i];
2892 if (EQ (prop, Qwidth) && NATNUMP (val))
2894 size_changed = 1;
2895 width = XFASTINT (val);
2897 else if (EQ (prop, Qheight) && NATNUMP (val))
2899 size_changed = 1;
2900 height = XFASTINT (val);
2902 else if (EQ (prop, Qtop))
2903 top = val;
2904 else if (EQ (prop, Qleft))
2905 left = val;
2906 else if (EQ (prop, Qicon_top))
2907 icon_top = val;
2908 else if (EQ (prop, Qicon_left))
2909 icon_left = val;
2910 else if (EQ (prop, Qforeground_color)
2911 || EQ (prop, Qbackground_color)
2912 || EQ (prop, Qfont))
2913 /* Processed above. */
2914 continue;
2915 else
2917 register Lisp_Object param_index, old_value;
2919 old_value = get_frame_param (f, prop);
2921 store_frame_param (f, prop, val);
2923 param_index = Fget (prop, Qx_frame_parameter);
2924 if (NATNUMP (param_index)
2925 && (XFASTINT (param_index)
2926 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2927 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2928 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2932 /* Don't die if just one of these was set. */
2933 if (EQ (left, Qunbound))
2935 left_no_change = 1;
2936 if (f->left_pos < 0)
2937 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
2938 else
2939 XSETINT (left, f->left_pos);
2941 if (EQ (top, Qunbound))
2943 top_no_change = 1;
2944 if (f->top_pos < 0)
2945 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
2946 else
2947 XSETINT (top, f->top_pos);
2950 /* If one of the icon positions was not set, preserve or default it. */
2951 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
2953 icon_left_no_change = 1;
2954 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
2955 if (NILP (icon_left))
2956 XSETINT (icon_left, 0);
2958 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
2960 icon_top_no_change = 1;
2961 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
2962 if (NILP (icon_top))
2963 XSETINT (icon_top, 0);
2966 /* Don't set these parameters unless they've been explicitly
2967 specified. The window might be mapped or resized while we're in
2968 this function, and we don't want to override that unless the lisp
2969 code has asked for it.
2971 Don't set these parameters unless they actually differ from the
2972 window's current parameters; the window may not actually exist
2973 yet. */
2975 Lisp_Object frame;
2977 check_frame_size (f, &height, &width);
2979 XSETFRAME (frame, f);
2981 if (size_changed
2982 && (width != FRAME_COLS (f)
2983 || height != FRAME_LINES (f)
2984 || f->new_text_lines || f->new_text_cols))
2985 Fset_frame_size (frame, make_number (width), make_number (height));
2987 if ((!NILP (left) || !NILP (top))
2988 && ! (left_no_change && top_no_change)
2989 && ! (NUMBERP (left) && XINT (left) == f->left_pos
2990 && NUMBERP (top) && XINT (top) == f->top_pos))
2992 int leftpos = 0;
2993 int toppos = 0;
2995 /* Record the signs. */
2996 f->size_hint_flags &= ~ (XNegative | YNegative);
2997 if (EQ (left, Qminus))
2998 f->size_hint_flags |= XNegative;
2999 else if (INTEGERP (left))
3001 leftpos = XINT (left);
3002 if (leftpos < 0)
3003 f->size_hint_flags |= XNegative;
3005 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3006 && CONSP (XCDR (left))
3007 && INTEGERP (XCAR (XCDR (left))))
3009 leftpos = - XINT (XCAR (XCDR (left)));
3010 f->size_hint_flags |= XNegative;
3012 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3013 && CONSP (XCDR (left))
3014 && INTEGERP (XCAR (XCDR (left))))
3016 leftpos = XINT (XCAR (XCDR (left)));
3019 if (EQ (top, Qminus))
3020 f->size_hint_flags |= YNegative;
3021 else if (INTEGERP (top))
3023 toppos = XINT (top);
3024 if (toppos < 0)
3025 f->size_hint_flags |= YNegative;
3027 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3028 && CONSP (XCDR (top))
3029 && INTEGERP (XCAR (XCDR (top))))
3031 toppos = - XINT (XCAR (XCDR (top)));
3032 f->size_hint_flags |= YNegative;
3034 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3035 && CONSP (XCDR (top))
3036 && INTEGERP (XCAR (XCDR (top))))
3038 toppos = XINT (XCAR (XCDR (top)));
3042 /* Store the numeric value of the position. */
3043 f->top_pos = toppos;
3044 f->left_pos = leftpos;
3046 f->win_gravity = NorthWestGravity;
3048 /* Actually set that position, and convert to absolute. */
3049 x_set_offset (f, leftpos, toppos, -1);
3052 if ((!NILP (icon_left) || !NILP (icon_top))
3053 && ! (icon_left_no_change && icon_top_no_change))
3054 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3057 UNGCPRO;
3061 /* Insert a description of internally-recorded parameters of frame X
3062 into the parameter alist *ALISTPTR that is to be given to the user.
3063 Only parameters that are specific to the X window system
3064 and whose values are not correctly recorded in the frame's
3065 param_alist need to be considered here. */
3067 void
3068 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
3070 char buf[16];
3071 Lisp_Object tem;
3073 /* Represent negative positions (off the top or left screen edge)
3074 in a way that Fmodify_frame_parameters will understand correctly. */
3075 XSETINT (tem, f->left_pos);
3076 if (f->left_pos >= 0)
3077 store_in_alist (alistptr, Qleft, tem);
3078 else
3079 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
3081 XSETINT (tem, f->top_pos);
3082 if (f->top_pos >= 0)
3083 store_in_alist (alistptr, Qtop, tem);
3084 else
3085 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
3087 store_in_alist (alistptr, Qborder_width,
3088 make_number (f->border_width));
3089 store_in_alist (alistptr, Qinternal_border_width,
3090 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
3091 store_in_alist (alistptr, Qleft_fringe,
3092 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
3093 store_in_alist (alistptr, Qright_fringe,
3094 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
3095 store_in_alist (alistptr, Qscroll_bar_width,
3096 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3097 ? make_number (0)
3098 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3099 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3100 /* nil means "use default width"
3101 for non-toolkit scroll bar.
3102 ruler-mode.el depends on this. */
3103 : Qnil));
3104 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
3105 store_in_alist (alistptr, Qwindow_id,
3106 build_string (buf));
3107 #ifdef HAVE_X_WINDOWS
3108 #ifdef USE_X_TOOLKIT
3109 /* Tooltip frame may not have this widget. */
3110 if (FRAME_X_OUTPUT (f)->widget)
3111 #endif
3112 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
3113 store_in_alist (alistptr, Qouter_window_id,
3114 build_string (buf));
3115 #endif
3116 store_in_alist (alistptr, Qicon_name, f->icon_name);
3117 FRAME_SAMPLE_VISIBILITY (f);
3118 store_in_alist (alistptr, Qvisibility,
3119 (FRAME_VISIBLE_P (f) ? Qt
3120 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3121 store_in_alist (alistptr, Qdisplay,
3122 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
3124 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
3125 tem = Qnil;
3126 else
3127 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
3128 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
3129 store_in_alist (alistptr, Qparent_id, tem);
3130 store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position);
3134 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3135 the previous value of that parameter, NEW_VALUE is the new value. */
3137 void
3138 x_set_fullscreen (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3140 if (NILP (new_value))
3141 f->want_fullscreen = FULLSCREEN_NONE;
3142 else if (EQ (new_value, Qfullboth) || EQ (new_value, Qfullscreen))
3143 f->want_fullscreen = FULLSCREEN_BOTH;
3144 else if (EQ (new_value, Qfullwidth))
3145 f->want_fullscreen = FULLSCREEN_WIDTH;
3146 else if (EQ (new_value, Qfullheight))
3147 f->want_fullscreen = FULLSCREEN_HEIGHT;
3148 else if (EQ (new_value, Qmaximized))
3149 f->want_fullscreen = FULLSCREEN_MAXIMIZED;
3151 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
3152 FRAME_TERMINAL (f)->fullscreen_hook (f);
3156 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3157 the previous value of that parameter, NEW_VALUE is the new value. */
3159 void
3160 x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3162 if (NILP (new_value))
3163 f->extra_line_spacing = 0;
3164 else if (NATNUMP (new_value))
3165 f->extra_line_spacing = XFASTINT (new_value);
3166 else
3167 signal_error ("Invalid line-spacing", new_value);
3168 if (FRAME_VISIBLE_P (f))
3169 redraw_frame (f);
3173 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3174 the previous value of that parameter, NEW_VALUE is the new value. */
3176 void
3177 x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3179 Lisp_Object bgcolor;
3181 if (NILP (new_value))
3182 f->gamma = 0;
3183 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3184 /* The value 0.4545 is the normal viewing gamma. */
3185 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3186 else
3187 signal_error ("Invalid screen-gamma", new_value);
3189 /* Apply the new gamma value to the frame background. */
3190 bgcolor = Fassq (Qbackground_color, f->param_alist);
3191 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3193 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
3194 if (NATNUMP (parm_index)
3195 && (XFASTINT (parm_index)
3196 < sizeof (frame_parms)/sizeof (frame_parms[0]))
3197 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3198 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3199 (f, bgcolor, Qnil);
3202 Fclear_face_cache (Qnil);
3206 void
3207 x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3209 Lisp_Object font_object, font_param = Qnil;
3210 int fontset = -1;
3212 /* Set the frame parameter back to the old value because we may
3213 fail to use ARG as the new parameter value. */
3214 store_frame_param (f, Qfont, oldval);
3216 /* ARG is a fontset name, a font name, a cons of fontset name and a
3217 font object, or a font object. In the last case, this function
3218 never fail. */
3219 if (STRINGP (arg))
3221 font_param = arg;
3222 fontset = fs_query_fontset (arg, 0);
3223 if (fontset < 0)
3225 font_object = font_open_by_name (f, SSDATA (arg));
3226 if (NILP (font_object))
3227 error ("Font `%s' is not defined", SSDATA (arg));
3228 arg = AREF (font_object, FONT_NAME_INDEX);
3230 else if (fontset > 0)
3232 Lisp_Object ascii_font = fontset_ascii (fontset);
3234 font_object = font_open_by_name (f, SSDATA (ascii_font));
3235 if (NILP (font_object))
3236 error ("Font `%s' is not defined", SDATA (arg));
3237 arg = AREF (font_object, FONT_NAME_INDEX);
3239 else
3240 error ("The default fontset can't be used for a frame font");
3242 else if (CONSP (arg) && STRINGP (XCAR (arg)) && FONT_OBJECT_P (XCDR (arg)))
3244 /* This is the case that the ASCII font of F's fontset XCAR
3245 (arg) is changed to the font XCDR (arg) by
3246 `set-fontset-font'. */
3247 fontset = fs_query_fontset (XCAR (arg), 0);
3248 if (fontset < 0)
3249 error ("Unknown fontset: %s", SDATA (XCAR (arg)));
3250 font_object = XCDR (arg);
3251 arg = AREF (font_object, FONT_NAME_INDEX);
3252 font_param = Ffont_get (font_object, QCname);
3254 else if (FONT_OBJECT_P (arg))
3256 font_object = arg;
3257 font_param = Ffont_get (font_object, QCname);
3258 /* This is to store the XLFD font name in the frame parameter for
3259 backward compatibility. We should store the font-object
3260 itself in the future. */
3261 arg = AREF (font_object, FONT_NAME_INDEX);
3262 fontset = FRAME_FONTSET (f);
3263 /* Check if we can use the current fontset. If not, set FONTSET
3264 to -1 to generate a new fontset from FONT-OBJECT. */
3265 if (fontset >= 0)
3267 Lisp_Object ascii_font = fontset_ascii (fontset);
3268 Lisp_Object spec = font_spec_from_name (ascii_font);
3270 if (! font_match_p (spec, font_object))
3271 fontset = -1;
3274 else
3275 signal_error ("Invalid font", arg);
3277 if (! NILP (Fequal (font_object, oldval)))
3278 return;
3280 x_new_font (f, font_object, fontset);
3281 store_frame_param (f, Qfont, arg);
3282 #ifdef HAVE_X_WINDOWS
3283 store_frame_param (f, Qfont_param, font_param);
3284 #endif
3285 /* Recalculate toolbar height. */
3286 f->n_tool_bar_rows = 0;
3287 /* Ensure we redraw it. */
3288 clear_current_matrices (f);
3290 recompute_basic_faces (f);
3292 do_pending_window_change (0);
3294 /* We used to call face-set-after-frame-default here, but it leads to
3295 recursive calls (since that function can set the `default' face's
3296 font which in turns changes the frame's `font' parameter).
3297 Also I don't know what this call is meant to do, but it seems the
3298 wrong way to do it anyway (it does a lot more work than what seems
3299 reasonable in response to a change to `font'). */
3303 void
3304 x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3306 if (! NILP (new_value)
3307 && !CONSP (new_value))
3309 char *p0, *p1;
3311 CHECK_STRING (new_value);
3312 p0 = p1 = SSDATA (new_value);
3313 new_value = Qnil;
3314 while (*p0)
3316 while (*p1 && ! isspace (*p1) && *p1 != ',') p1++;
3317 if (p0 < p1)
3318 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3319 new_value);
3320 if (*p1)
3322 int c;
3324 while ((c = *++p1) && isspace (c));
3326 p0 = p1;
3328 new_value = Fnreverse (new_value);
3331 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3332 return;
3334 if (FRAME_FONT (f))
3335 free_all_realized_faces (Qnil);
3337 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
3338 if (NILP (new_value))
3340 if (NILP (old_value))
3341 error ("No font backend available");
3342 font_update_drivers (f, old_value);
3343 error ("None of specified font backends are available");
3345 store_frame_param (f, Qfont_backend, new_value);
3347 if (FRAME_FONT (f))
3349 Lisp_Object frame;
3351 XSETFRAME (frame, f);
3352 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3353 ++face_change_count;
3354 ++windows_or_buffers_changed;
3359 void
3360 x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3362 compute_fringe_widths (f, 1);
3363 #ifdef HAVE_X_WINDOWS
3364 /* Must adjust this so window managers report correct number of columns. */
3365 if (FRAME_X_WINDOW (f) != 0)
3366 x_wm_set_size_hint (f, 0, 0);
3367 #endif
3370 void
3371 x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3373 CHECK_NUMBER (arg);
3375 if (XINT (arg) == f->border_width)
3376 return;
3378 if (FRAME_X_WINDOW (f) != 0)
3379 error ("Cannot change the border width of a frame");
3381 f->border_width = XINT (arg);
3384 void
3385 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3387 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
3389 CHECK_NUMBER (arg);
3390 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3391 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3392 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
3394 #ifdef USE_X_TOOLKIT
3395 if (FRAME_X_OUTPUT (f)->edit_widget)
3396 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3397 #endif
3399 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
3400 return;
3402 if (FRAME_X_WINDOW (f) != 0)
3404 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3405 SET_FRAME_GARBAGED (f);
3406 do_pending_window_change (0);
3408 else
3409 SET_FRAME_GARBAGED (f);
3412 void
3413 x_set_visibility (struct frame *f, Lisp_Object value, Lisp_Object oldval)
3415 Lisp_Object frame;
3416 XSETFRAME (frame, f);
3418 if (NILP (value))
3419 Fmake_frame_invisible (frame, Qt);
3420 else if (EQ (value, Qicon))
3421 Ficonify_frame (frame);
3422 else
3423 Fmake_frame_visible (frame);
3426 void
3427 x_set_autoraise (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3429 f->auto_raise = !EQ (Qnil, arg);
3432 void
3433 x_set_autolower (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3435 f->auto_lower = !EQ (Qnil, arg);
3438 void
3439 x_set_unsplittable (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3441 f->no_split = !NILP (arg);
3444 void
3445 x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3447 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3448 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3449 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3450 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3452 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3453 = (NILP (arg)
3454 ? vertical_scroll_bar_none
3455 : EQ (Qleft, arg)
3456 ? vertical_scroll_bar_left
3457 : EQ (Qright, arg)
3458 ? vertical_scroll_bar_right
3459 : EQ (Qleft, Vdefault_frame_scroll_bars)
3460 ? vertical_scroll_bar_left
3461 : EQ (Qright, Vdefault_frame_scroll_bars)
3462 ? vertical_scroll_bar_right
3463 : vertical_scroll_bar_none);
3465 /* We set this parameter before creating the X window for the
3466 frame, so we can get the geometry right from the start.
3467 However, if the window hasn't been created yet, we shouldn't
3468 call x_set_window_size. */
3469 if (FRAME_X_WINDOW (f))
3470 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3471 do_pending_window_change (0);
3475 void
3476 x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3478 int wid = FRAME_COLUMN_WIDTH (f);
3480 if (NILP (arg))
3482 x_set_scroll_bar_default_width (f);
3484 if (FRAME_X_WINDOW (f))
3485 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3486 do_pending_window_change (0);
3488 else if (INTEGERP (arg) && XINT (arg) > 0
3489 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3491 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3492 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3494 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3495 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3496 if (FRAME_X_WINDOW (f))
3497 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3498 do_pending_window_change (0);
3501 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
3502 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3503 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3508 /* Return non-nil if frame F wants a bitmap icon. */
3510 Lisp_Object
3511 x_icon_type (FRAME_PTR f)
3513 Lisp_Object tem;
3515 tem = assq_no_quit (Qicon_type, f->param_alist);
3516 if (CONSP (tem))
3517 return XCDR (tem);
3518 else
3519 return Qnil;
3522 void
3523 x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3525 double alpha = 1.0;
3526 double newval[2];
3527 int i, ialpha;
3528 Lisp_Object item;
3530 for (i = 0; i < 2; i++)
3532 newval[i] = 1.0;
3533 if (CONSP (arg))
3535 item = CAR (arg);
3536 arg = CDR (arg);
3538 else
3539 item = arg;
3541 if (NILP (item))
3542 alpha = - 1.0;
3543 else if (FLOATP (item))
3545 alpha = XFLOAT_DATA (item);
3546 if (alpha < 0.0 || 1.0 < alpha)
3547 args_out_of_range (make_float (0.0), make_float (1.0));
3549 else if (INTEGERP (item))
3551 ialpha = XINT (item);
3552 if (ialpha < 0 || 100 < ialpha)
3553 args_out_of_range (make_number (0), make_number (100));
3554 else
3555 alpha = ialpha / 100.0;
3557 else
3558 wrong_type_argument (Qnumberp, item);
3559 newval[i] = alpha;
3562 for (i = 0; i < 2; i++)
3563 f->alpha[i] = newval[i];
3565 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3566 BLOCK_INPUT;
3567 x_set_frame_alpha (f);
3568 UNBLOCK_INPUT;
3569 #endif
3571 return;
3575 /* Subroutines of creating an X frame. */
3577 /* Make sure that Vx_resource_name is set to a reasonable value.
3578 Fix it up, or set it to `emacs' if it is too hopeless. */
3580 void
3581 validate_x_resource_name (void)
3583 int len = 0;
3584 /* Number of valid characters in the resource name. */
3585 int good_count = 0;
3586 /* Number of invalid characters in the resource name. */
3587 int bad_count = 0;
3588 Lisp_Object new;
3589 int i;
3591 if (!STRINGP (Vx_resource_class))
3592 Vx_resource_class = build_string (EMACS_CLASS);
3594 if (STRINGP (Vx_resource_name))
3596 unsigned char *p = SDATA (Vx_resource_name);
3598 len = SBYTES (Vx_resource_name);
3600 /* Only letters, digits, - and _ are valid in resource names.
3601 Count the valid characters and count the invalid ones. */
3602 for (i = 0; i < len; i++)
3604 int c = p[i];
3605 if (! ((c >= 'a' && c <= 'z')
3606 || (c >= 'A' && c <= 'Z')
3607 || (c >= '0' && c <= '9')
3608 || c == '-' || c == '_'))
3609 bad_count++;
3610 else
3611 good_count++;
3614 else
3615 /* Not a string => completely invalid. */
3616 bad_count = 5, good_count = 0;
3618 /* If name is valid already, return. */
3619 if (bad_count == 0)
3620 return;
3622 /* If name is entirely invalid, or nearly so, use `emacs'. */
3623 if (good_count < 2)
3625 Vx_resource_name = build_string ("emacs");
3626 return;
3629 /* Name is partly valid. Copy it and replace the invalid characters
3630 with underscores. */
3632 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3634 for (i = 0; i < len; i++)
3636 int c = SREF (new, i);
3637 if (! ((c >= 'a' && c <= 'z')
3638 || (c >= 'A' && c <= 'Z')
3639 || (c >= '0' && c <= '9')
3640 || c == '-' || c == '_'))
3641 SSET (new, i, '_');
3646 extern char *x_get_string_resource (XrmDatabase, const char *, const char *);
3647 extern Display_Info *check_x_display_info (Lisp_Object);
3650 /* Get specified attribute from resource database RDB.
3651 See Fx_get_resource below for other parameters. */
3653 static Lisp_Object
3654 xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3656 register char *value;
3657 char *name_key;
3658 char *class_key;
3660 CHECK_STRING (attribute);
3661 CHECK_STRING (class);
3663 if (!NILP (component))
3664 CHECK_STRING (component);
3665 if (!NILP (subclass))
3666 CHECK_STRING (subclass);
3667 if (NILP (component) != NILP (subclass))
3668 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3670 validate_x_resource_name ();
3672 /* Allocate space for the components, the dots which separate them,
3673 and the final '\0'. Make them big enough for the worst case. */
3674 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3675 + (STRINGP (component)
3676 ? SBYTES (component) : 0)
3677 + SBYTES (attribute)
3678 + 3);
3680 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3681 + SBYTES (class)
3682 + (STRINGP (subclass)
3683 ? SBYTES (subclass) : 0)
3684 + 3);
3686 /* Start with emacs.FRAMENAME for the name (the specific one)
3687 and with `Emacs' for the class key (the general one). */
3688 strcpy (name_key, SSDATA (Vx_resource_name));
3689 strcpy (class_key, SSDATA (Vx_resource_class));
3691 strcat (class_key, ".");
3692 strcat (class_key, SSDATA (class));
3694 if (!NILP (component))
3696 strcat (class_key, ".");
3697 strcat (class_key, SSDATA (subclass));
3699 strcat (name_key, ".");
3700 strcat (name_key, SSDATA (component));
3703 strcat (name_key, ".");
3704 strcat (name_key, SSDATA (attribute));
3706 value = x_get_string_resource (rdb, name_key, class_key);
3708 if (value != (char *) 0 && *value)
3709 return build_string (value);
3710 else
3711 return Qnil;
3715 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3716 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3717 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3718 class, where INSTANCE is the name under which Emacs was invoked, or
3719 the name specified by the `-name' or `-rn' command-line arguments.
3721 The optional arguments COMPONENT and SUBCLASS add to the key and the
3722 class, respectively. You must specify both of them or neither.
3723 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3724 and the class is `Emacs.CLASS.SUBCLASS'. */)
3725 (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3727 #ifdef HAVE_X_WINDOWS
3728 check_x ();
3729 #endif
3731 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3732 attribute, class, component, subclass);
3735 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3737 Lisp_Object
3738 display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3740 return xrdb_get_resource (dpyinfo->xrdb,
3741 attribute, class, component, subclass);
3744 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
3745 /* Used when C code wants a resource value. */
3746 /* Called from oldXMenu/Create.c. */
3747 char *
3748 x_get_resource_string (const char *attribute, const char *class)
3750 char *name_key;
3751 char *class_key;
3752 struct frame *sf = SELECTED_FRAME ();
3754 /* Allocate space for the components, the dots which separate them,
3755 and the final '\0'. */
3756 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3757 + strlen (attribute) + 2);
3758 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3759 + strlen (class) + 2);
3761 sprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
3762 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3764 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3765 name_key, class_key);
3767 #endif
3769 /* Return the value of parameter PARAM.
3771 First search ALIST, then Vdefault_frame_alist, then the X defaults
3772 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3774 Convert the resource to the type specified by desired_type.
3776 If no default is specified, return Qunbound. If you call
3777 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3778 and don't let it get stored in any Lisp-visible variables! */
3780 Lisp_Object
3781 x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
3782 const char *attribute, const char *class, enum resource_types type)
3784 register Lisp_Object tem;
3786 tem = Fassq (param, alist);
3788 if (!NILP (tem))
3790 /* If we find this parm in ALIST, clear it out
3791 so that it won't be "left over" at the end. */
3792 Lisp_Object tail;
3793 XSETCAR (tem, Qnil);
3794 /* In case the parameter appears more than once in the alist,
3795 clear it out. */
3796 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3797 if (CONSP (XCAR (tail))
3798 && EQ (XCAR (XCAR (tail)), param))
3799 XSETCAR (XCAR (tail), Qnil);
3801 else
3802 tem = Fassq (param, Vdefault_frame_alist);
3804 /* If it wasn't specified in ALIST or the Lisp-level defaults,
3805 look in the X resources. */
3806 if (EQ (tem, Qnil))
3808 if (attribute && dpyinfo)
3810 tem = display_x_get_resource (dpyinfo,
3811 build_string (attribute),
3812 build_string (class),
3813 Qnil, Qnil);
3815 if (NILP (tem))
3816 return Qunbound;
3818 switch (type)
3820 case RES_TYPE_NUMBER:
3821 return make_number (atoi (SSDATA (tem)));
3823 case RES_TYPE_BOOLEAN_NUMBER:
3824 if (!strcmp (SSDATA (tem), "on")
3825 || !strcmp (SSDATA (tem), "true"))
3826 return make_number (1);
3827 return make_number (atoi (SSDATA (tem)));
3828 break;
3830 case RES_TYPE_FLOAT:
3831 return make_float (atof (SSDATA (tem)));
3833 case RES_TYPE_BOOLEAN:
3834 tem = Fdowncase (tem);
3835 if (!strcmp (SSDATA (tem), "on")
3836 #ifdef HAVE_NS
3837 || !strcmp (SSDATA (tem), "yes")
3838 #endif
3839 || !strcmp (SSDATA (tem), "true"))
3840 return Qt;
3841 else
3842 return Qnil;
3844 case RES_TYPE_STRING:
3845 return tem;
3847 case RES_TYPE_SYMBOL:
3848 /* As a special case, we map the values `true' and `on'
3849 to Qt, and `false' and `off' to Qnil. */
3851 Lisp_Object lower;
3852 lower = Fdowncase (tem);
3853 if (!strcmp (SSDATA (lower), "on")
3854 #ifdef HAVE_NS
3855 || !strcmp (SSDATA (lower), "yes")
3856 #endif
3857 || !strcmp (SSDATA (lower), "true"))
3858 return Qt;
3859 else if (!strcmp (SSDATA (lower), "off")
3860 #ifdef HAVE_NS
3861 || !strcmp (SSDATA (lower), "no")
3862 #endif
3863 || !strcmp (SSDATA (lower), "false"))
3864 return Qnil;
3865 else
3866 return Fintern (tem, Qnil);
3869 default:
3870 abort ();
3873 else
3874 return Qunbound;
3876 return Fcdr (tem);
3879 static Lisp_Object
3880 x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param,
3881 const char *attribute, const char *class,
3882 enum resource_types type)
3884 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3885 alist, param, attribute, class, type);
3888 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
3890 Lisp_Object
3891 x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist,
3892 Lisp_Object param,
3893 const char *attribute, const char *class,
3894 enum resource_types type)
3896 Lisp_Object value;
3898 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3899 attribute, class, type);
3900 if (! NILP (value) && ! EQ (value, Qunbound))
3901 store_frame_param (f, param, value);
3903 return value;
3907 /* Record in frame F the specified or default value according to ALIST
3908 of the parameter named PROP (a Lisp symbol).
3909 If no value is specified for PROP, look for an X default for XPROP
3910 on the frame named NAME.
3911 If that is not found either, use the value DEFLT. */
3913 Lisp_Object
3914 x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
3915 Lisp_Object deflt, const char *xprop, const char *xclass,
3916 enum resource_types type)
3918 Lisp_Object tem;
3920 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3921 if (EQ (tem, Qunbound))
3922 tem = deflt;
3923 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
3924 return tem;
3930 /* NS used to define x-parse-geometry in ns-win.el, but that confused
3931 make-docfile: the documentation string in ns-win.el was used for
3932 x-parse-geometry even in non-NS builds.
3934 With two definitions of x-parse-geometry in this file, various
3935 things still get confused (eg M-x apropos documentation), so that
3936 it is best if the two definitions just share the same doc-string.
3938 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
3939 doc: /* Parse a display geometry string STRING.
3940 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3941 The properties returned may include `top', `left', `height', and `width'.
3942 For X, the value of `left' or `top' may be an integer,
3943 or a list (+ N) meaning N pixels relative to top/left corner,
3944 or a list (- N) meaning -N pixels relative to bottom/right corner.
3945 On Nextstep, this just calls `ns-parse-geometry'. */)
3946 (Lisp_Object string)
3948 #ifdef HAVE_NS
3949 call1 (Qns_parse_geometry, string);
3950 #else
3951 int geometry, x, y;
3952 unsigned int width, height;
3953 Lisp_Object result;
3955 CHECK_STRING (string);
3957 geometry = XParseGeometry (SSDATA (string),
3958 &x, &y, &width, &height);
3959 result = Qnil;
3960 if (geometry & XValue)
3962 Lisp_Object element;
3964 if (x >= 0 && (geometry & XNegative))
3965 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
3966 else if (x < 0 && ! (geometry & XNegative))
3967 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
3968 else
3969 element = Fcons (Qleft, make_number (x));
3970 result = Fcons (element, result);
3973 if (geometry & YValue)
3975 Lisp_Object element;
3977 if (y >= 0 && (geometry & YNegative))
3978 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
3979 else if (y < 0 && ! (geometry & YNegative))
3980 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
3981 else
3982 element = Fcons (Qtop, make_number (y));
3983 result = Fcons (element, result);
3986 if (geometry & WidthValue)
3987 result = Fcons (Fcons (Qwidth, make_number (width)), result);
3988 if (geometry & HeightValue)
3989 result = Fcons (Fcons (Qheight, make_number (height)), result);
3991 return result;
3992 #endif /* HAVE_NS */
3996 /* Calculate the desired size and position of frame F.
3997 Return the flags saying which aspects were specified.
3999 Also set the win_gravity and size_hint_flags of F.
4001 Adjust height for toolbar if TOOLBAR_P is 1.
4003 This function does not make the coordinates positive. */
4005 #define DEFAULT_ROWS 35
4006 #define DEFAULT_COLS 80
4009 x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
4011 register Lisp_Object tem0, tem1, tem2;
4012 long window_prompting = 0;
4013 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4015 /* Default values if we fall through.
4016 Actually, if that happens we should get
4017 window manager prompting. */
4018 SET_FRAME_COLS (f, DEFAULT_COLS);
4019 FRAME_LINES (f) = DEFAULT_ROWS;
4020 /* Window managers expect that if program-specified
4021 positions are not (0,0), they're intentional, not defaults. */
4022 f->top_pos = 0;
4023 f->left_pos = 0;
4025 /* Ensure that old new_text_cols and new_text_lines will not override the
4026 values set here. */
4027 /* ++KFS: This was specific to W32, but seems ok for all platforms */
4028 f->new_text_cols = f->new_text_lines = 0;
4030 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4031 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4032 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4033 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4035 if (!EQ (tem0, Qunbound))
4037 CHECK_NUMBER (tem0);
4038 FRAME_LINES (f) = XINT (tem0);
4040 if (!EQ (tem1, Qunbound))
4042 CHECK_NUMBER (tem1);
4043 SET_FRAME_COLS (f, XINT (tem1));
4045 if (!NILP (tem2) && !EQ (tem2, Qunbound))
4046 window_prompting |= USSize;
4047 else
4048 window_prompting |= PSize;
4051 f->scroll_bar_actual_width
4052 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
4054 /* This used to be done _before_ calling x_figure_window_size, but
4055 since the height is reset here, this was really a no-op. I
4056 assume that moving it here does what Gerd intended (although he
4057 no longer can remember what that was... ++KFS, 2003-03-25. */
4059 /* Add the tool-bar height to the initial frame height so that the
4060 user gets a text display area of the size he specified with -g or
4061 via .Xdefaults. Later changes of the tool-bar height don't
4062 change the frame size. This is done so that users can create
4063 tall Emacs frames without having to guess how tall the tool-bar
4064 will get. */
4065 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4067 int margin, relief, bar_height;
4069 relief = (tool_bar_button_relief >= 0
4070 ? tool_bar_button_relief
4071 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4073 if (INTEGERP (Vtool_bar_button_margin)
4074 && XINT (Vtool_bar_button_margin) > 0)
4075 margin = XFASTINT (Vtool_bar_button_margin);
4076 else if (CONSP (Vtool_bar_button_margin)
4077 && INTEGERP (XCDR (Vtool_bar_button_margin))
4078 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
4079 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4080 else
4081 margin = 0;
4083 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4084 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
4087 compute_fringe_widths (f, 0);
4089 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
4090 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
4092 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4093 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4094 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4095 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4097 if (EQ (tem0, Qminus))
4099 f->top_pos = 0;
4100 window_prompting |= YNegative;
4102 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
4103 && CONSP (XCDR (tem0))
4104 && INTEGERP (XCAR (XCDR (tem0))))
4106 f->top_pos = - XINT (XCAR (XCDR (tem0)));
4107 window_prompting |= YNegative;
4109 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
4110 && CONSP (XCDR (tem0))
4111 && INTEGERP (XCAR (XCDR (tem0))))
4113 f->top_pos = XINT (XCAR (XCDR (tem0)));
4115 else if (EQ (tem0, Qunbound))
4116 f->top_pos = 0;
4117 else
4119 CHECK_NUMBER (tem0);
4120 f->top_pos = XINT (tem0);
4121 if (f->top_pos < 0)
4122 window_prompting |= YNegative;
4125 if (EQ (tem1, Qminus))
4127 f->left_pos = 0;
4128 window_prompting |= XNegative;
4130 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
4131 && CONSP (XCDR (tem1))
4132 && INTEGERP (XCAR (XCDR (tem1))))
4134 f->left_pos = - XINT (XCAR (XCDR (tem1)));
4135 window_prompting |= XNegative;
4137 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
4138 && CONSP (XCDR (tem1))
4139 && INTEGERP (XCAR (XCDR (tem1))))
4141 f->left_pos = XINT (XCAR (XCDR (tem1)));
4143 else if (EQ (tem1, Qunbound))
4144 f->left_pos = 0;
4145 else
4147 CHECK_NUMBER (tem1);
4148 f->left_pos = XINT (tem1);
4149 if (f->left_pos < 0)
4150 window_prompting |= XNegative;
4153 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
4154 window_prompting |= USPosition;
4155 else
4156 window_prompting |= PPosition;
4159 if (window_prompting & XNegative)
4161 if (window_prompting & YNegative)
4162 f->win_gravity = SouthEastGravity;
4163 else
4164 f->win_gravity = NorthEastGravity;
4166 else
4168 if (window_prompting & YNegative)
4169 f->win_gravity = SouthWestGravity;
4170 else
4171 f->win_gravity = NorthWestGravity;
4174 f->size_hint_flags = window_prompting;
4176 return window_prompting;
4181 #endif /* HAVE_WINDOW_SYSTEM */
4183 void
4184 frame_make_pointer_invisible (void)
4186 if (! NILP (Vmake_pointer_invisible))
4188 struct frame *f;
4189 if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
4190 return;
4192 f = SELECTED_FRAME ();
4193 if (f && !f->pointer_invisible
4194 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4196 f->mouse_moved = 0;
4197 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 1);
4198 f->pointer_invisible = 1;
4203 void
4204 frame_make_pointer_visible (void)
4206 /* We don't check Vmake_pointer_invisible here in case the
4207 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4208 struct frame *f;
4210 if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
4211 return;
4213 f = SELECTED_FRAME ();
4214 if (f && f->pointer_invisible && f->mouse_moved
4215 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4217 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 0);
4218 f->pointer_invisible = 0;
4222 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p,
4223 Sframe_pointer_visible_p, 0, 1, 0,
4224 doc: /* Return t if the mouse pointer displayed on FRAME is visible.
4225 Otherwise it returns nil. FRAME omitted or nil means the
4226 selected frame. This is useful when `make-pointer-invisible' is set. */)
4227 (Lisp_Object frame)
4229 if (NILP (frame))
4230 frame = selected_frame;
4232 CHECK_FRAME (frame);
4234 return (XFRAME (frame)->pointer_invisible ? Qnil : Qt);
4238 /***********************************************************************
4239 Initialization
4240 ***********************************************************************/
4242 void
4243 syms_of_frame (void)
4245 Qframep = intern_c_string ("framep");
4246 staticpro (&Qframep);
4247 Qframe_live_p = intern_c_string ("frame-live-p");
4248 staticpro (&Qframe_live_p);
4249 Qexplicit_name = intern_c_string ("explicit-name");
4250 staticpro (&Qexplicit_name);
4251 Qheight = intern_c_string ("height");
4252 staticpro (&Qheight);
4253 Qicon = intern_c_string ("icon");
4254 staticpro (&Qicon);
4255 Qminibuffer = intern_c_string ("minibuffer");
4256 staticpro (&Qminibuffer);
4257 Qmodeline = intern_c_string ("modeline");
4258 staticpro (&Qmodeline);
4259 Qonly = intern_c_string ("only");
4260 staticpro (&Qonly);
4261 Qwidth = intern_c_string ("width");
4262 staticpro (&Qwidth);
4263 Qgeometry = intern_c_string ("geometry");
4264 staticpro (&Qgeometry);
4265 Qicon_left = intern_c_string ("icon-left");
4266 staticpro (&Qicon_left);
4267 Qicon_top = intern_c_string ("icon-top");
4268 staticpro (&Qicon_top);
4269 Qtooltip = intern_c_string ("tooltip");
4270 staticpro (&Qtooltip);
4271 Qleft = intern_c_string ("left");
4272 staticpro (&Qleft);
4273 Qright = intern_c_string ("right");
4274 staticpro (&Qright);
4275 Quser_position = intern_c_string ("user-position");
4276 staticpro (&Quser_position);
4277 Quser_size = intern_c_string ("user-size");
4278 staticpro (&Quser_size);
4279 Qwindow_id = intern_c_string ("window-id");
4280 staticpro (&Qwindow_id);
4281 #ifdef HAVE_X_WINDOWS
4282 Qouter_window_id = intern_c_string ("outer-window-id");
4283 staticpro (&Qouter_window_id);
4284 #endif
4285 Qparent_id = intern_c_string ("parent-id");
4286 staticpro (&Qparent_id);
4287 Qx = intern_c_string ("x");
4288 staticpro (&Qx);
4289 Qw32 = intern_c_string ("w32");
4290 staticpro (&Qw32);
4291 Qpc = intern_c_string ("pc");
4292 staticpro (&Qpc);
4293 Qmac = intern_c_string ("mac");
4294 staticpro (&Qmac);
4295 Qns = intern_c_string ("ns");
4296 staticpro (&Qns);
4297 Qvisible = intern_c_string ("visible");
4298 staticpro (&Qvisible);
4299 Qbuffer_predicate = intern_c_string ("buffer-predicate");
4300 staticpro (&Qbuffer_predicate);
4301 Qbuffer_list = intern_c_string ("buffer-list");
4302 staticpro (&Qbuffer_list);
4303 Qburied_buffer_list = intern_c_string ("buried-buffer-list");
4304 staticpro (&Qburied_buffer_list);
4305 Qdisplay_type = intern_c_string ("display-type");
4306 staticpro (&Qdisplay_type);
4307 Qbackground_mode = intern_c_string ("background-mode");
4308 staticpro (&Qbackground_mode);
4309 Qnoelisp = intern_c_string ("noelisp");
4310 staticpro (&Qnoelisp);
4311 Qtty_color_mode = intern_c_string ("tty-color-mode");
4312 staticpro (&Qtty_color_mode);
4313 Qtty = intern_c_string ("tty");
4314 staticpro (&Qtty);
4315 Qtty_type = intern_c_string ("tty-type");
4316 staticpro (&Qtty_type);
4318 Qface_set_after_frame_default = intern_c_string ("face-set-after-frame-default");
4319 staticpro (&Qface_set_after_frame_default);
4321 Qfullwidth = intern_c_string ("fullwidth");
4322 staticpro (&Qfullwidth);
4323 Qfullheight = intern_c_string ("fullheight");
4324 staticpro (&Qfullheight);
4325 Qfullboth = intern_c_string ("fullboth");
4326 staticpro (&Qfullboth);
4327 Qmaximized = intern_c_string ("maximized");
4328 staticpro (&Qmaximized);
4329 Qx_resource_name = intern_c_string ("x-resource-name");
4330 staticpro (&Qx_resource_name);
4332 Qx_frame_parameter = intern_c_string ("x-frame-parameter");
4333 staticpro (&Qx_frame_parameter);
4335 Qterminal = intern_c_string ("terminal");
4336 staticpro (&Qterminal);
4337 Qterminal_live_p = intern_c_string ("terminal-live-p");
4338 staticpro (&Qterminal_live_p);
4340 #ifdef HAVE_NS
4341 Qns_parse_geometry = intern_c_string ("ns-parse-geometry");
4342 staticpro (&Qns_parse_geometry);
4343 #endif
4346 int i;
4348 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4350 Lisp_Object v = intern_c_string (frame_parms[i].name);
4351 if (frame_parms[i].variable)
4353 *frame_parms[i].variable = v;
4354 staticpro (frame_parms[i].variable);
4356 Fput (v, Qx_frame_parameter, make_number (i));
4360 #ifdef HAVE_WINDOW_SYSTEM
4361 DEFVAR_LISP ("x-resource-name", Vx_resource_name,
4362 doc: /* The name Emacs uses to look up X resources.
4363 `x-get-resource' uses this as the first component of the instance name
4364 when requesting resource values.
4365 Emacs initially sets `x-resource-name' to the name under which Emacs
4366 was invoked, or to the value specified with the `-name' or `-rn'
4367 switches, if present.
4369 It may be useful to bind this variable locally around a call
4370 to `x-get-resource'. See also the variable `x-resource-class'. */);
4371 Vx_resource_name = Qnil;
4373 DEFVAR_LISP ("x-resource-class", Vx_resource_class,
4374 doc: /* The class Emacs uses to look up X resources.
4375 `x-get-resource' uses this as the first component of the instance class
4376 when requesting resource values.
4378 Emacs initially sets `x-resource-class' to "Emacs".
4380 Setting this variable permanently is not a reasonable thing to do,
4381 but binding this variable locally around a call to `x-get-resource'
4382 is a reasonable practice. See also the variable `x-resource-name'. */);
4383 Vx_resource_class = build_string (EMACS_CLASS);
4385 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit,
4386 doc: /* The lower limit of the frame opacity (alpha transparency).
4387 The value should range from 0 (invisible) to 100 (completely opaque).
4388 You can also use a floating number between 0.0 and 1.0.
4389 The default is 20. */);
4390 Vframe_alpha_lower_limit = make_number (20);
4391 #endif
4393 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist,
4394 doc: /* Alist of default values for frame creation.
4395 These may be set in your init file, like this:
4396 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4397 These override values given in window system configuration data,
4398 including X Windows' defaults database.
4399 For values specific to the first Emacs frame, see `initial-frame-alist'.
4400 For window-system specific values, see `window-system-default-frame-alist'.
4401 For values specific to the separate minibuffer frame, see
4402 `minibuffer-frame-alist'.
4403 The `menu-bar-lines' element of the list controls whether new frames
4404 have menu bars; `menu-bar-mode' works by altering this element.
4405 Setting this variable does not affect existing frames, only new ones. */);
4406 Vdefault_frame_alist = Qnil;
4408 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars,
4409 doc: /* Default position of scroll bars on this window-system. */);
4410 #ifdef HAVE_WINDOW_SYSTEM
4411 #if defined(HAVE_NTGUI) || defined(NS_IMPL_COCOA) || (defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS))
4412 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
4413 default. */
4414 Vdefault_frame_scroll_bars = Qright;
4415 #else
4416 Vdefault_frame_scroll_bars = Qleft;
4417 #endif
4418 #else
4419 Vdefault_frame_scroll_bars = Qnil;
4420 #endif
4422 DEFVAR_LISP ("terminal-frame", Vterminal_frame,
4423 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4425 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function,
4426 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4427 `mouse-position' calls this function, passing its usual return value as
4428 argument, and returns whatever this function returns.
4429 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4430 which need to do mouse handling at the Lisp level. */);
4431 Vmouse_position_function = Qnil;
4433 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight,
4434 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4435 If the value is an integer, highlighting is only shown after moving the
4436 mouse, while keyboard input turns off the highlight even when the mouse
4437 is over the clickable text. However, the mouse shape still indicates
4438 when the mouse is over clickable text. */);
4439 Vmouse_highlight = Qt;
4441 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible,
4442 doc: /* If non-nil, make pointer invisible while typing.
4443 The pointer becomes visible again when the mouse is moved. */);
4444 Vmake_pointer_invisible = Qt;
4446 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
4447 doc: /* Functions to be run before deleting a frame.
4448 The functions are run with one arg, the frame to be deleted.
4449 See `delete-frame'.
4451 Note that functions in this list may be called just before the frame is
4452 actually deleted, or some time later (or even both when an earlier function
4453 in `delete-frame-functions' (indirectly) calls `delete-frame'
4454 recursively). */);
4455 Vdelete_frame_functions = Qnil;
4456 Qdelete_frame_functions = intern_c_string ("delete-frame-functions");
4457 staticpro (&Qdelete_frame_functions);
4459 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode,
4460 doc: /* Non-nil if Menu-Bar mode is enabled.
4461 See the command `menu-bar-mode' for a description of this minor mode.
4462 Setting this variable directly does not take effect;
4463 either customize it (see the info node `Easy Customization')
4464 or call the function `menu-bar-mode'. */);
4465 Vmenu_bar_mode = Qt;
4467 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode,
4468 doc: /* Non-nil if Tool-Bar mode is enabled.
4469 See the command `tool-bar-mode' for a description of this minor mode.
4470 Setting this variable directly does not take effect;
4471 either customize it (see the info node `Easy Customization')
4472 or call the function `tool-bar-mode'. */);
4473 #ifdef HAVE_WINDOW_SYSTEM
4474 Vtool_bar_mode = Qt;
4475 #else
4476 Vtool_bar_mode = Qnil;
4477 #endif
4479 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4480 doc: /* Minibufferless frames use this frame's minibuffer.
4482 Emacs cannot create minibufferless frames unless this is set to an
4483 appropriate surrogate.
4485 Emacs consults this variable only when creating minibufferless
4486 frames; once the frame is created, it sticks with its assigned
4487 minibuffer, no matter what this variable is set to. This means that
4488 this variable doesn't necessarily say anything meaningful about the
4489 current set of frames, or where the minibuffer is currently being
4490 displayed.
4492 This variable is local to the current terminal and cannot be buffer-local. */);
4494 DEFVAR_BOOL ("focus-follows-mouse", focus_follows_mouse,
4495 doc: /* Non-nil if window system changes focus when you move the mouse.
4496 You should set this variable to tell Emacs how your window manager
4497 handles focus, since there is no way in general for Emacs to find out
4498 automatically. See also `mouse-autoselect-window'. */);
4499 focus_follows_mouse = 0;
4501 staticpro (&Vframe_list);
4503 defsubr (&Sframep);
4504 defsubr (&Sframe_live_p);
4505 defsubr (&Swindow_system);
4506 defsubr (&Smake_terminal_frame);
4507 defsubr (&Shandle_switch_frame);
4508 defsubr (&Sselect_frame);
4509 defsubr (&Sselected_frame);
4510 defsubr (&Sframe_list);
4511 defsubr (&Snext_frame);
4512 defsubr (&Sprevious_frame);
4513 defsubr (&Sother_visible_frames_p);
4514 defsubr (&Sdelete_frame);
4515 defsubr (&Smouse_position);
4516 defsubr (&Smouse_pixel_position);
4517 defsubr (&Sset_mouse_position);
4518 defsubr (&Sset_mouse_pixel_position);
4519 #if 0
4520 defsubr (&Sframe_configuration);
4521 defsubr (&Srestore_frame_configuration);
4522 #endif
4523 defsubr (&Smake_frame_visible);
4524 defsubr (&Smake_frame_invisible);
4525 defsubr (&Siconify_frame);
4526 defsubr (&Sframe_visible_p);
4527 defsubr (&Svisible_frame_list);
4528 defsubr (&Sraise_frame);
4529 defsubr (&Slower_frame);
4530 defsubr (&Sredirect_frame_focus);
4531 defsubr (&Sframe_focus);
4532 defsubr (&Sframe_parameters);
4533 defsubr (&Sframe_parameter);
4534 defsubr (&Smodify_frame_parameters);
4535 defsubr (&Sframe_char_height);
4536 defsubr (&Sframe_char_width);
4537 defsubr (&Sframe_pixel_height);
4538 defsubr (&Sframe_pixel_width);
4539 defsubr (&Stool_bar_pixel_width);
4540 defsubr (&Sset_frame_height);
4541 defsubr (&Sset_frame_width);
4542 defsubr (&Sset_frame_size);
4543 defsubr (&Sset_frame_position);
4544 defsubr (&Sframe_pointer_visible_p);
4546 #ifdef HAVE_WINDOW_SYSTEM
4547 defsubr (&Sx_get_resource);
4548 defsubr (&Sx_parse_geometry);
4549 #endif