Merge from trunk
[emacs.git] / src / frame.c
blob3ee06666c45a9f5cf0cec97ee496a090b7afb809
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 <setjmp.h>
25 #include "lisp.h"
26 #include "character.h"
27 #ifdef HAVE_X_WINDOWS
28 #include "xterm.h"
29 #endif
30 #ifdef WINDOWSNT
31 #include "w32term.h"
32 #endif
33 #ifdef HAVE_NS
34 #include "nsterm.h"
35 #endif
36 #include "buffer.h"
37 /* These help us bind and responding to switch-frame events. */
38 #include "commands.h"
39 #include "keyboard.h"
40 #include "frame.h"
41 #include "blockinput.h"
42 #include "termchar.h"
43 #include "termhooks.h"
44 #include "dispextern.h"
45 #include "window.h"
46 #include "font.h"
47 #ifdef HAVE_WINDOW_SYSTEM
48 #include "fontset.h"
49 #endif
50 #ifdef MSDOS
51 #include "msdos.h"
52 #include "dosfns.h"
53 #endif
56 /* If we shall make pointer invisible when typing or not. */
57 Lisp_Object Vmake_pointer_invisible;
59 #ifdef HAVE_WINDOW_SYSTEM
61 /* The name we're using in resource queries. Most often "emacs". */
63 Lisp_Object Vx_resource_name;
65 /* The application class we're using in resource queries.
66 Normally "Emacs". */
68 Lisp_Object Vx_resource_class;
70 /* Lower limit value of the frame opacity (alpha transparency). */
72 Lisp_Object Vframe_alpha_lower_limit;
74 #endif
76 #ifdef HAVE_NS
77 Lisp_Object Qns_parse_geometry;
78 #endif
80 Lisp_Object Qframep, Qframe_live_p;
81 Lisp_Object Qicon, Qmodeline;
82 Lisp_Object Qonly;
83 Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
84 Lisp_Object Qvisible;
85 Lisp_Object Qdisplay_type;
86 Lisp_Object Qbackground_mode;
87 Lisp_Object Qnoelisp;
89 Lisp_Object Qx_frame_parameter;
90 Lisp_Object Qx_resource_name;
91 Lisp_Object Qterminal;
92 Lisp_Object Qterminal_live_p;
94 /* Frame parameters (set or reported). */
96 Lisp_Object Qauto_raise, Qauto_lower;
97 Lisp_Object Qborder_color, Qborder_width;
98 Lisp_Object Qcursor_color, Qcursor_type;
99 Lisp_Object Qgeometry; /* Not used */
100 Lisp_Object Qheight, Qwidth;
101 Lisp_Object Qleft, Qright;
102 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
103 Lisp_Object Qinternal_border_width;
104 Lisp_Object Qmouse_color;
105 Lisp_Object Qminibuffer;
106 Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
107 Lisp_Object Qvisibility;
108 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
109 Lisp_Object Qscreen_gamma;
110 Lisp_Object Qline_spacing;
111 Lisp_Object Quser_position, Quser_size;
112 Lisp_Object Qwait_for_wm;
113 Lisp_Object Qwindow_id;
114 #ifdef HAVE_X_WINDOWS
115 Lisp_Object Qouter_window_id;
116 #endif
117 Lisp_Object Qparent_id;
118 Lisp_Object Qtitle, Qname;
119 Lisp_Object Qexplicit_name;
120 Lisp_Object Qunsplittable;
121 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
122 Lisp_Object Vmenu_bar_mode, Vtool_bar_mode;
123 Lisp_Object Qleft_fringe, Qright_fringe;
124 Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
125 Lisp_Object Qtty_color_mode;
126 Lisp_Object Qtty, Qtty_type;
128 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
129 Lisp_Object Qsticky;
130 Lisp_Object Qfont_backend;
131 Lisp_Object Qalpha;
133 Lisp_Object Qface_set_after_frame_default;
135 Lisp_Object Vterminal_frame;
136 Lisp_Object Vdefault_frame_alist;
137 Lisp_Object Vdefault_frame_scroll_bars;
138 Lisp_Object Vmouse_position_function;
139 Lisp_Object Vmouse_highlight;
140 static Lisp_Object Vdelete_frame_functions, Qdelete_frame_functions;
142 int focus_follows_mouse;
144 static void
145 set_menu_bar_lines_1 (window, n)
146 Lisp_Object window;
147 int n;
149 struct window *w = XWINDOW (window);
151 XSETFASTINT (w->last_modified, 0);
152 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
153 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
155 /* Handle just the top child in a vertical split. */
156 if (!NILP (w->vchild))
157 set_menu_bar_lines_1 (w->vchild, n);
159 /* Adjust all children in a horizontal split. */
160 for (window = w->hchild; !NILP (window); window = w->next)
162 w = XWINDOW (window);
163 set_menu_bar_lines_1 (window, n);
167 void
168 set_menu_bar_lines (f, value, oldval)
169 struct frame *f;
170 Lisp_Object value, oldval;
172 int nlines;
173 int olines = FRAME_MENU_BAR_LINES (f);
175 /* Right now, menu bars don't work properly in minibuf-only frames;
176 most of the commands try to apply themselves to the minibuffer
177 frame itself, and get an error because you can't switch buffers
178 in or split the minibuffer window. */
179 if (FRAME_MINIBUF_ONLY_P (f))
180 return;
182 if (INTEGERP (value))
183 nlines = XINT (value);
184 else
185 nlines = 0;
187 if (nlines != olines)
189 windows_or_buffers_changed++;
190 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
191 FRAME_MENU_BAR_LINES (f) = nlines;
192 set_menu_bar_lines_1 (f->root_window, nlines - olines);
193 adjust_glyphs (f);
197 Lisp_Object Vframe_list;
199 extern Lisp_Object Vminibuffer_list;
200 extern Lisp_Object get_minibuffer ();
201 extern Lisp_Object Fhandle_switch_frame ();
202 extern Lisp_Object Fredirect_frame_focus ();
203 extern Lisp_Object x_get_focus_frame ();
204 extern Lisp_Object QCname, Qfont_param;
207 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
208 doc: /* Return non-nil if OBJECT is a frame.
209 Value is t for a termcap frame (a character-only terminal),
210 `x' for an Emacs frame that is really an X window,
211 `w32' for an Emacs frame that is a window on MS-Windows display,
212 `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
213 `pc' for a direct-write MS-DOS frame.
214 See also `frame-live-p'. */)
215 (object)
216 Lisp_Object object;
218 if (!FRAMEP (object))
219 return Qnil;
220 switch (XFRAME (object)->output_method)
222 case output_initial: /* The initial frame is like a termcap frame. */
223 case output_termcap:
224 return Qt;
225 case output_x_window:
226 return Qx;
227 case output_w32:
228 return Qw32;
229 case output_msdos_raw:
230 return Qpc;
231 case output_mac:
232 return Qmac;
233 case output_ns:
234 return Qns;
235 default:
236 abort ();
240 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
241 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
242 Value is nil if OBJECT is not a live frame. If object is a live
243 frame, the return value indicates what sort of terminal device it is
244 displayed on. See the documentation of `framep' for possible
245 return values. */)
246 (object)
247 Lisp_Object object;
249 return ((FRAMEP (object)
250 && FRAME_LIVE_P (XFRAME (object)))
251 ? Fframep (object)
252 : Qnil);
255 DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
256 doc: /* The name of the window system that FRAME is displaying through.
257 The value is a symbol---for instance, 'x' for X windows.
258 The value is nil if Emacs is using a text-only terminal.
260 FRAME defaults to the currently selected frame. */)
261 (frame)
262 Lisp_Object frame;
264 Lisp_Object type;
265 if (NILP (frame))
266 frame = selected_frame;
268 type = Fframep (frame);
270 if (NILP (type))
271 wrong_type_argument (Qframep, frame);
273 if (EQ (type, Qt))
274 return Qnil;
275 else
276 return type;
279 struct frame *
280 make_frame (mini_p)
281 int mini_p;
283 Lisp_Object frame;
284 register struct frame *f;
285 register Lisp_Object root_window;
286 register Lisp_Object mini_window;
288 f = allocate_frame ();
289 XSETFRAME (frame, f);
291 f->desired_matrix = 0;
292 f->current_matrix = 0;
293 f->desired_pool = 0;
294 f->current_pool = 0;
295 f->glyphs_initialized_p = 0;
296 f->decode_mode_spec_buffer = 0;
297 f->visible = 0;
298 f->async_visible = 0;
299 f->output_data.nothing = 0;
300 f->iconified = 0;
301 f->async_iconified = 0;
302 f->wants_modeline = 1;
303 f->auto_raise = 0;
304 f->auto_lower = 0;
305 f->no_split = 0;
306 f->garbaged = 1;
307 f->has_minibuffer = mini_p;
308 f->focus_frame = Qnil;
309 f->explicit_name = 0;
310 f->can_have_scroll_bars = 0;
311 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
312 f->param_alist = Qnil;
313 f->scroll_bars = Qnil;
314 f->condemned_scroll_bars = Qnil;
315 f->face_alist = Qnil;
316 f->face_cache = NULL;
317 f->menu_bar_items = Qnil;
318 f->menu_bar_vector = Qnil;
319 f->menu_bar_items_used = 0;
320 f->buffer_predicate = Qnil;
321 f->buffer_list = Qnil;
322 f->buried_buffer_list = Qnil;
323 f->namebuf = 0;
324 f->title = Qnil;
325 f->menu_bar_window = Qnil;
326 f->tool_bar_window = Qnil;
327 f->tool_bar_items = Qnil;
328 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
329 f->n_tool_bar_items = 0;
330 f->left_fringe_width = f->right_fringe_width = 0;
331 f->fringe_cols = 0;
332 f->scroll_bar_actual_width = 0;
333 f->border_width = 0;
334 f->internal_border_width = 0;
335 f->column_width = 1; /* !FRAME_WINDOW_P value */
336 f->line_height = 1; /* !FRAME_WINDOW_P value */
337 f->x_pixels_diff = f->y_pixels_diff = 0;
338 #ifdef HAVE_WINDOW_SYSTEM
339 f->want_fullscreen = FULLSCREEN_NONE;
340 #endif
341 f->size_hint_flags = 0;
342 f->win_gravity = 0;
343 f->font_driver_list = NULL;
344 f->font_data_list = NULL;
346 root_window = make_window ();
347 if (mini_p)
349 mini_window = make_window ();
350 XWINDOW (root_window)->next = mini_window;
351 XWINDOW (mini_window)->prev = root_window;
352 XWINDOW (mini_window)->mini_p = Qt;
353 XWINDOW (mini_window)->frame = frame;
354 f->minibuffer_window = mini_window;
356 else
358 mini_window = Qnil;
359 XWINDOW (root_window)->next = Qnil;
360 f->minibuffer_window = Qnil;
363 XWINDOW (root_window)->frame = frame;
365 /* 10 is arbitrary,
366 just so that there is "something there."
367 Correct size will be set up later with change_frame_size. */
369 SET_FRAME_COLS (f, 10);
370 FRAME_LINES (f) = 10;
372 XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
373 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10));
375 if (mini_p)
377 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
378 XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
379 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1);
382 /* Choose a buffer for the frame's root window. */
384 Lisp_Object buf;
386 XWINDOW (root_window)->buffer = Qt;
387 buf = Fcurrent_buffer ();
388 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
389 a space), try to find another one. */
390 if (SREF (Fbuffer_name (buf), 0) == ' ')
391 buf = Fother_buffer (buf, Qnil, Qnil);
393 /* Use set_window_buffer, not Fset_window_buffer, and don't let
394 hooks be run by it. The reason is that the whole frame/window
395 arrangement is not yet fully intialized at this point. Windows
396 don't have the right size, glyph matrices aren't initialized
397 etc. Running Lisp functions at this point surely ends in a
398 SEGV. */
399 set_window_buffer (root_window, buf, 0, 0);
400 f->buffer_list = Fcons (buf, Qnil);
403 if (mini_p)
405 XWINDOW (mini_window)->buffer = Qt;
406 set_window_buffer (mini_window,
407 (NILP (Vminibuffer_list)
408 ? get_minibuffer (0)
409 : Fcar (Vminibuffer_list)),
410 0, 0);
413 f->root_window = root_window;
414 f->selected_window = root_window;
415 /* Make sure this window seems more recently used than
416 a newly-created, never-selected window. */
417 ++window_select_count;
418 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
420 f->default_face_done_p = 0;
422 return f;
425 #ifdef HAVE_WINDOW_SYSTEM
426 /* Make a frame using a separate minibuffer window on another frame.
427 MINI_WINDOW is the minibuffer window to use. nil means use the
428 default (the global minibuffer). */
430 struct frame *
431 make_frame_without_minibuffer (mini_window, kb, display)
432 register Lisp_Object mini_window;
433 KBOARD *kb;
434 Lisp_Object display;
436 register struct frame *f;
437 struct gcpro gcpro1;
439 if (!NILP (mini_window))
440 CHECK_LIVE_WINDOW (mini_window);
442 if (!NILP (mini_window)
443 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
444 error ("Frame and minibuffer must be on the same terminal");
446 /* Make a frame containing just a root window. */
447 f = make_frame (0);
449 if (NILP (mini_window))
451 /* Use default-minibuffer-frame if possible. */
452 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
453 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
455 Lisp_Object frame_dummy;
457 XSETFRAME (frame_dummy, f);
458 GCPRO1 (frame_dummy);
459 /* If there's no minibuffer frame to use, create one. */
460 kb->Vdefault_minibuffer_frame =
461 call1 (intern ("make-initial-minibuffer-frame"), display);
462 UNGCPRO;
465 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
468 f->minibuffer_window = mini_window;
470 /* Make the chosen minibuffer window display the proper minibuffer,
471 unless it is already showing a minibuffer. */
472 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
473 Fset_window_buffer (mini_window,
474 (NILP (Vminibuffer_list)
475 ? get_minibuffer (0)
476 : Fcar (Vminibuffer_list)), Qnil);
477 return f;
480 /* Make a frame containing only a minibuffer window. */
482 struct frame *
483 make_minibuffer_frame ()
485 /* First make a frame containing just a root window, no minibuffer. */
487 register struct frame *f = make_frame (0);
488 register Lisp_Object mini_window;
489 register Lisp_Object frame;
491 XSETFRAME (frame, f);
493 f->auto_raise = 0;
494 f->auto_lower = 0;
495 f->no_split = 1;
496 f->wants_modeline = 0;
497 f->has_minibuffer = 1;
499 /* Now label the root window as also being the minibuffer.
500 Avoid infinite looping on the window chain by marking next pointer
501 as nil. */
503 mini_window = f->minibuffer_window = f->root_window;
504 XWINDOW (mini_window)->mini_p = Qt;
505 XWINDOW (mini_window)->next = Qnil;
506 XWINDOW (mini_window)->prev = Qnil;
507 XWINDOW (mini_window)->frame = frame;
509 /* Put the proper buffer in that window. */
511 Fset_window_buffer (mini_window,
512 (NILP (Vminibuffer_list)
513 ? get_minibuffer (0)
514 : Fcar (Vminibuffer_list)), Qnil);
515 return f;
517 #endif /* HAVE_WINDOW_SYSTEM */
519 /* Construct a frame that refers to a terminal. */
521 static int tty_frame_count;
523 struct frame *
524 make_initial_frame (void)
526 struct frame *f;
527 struct terminal *terminal;
528 Lisp_Object frame;
530 eassert (initial_kboard);
532 /* The first call must initialize Vframe_list. */
533 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
534 Vframe_list = Qnil;
536 terminal = init_initial_terminal ();
538 f = make_frame (1);
539 XSETFRAME (frame, f);
541 Vframe_list = Fcons (frame, Vframe_list);
543 tty_frame_count = 1;
544 f->name = make_pure_c_string ("F1");
546 f->visible = 1;
547 f->async_visible = 1;
549 f->output_method = terminal->type;
550 f->terminal = terminal;
551 f->terminal->reference_count++;
552 f->output_data.nothing = 0;
554 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
555 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
557 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
558 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
560 #ifdef CANNOT_DUMP
561 if (!noninteractive)
562 init_frame_faces (f);
563 #endif
565 return f;
569 struct frame *
570 make_terminal_frame (struct terminal *terminal)
572 register struct frame *f;
573 Lisp_Object frame;
574 char name[20];
576 if (!terminal->name)
577 error ("Terminal is not live, can't create new frames on it");
579 f = make_frame (1);
581 XSETFRAME (frame, f);
582 Vframe_list = Fcons (frame, Vframe_list);
584 tty_frame_count++;
585 sprintf (name, "F%d", tty_frame_count);
586 f->name = build_string (name);
588 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
589 f->async_visible = 1; /* Don't let visible be cleared later. */
590 f->terminal = terminal;
591 f->terminal->reference_count++;
592 #ifdef MSDOS
593 f->output_data.tty->display_info = &the_only_display_info;
594 if (!inhibit_window_system
595 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
596 || XFRAME (selected_frame)->output_method == output_msdos_raw))
597 f->output_method = output_msdos_raw;
598 else
599 f->output_method = output_termcap;
600 #else /* not MSDOS */
601 f->output_method = output_termcap;
602 create_tty_output (f);
603 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
604 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
605 #endif /* not MSDOS */
607 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
608 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
610 /* Set the top frame to the newly created frame. */
611 if (FRAMEP (FRAME_TTY (f)->top_frame)
612 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
613 XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
615 FRAME_TTY (f)->top_frame = frame;
617 if (!noninteractive)
618 init_frame_faces (f);
620 return f;
623 /* Get a suitable value for frame parameter PARAMETER for a newly
624 created frame, based on (1) the user-supplied frame parameter
625 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
627 static Lisp_Object
628 get_future_frame_param (Lisp_Object parameter,
629 Lisp_Object supplied_parms,
630 char *current_value)
632 Lisp_Object result;
634 result = Fassq (parameter, supplied_parms);
635 if (NILP (result))
636 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
637 if (NILP (result) && current_value != NULL)
638 result = build_string (current_value);
639 if (!NILP (result) && !STRINGP (result))
640 result = XCDR (result);
641 if (NILP (result) || !STRINGP (result))
642 result = Qnil;
644 return result;
647 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
648 1, 1, 0,
649 doc: /* Create an additional terminal frame, possibly on another terminal.
650 This function takes one argument, an alist specifying frame parameters.
652 You can create multiple frames on a single text-only terminal, but
653 only one of them (the selected terminal frame) is actually displayed.
655 In practice, generally you don't need to specify any parameters,
656 except when you want to create a new frame on another terminal.
657 In that case, the `tty' parameter specifies the device file to open,
658 and the `tty-type' parameter specifies the terminal type. Example:
660 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
662 Note that changing the size of one terminal frame automatically
663 affects all frames on the same terminal device. */)
664 (parms)
665 Lisp_Object parms;
667 struct frame *f;
668 struct terminal *t = NULL;
669 Lisp_Object frame, tem;
670 struct frame *sf = SELECTED_FRAME ();
672 #ifdef MSDOS
673 if (sf->output_method != output_msdos_raw
674 && sf->output_method != output_termcap)
675 abort ();
676 #else /* not MSDOS */
678 #ifdef WINDOWSNT /* This should work now! */
679 if (sf->output_method != output_termcap)
680 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
681 #endif
682 #endif /* not MSDOS */
685 Lisp_Object terminal;
687 terminal = Fassq (Qterminal, parms);
688 if (!NILP (terminal))
690 terminal = XCDR (terminal);
691 t = get_terminal (terminal, 1);
693 #ifdef MSDOS
694 if (t && t != the_only_display_info.terminal)
695 /* msdos.c assumes a single tty_display_info object. */
696 error ("Multiple terminals are not supported on this platform");
697 if (!t)
698 t = the_only_display_info.terminal;
699 #endif
702 if (!t)
704 char *name = 0, *type = 0;
705 Lisp_Object tty, tty_type;
707 tty = get_future_frame_param
708 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
709 ? FRAME_TTY (XFRAME (selected_frame))->name
710 : NULL));
711 if (!NILP (tty))
713 name = (char *) alloca (SBYTES (tty) + 1);
714 strncpy (name, SDATA (tty), SBYTES (tty));
715 name[SBYTES (tty)] = 0;
718 tty_type = get_future_frame_param
719 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
720 ? FRAME_TTY (XFRAME (selected_frame))->type
721 : NULL));
722 if (!NILP (tty_type))
724 type = (char *) alloca (SBYTES (tty_type) + 1);
725 strncpy (type, SDATA (tty_type), SBYTES (tty_type));
726 type[SBYTES (tty_type)] = 0;
729 t = init_tty (name, type, 0); /* Errors are not fatal. */
732 f = make_terminal_frame (t);
735 int width, height;
736 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
737 change_frame_size (f, height, width, 0, 0, 0);
740 adjust_glyphs (f);
741 calculate_costs (f);
742 XSETFRAME (frame, f);
743 Fmodify_frame_parameters (frame, parms);
744 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
745 build_string (t->display_info.tty->type)),
746 Qnil));
747 if (t->display_info.tty->name != NULL)
748 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
749 build_string (t->display_info.tty->name)),
750 Qnil));
751 else
752 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
754 /* Make the frame face alist be frame-specific, so that each
755 frame could change its face definitions independently. */
756 f->face_alist = Fcopy_alist (sf->face_alist);
757 /* Simple Fcopy_alist isn't enough, because we need the contents of
758 the vectors which are the CDRs of associations in face_alist to
759 be copied as well. */
760 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
761 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
762 return frame;
766 /* Perform the switch to frame FRAME.
768 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
769 FRAME1 as frame.
771 If TRACK is non-zero and the frame that currently has the focus
772 redirects its focus to the selected frame, redirect that focused
773 frame's focus to FRAME instead.
775 FOR_DELETION non-zero means that the selected frame is being
776 deleted, which includes the possibility that the frame's terminal
777 is dead.
779 The value of NORECORD is passed as argument to Fselect_window. */
781 Lisp_Object
782 do_switch_frame (frame, track, for_deletion, norecord)
783 Lisp_Object frame, norecord;
784 int track, for_deletion;
786 struct frame *sf = SELECTED_FRAME ();
788 /* If FRAME is a switch-frame event, extract the frame we should
789 switch to. */
790 if (CONSP (frame)
791 && EQ (XCAR (frame), Qswitch_frame)
792 && CONSP (XCDR (frame)))
793 frame = XCAR (XCDR (frame));
795 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
796 a switch-frame event to arrive after a frame is no longer live,
797 especially when deleting the initial frame during startup. */
798 CHECK_FRAME (frame);
799 if (! FRAME_LIVE_P (XFRAME (frame)))
800 return Qnil;
802 if (sf == XFRAME (frame))
803 return frame;
805 /* This is too greedy; it causes inappropriate focus redirection
806 that's hard to get rid of. */
807 #if 0
808 /* If a frame's focus has been redirected toward the currently
809 selected frame, we should change the redirection to point to the
810 newly selected frame. This means that if the focus is redirected
811 from a minibufferless frame to a surrogate minibuffer frame, we
812 can use `other-window' to switch between all the frames using
813 that minibuffer frame, and the focus redirection will follow us
814 around. */
815 if (track)
817 Lisp_Object tail;
819 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
821 Lisp_Object focus;
823 if (!FRAMEP (XCAR (tail)))
824 abort ();
826 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
828 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
829 Fredirect_frame_focus (XCAR (tail), frame);
832 #else /* ! 0 */
833 /* Instead, apply it only to the frame we're pointing to. */
834 #ifdef HAVE_WINDOW_SYSTEM
835 if (track && FRAME_WINDOW_P (XFRAME (frame)))
837 Lisp_Object focus, xfocus;
839 xfocus = x_get_focus_frame (XFRAME (frame));
840 if (FRAMEP (xfocus))
842 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
843 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
844 Fredirect_frame_focus (xfocus, frame);
847 #endif /* HAVE_X_WINDOWS */
848 #endif /* ! 0 */
850 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
851 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
853 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
855 if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
856 /* Mark previously displayed frame as now obscured. */
857 XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2;
858 XFRAME (frame)->async_visible = 1;
859 FRAME_TTY (XFRAME (frame))->top_frame = frame;
862 selected_frame = frame;
863 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
864 last_nonminibuf_frame = XFRAME (selected_frame);
866 Fselect_window (XFRAME (frame)->selected_window, norecord);
868 /* We want to make sure that the next event generates a frame-switch
869 event to the appropriate frame. This seems kludgy to me, but
870 before you take it out, make sure that evaluating something like
871 (select-window (frame-root-window (new-frame))) doesn't end up
872 with your typing being interpreted in the new frame instead of
873 the one you're actually typing in. */
874 internal_last_event_frame = Qnil;
876 return frame;
879 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
880 doc: /* Select FRAME.
881 Subsequent editing commands apply to its selected window.
882 Optional argument NORECORD means to neither change the order of
883 recently selected windows nor the buffer list.
885 The selection of FRAME lasts until the next time the user does
886 something to select a different frame, or until the next time
887 this function is called. If you are using a window system, the
888 previously selected frame may be restored as the selected frame
889 when returning to the command loop, because it still may have
890 the window system's input focus. On a text-only terminal, the
891 next redisplay will display FRAME.
893 This function returns FRAME, or nil if FRAME has been deleted. */)
894 (frame, norecord)
895 Lisp_Object frame, norecord;
897 return do_switch_frame (frame, 1, 0, norecord);
901 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
902 doc: /* Handle a switch-frame event EVENT.
903 Switch-frame events are usually bound to this function.
904 A switch-frame event tells Emacs that the window manager has requested
905 that the user's events be directed to the frame mentioned in the event.
906 This function selects the selected window of the frame of EVENT.
908 If EVENT is frame object, handle it as if it were a switch-frame event
909 to that frame. */)
910 (event)
911 Lisp_Object event;
913 /* Preserve prefix arg that the command loop just cleared. */
914 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
915 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
916 return do_switch_frame (event, 0, 0, Qnil);
919 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
920 doc: /* Return the frame that is now selected. */)
923 return selected_frame;
926 DEFUN ("frame-list", Fframe_list, Sframe_list,
927 0, 0, 0,
928 doc: /* Return a list of all live frames. */)
931 Lisp_Object frames;
932 frames = Fcopy_sequence (Vframe_list);
933 #ifdef HAVE_WINDOW_SYSTEM
934 if (FRAMEP (tip_frame))
935 frames = Fdelq (tip_frame, frames);
936 #endif
937 return frames;
940 /* Return the next frame in the frame list after FRAME.
941 If MINIBUF is nil, exclude minibuffer-only frames.
942 If MINIBUF is a window, include only its own frame
943 and any frame now using that window as the minibuffer.
944 If MINIBUF is `visible', include all visible frames.
945 If MINIBUF is 0, include all visible and iconified frames.
946 Otherwise, include all frames. */
948 static Lisp_Object
949 next_frame (frame, minibuf)
950 Lisp_Object frame;
951 Lisp_Object minibuf;
953 Lisp_Object tail;
954 int passed = 0;
956 /* There must always be at least one frame in Vframe_list. */
957 if (! CONSP (Vframe_list))
958 abort ();
960 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
961 forever. Forestall that. */
962 CHECK_LIVE_FRAME (frame);
964 while (1)
965 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
967 Lisp_Object f;
969 f = XCAR (tail);
971 if (passed
972 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
973 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
974 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
975 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
977 /* Decide whether this frame is eligible to be returned. */
979 /* If we've looped all the way around without finding any
980 eligible frames, return the original frame. */
981 if (EQ (f, frame))
982 return f;
984 /* Let minibuf decide if this frame is acceptable. */
985 if (NILP (minibuf))
987 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
988 return f;
990 else if (EQ (minibuf, Qvisible))
992 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
993 if (FRAME_VISIBLE_P (XFRAME (f)))
994 return f;
996 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
998 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
999 if (FRAME_VISIBLE_P (XFRAME (f))
1000 || FRAME_ICONIFIED_P (XFRAME (f)))
1001 return f;
1003 else if (WINDOWP (minibuf))
1005 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1006 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1007 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1008 FRAME_FOCUS_FRAME (XFRAME (f))))
1009 return f;
1011 else
1012 return f;
1015 if (EQ (frame, f))
1016 passed++;
1020 /* Return the previous frame in the frame list before FRAME.
1021 If MINIBUF is nil, exclude minibuffer-only frames.
1022 If MINIBUF is a window, include only its own frame
1023 and any frame now using that window as the minibuffer.
1024 If MINIBUF is `visible', include all visible frames.
1025 If MINIBUF is 0, include all visible and iconified frames.
1026 Otherwise, include all frames. */
1028 static Lisp_Object
1029 prev_frame (frame, minibuf)
1030 Lisp_Object frame;
1031 Lisp_Object minibuf;
1033 Lisp_Object tail;
1034 Lisp_Object prev;
1036 /* There must always be at least one frame in Vframe_list. */
1037 if (! CONSP (Vframe_list))
1038 abort ();
1040 prev = Qnil;
1041 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1043 Lisp_Object f;
1045 f = XCAR (tail);
1046 if (!FRAMEP (f))
1047 abort ();
1049 if (EQ (frame, f) && !NILP (prev))
1050 return prev;
1052 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1053 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1054 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1055 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
1057 /* Decide whether this frame is eligible to be returned,
1058 according to minibuf. */
1059 if (NILP (minibuf))
1061 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1062 prev = f;
1064 else if (WINDOWP (minibuf))
1066 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1067 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1068 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1069 FRAME_FOCUS_FRAME (XFRAME (f))))
1070 prev = f;
1072 else if (EQ (minibuf, Qvisible))
1074 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1075 if (FRAME_VISIBLE_P (XFRAME (f)))
1076 prev = f;
1078 else if (XFASTINT (minibuf) == 0)
1080 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1081 if (FRAME_VISIBLE_P (XFRAME (f))
1082 || FRAME_ICONIFIED_P (XFRAME (f)))
1083 prev = f;
1085 else
1086 prev = f;
1090 /* We've scanned the entire list. */
1091 if (NILP (prev))
1092 /* We went through the whole frame list without finding a single
1093 acceptable frame. Return the original frame. */
1094 return frame;
1095 else
1096 /* There were no acceptable frames in the list before FRAME; otherwise,
1097 we would have returned directly from the loop. Since PREV is the last
1098 acceptable frame in the list, return it. */
1099 return prev;
1103 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1104 doc: /* Return the next frame in the frame list after FRAME.
1105 It considers only frames on the same terminal as FRAME.
1106 By default, skip minibuffer-only frames.
1107 If omitted, FRAME defaults to the selected frame.
1108 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1109 If MINIFRAME is a window, include only its own frame
1110 and any frame now using that window as the minibuffer.
1111 If MINIFRAME is `visible', include all visible frames.
1112 If MINIFRAME is 0, include all visible and iconified frames.
1113 Otherwise, include all frames. */)
1114 (frame, miniframe)
1115 Lisp_Object frame, miniframe;
1117 if (NILP (frame))
1118 frame = selected_frame;
1120 CHECK_LIVE_FRAME (frame);
1121 return next_frame (frame, miniframe);
1124 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1125 doc: /* Return the previous frame in the frame list before FRAME.
1126 It considers only frames on the same terminal as FRAME.
1127 By default, skip minibuffer-only frames.
1128 If omitted, FRAME defaults to the selected frame.
1129 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1130 If MINIFRAME is a window, include only its own frame
1131 and any frame now using that window as the minibuffer.
1132 If MINIFRAME is `visible', include all visible frames.
1133 If MINIFRAME is 0, include all visible and iconified frames.
1134 Otherwise, include all frames. */)
1135 (frame, miniframe)
1136 Lisp_Object frame, miniframe;
1138 if (NILP (frame))
1139 frame = selected_frame;
1140 CHECK_LIVE_FRAME (frame);
1141 return prev_frame (frame, miniframe);
1144 /* Return 1 if it is ok to delete frame F;
1145 0 if all frames aside from F are invisible.
1146 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1149 other_visible_frames (f)
1150 FRAME_PTR f;
1152 /* We know the selected frame is visible,
1153 so if F is some other frame, it can't be the sole visible one. */
1154 if (f == SELECTED_FRAME ())
1156 Lisp_Object frames;
1157 int count = 0;
1159 for (frames = Vframe_list;
1160 CONSP (frames);
1161 frames = XCDR (frames))
1163 Lisp_Object this;
1165 this = XCAR (frames);
1166 /* Verify that the frame's window still exists
1167 and we can still talk to it. And note any recent change
1168 in visibility. */
1169 #ifdef HAVE_WINDOW_SYSTEM
1170 if (FRAME_WINDOW_P (XFRAME (this)))
1172 x_sync (XFRAME (this));
1173 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1175 #endif
1177 if (FRAME_VISIBLE_P (XFRAME (this))
1178 || FRAME_ICONIFIED_P (XFRAME (this))
1179 /* Allow deleting the terminal frame when at least
1180 one X frame exists! */
1181 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1182 count++;
1184 return count > 1;
1186 return 1;
1189 DEFUN ("other-visible-frames-p", Fother_visible_frames_p, Sother_visible_frames_p, 0, 1, 0,
1190 doc: /* Return t if there are other visible frames beside FRAME.
1191 FRAME defaults to the selected frame. */)
1192 (frame)
1193 Lisp_Object frame;
1195 if (NILP (frame))
1196 frame = selected_frame;
1197 CHECK_LIVE_FRAME (frame);
1198 return other_visible_frames (XFRAME (frame)) ? Qt : Qnil;
1201 /* Error handler for `delete-frame-functions'. */
1202 static Lisp_Object
1203 delete_frame_handler (Lisp_Object arg)
1205 add_to_log ("Error during `delete-frame': %s", arg, Qnil);
1206 return Qnil;
1209 extern Lisp_Object Qrun_hook_with_args;
1211 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1212 unconditionally. x_connection_closed and delete_terminal use
1213 this. Any other value of FORCE implements the semantics
1214 described for Fdelete_frame. */
1215 Lisp_Object
1216 delete_frame (frame, force)
1217 /* If we use `register' here, gcc-4.0.2 on amd64 using
1218 -DUSE_LISP_UNION_TYPE complains further down that we're getting the
1219 address of `force'. Go figure. */
1220 Lisp_Object frame, force;
1222 struct frame *f;
1223 struct frame *sf = SELECTED_FRAME ();
1224 struct kboard *kb;
1226 int minibuffer_selected;
1227 int tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
1229 if (EQ (frame, Qnil))
1231 f = sf;
1232 XSETFRAME (frame, f);
1234 else
1236 CHECK_FRAME (frame);
1237 f = XFRAME (frame);
1240 if (! FRAME_LIVE_P (f))
1241 return Qnil;
1243 if (NILP (force) && !other_visible_frames (f))
1244 error ("Attempt to delete the sole visible or iconified frame");
1246 /* x_connection_closed must have set FORCE to `noelisp' in order
1247 to delete the last frame, if it is gone. */
1248 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1249 error ("Attempt to delete the only frame");
1251 /* Does this frame have a minibuffer, and is it the surrogate
1252 minibuffer for any other frame? */
1253 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1255 Lisp_Object frames;
1257 for (frames = Vframe_list;
1258 CONSP (frames);
1259 frames = XCDR (frames))
1261 Lisp_Object this;
1262 this = XCAR (frames);
1264 if (! EQ (this, frame)
1265 && EQ (frame,
1266 WINDOW_FRAME (XWINDOW
1267 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1269 /* If we MUST delete this frame, delete the other first.
1270 But do this only if FORCE equals `noelisp'. */
1271 if (EQ (force, Qnoelisp))
1272 delete_frame (this, Qnoelisp);
1273 else
1274 error ("Attempt to delete a surrogate minibuffer frame");
1279 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1280 frame is a tooltip. FORCE is set to `noelisp' when handling
1281 a disconnect from the terminal, so we don't dare call Lisp
1282 code. */
1283 if (NILP (Vrun_hooks) || tooltip_frame)
1285 else if (EQ (force, Qnoelisp))
1286 pending_funcalls
1287 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1288 pending_funcalls);
1289 else
1290 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1292 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1293 if (! FRAME_LIVE_P (f))
1294 return Qnil;
1296 /* At this point, we are committed to deleting the frame.
1297 There is no more chance for errors to prevent it. */
1299 minibuffer_selected = EQ (minibuf_window, selected_window);
1301 /* Don't let the frame remain selected. */
1302 if (f == sf)
1304 Lisp_Object tail, frame1;
1306 /* Look for another visible frame on the same terminal. */
1307 frame1 = next_frame (frame, Qvisible);
1309 /* If there is none, find *some* other frame. */
1310 if (NILP (frame1) || EQ (frame1, frame))
1312 FOR_EACH_FRAME (tail, frame1)
1314 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1315 break;
1318 #ifdef NS_IMPL_COCOA
1319 else
1320 /* Under NS, there is no system mechanism for choosing a new
1321 window to get focus -- it is left to application code.
1322 So the portion of THIS application interfacing with NS
1323 needs to know about it. We call Fraise_frame, but the
1324 purpose is really to transfer focus. */
1325 Fraise_frame (frame1);
1326 #endif
1328 do_switch_frame (frame1, 0, 1, Qnil);
1329 sf = SELECTED_FRAME ();
1332 /* Don't allow minibuf_window to remain on a deleted frame. */
1333 if (EQ (f->minibuffer_window, minibuf_window))
1335 Fset_window_buffer (sf->minibuffer_window,
1336 XWINDOW (minibuf_window)->buffer, Qnil);
1337 minibuf_window = sf->minibuffer_window;
1339 /* If the dying minibuffer window was selected,
1340 select the new one. */
1341 if (minibuffer_selected)
1342 Fselect_window (minibuf_window, Qnil);
1345 /* Don't let echo_area_window to remain on a deleted frame. */
1346 if (EQ (f->minibuffer_window, echo_area_window))
1347 echo_area_window = sf->minibuffer_window;
1349 /* Clear any X selections for this frame. */
1350 #ifdef HAVE_X_WINDOWS
1351 if (FRAME_X_P (f))
1352 x_clear_frame_selections (f);
1353 #endif
1355 /* Free glyphs.
1356 This function must be called before the window tree of the
1357 frame is deleted because windows contain dynamically allocated
1358 memory. */
1359 free_glyphs (f);
1361 #ifdef HAVE_WINDOW_SYSTEM
1362 /* Give chance to each font driver to free a frame specific data. */
1363 font_update_drivers (f, Qnil);
1364 #endif
1366 /* Mark all the windows that used to be on FRAME as deleted, and then
1367 remove the reference to them. */
1368 delete_all_subwindows (f->root_window);
1369 f->root_window = Qnil;
1371 Vframe_list = Fdelq (frame, Vframe_list);
1372 FRAME_SET_VISIBLE (f, 0);
1374 /* Allow the vector of menu bar contents to be freed in the next
1375 garbage collection. The frame object itself may not be garbage
1376 collected until much later, because recent_keys and other data
1377 structures can still refer to it. */
1378 f->menu_bar_vector = Qnil;
1380 free_font_driver_list (f);
1381 xfree (f->namebuf);
1382 xfree (f->decode_mode_spec_buffer);
1383 xfree (FRAME_INSERT_COST (f));
1384 xfree (FRAME_DELETEN_COST (f));
1385 xfree (FRAME_INSERTN_COST (f));
1386 xfree (FRAME_DELETE_COST (f));
1387 xfree (FRAME_MESSAGE_BUF (f));
1389 /* Since some events are handled at the interrupt level, we may get
1390 an event for f at any time; if we zero out the frame's terminal
1391 now, then we may trip up the event-handling code. Instead, we'll
1392 promise that the terminal of the frame must be valid until we
1393 have called the window-system-dependent frame destruction
1394 routine. */
1396 if (FRAME_TERMINAL (f)->delete_frame_hook)
1397 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
1400 struct terminal *terminal = FRAME_TERMINAL (f);
1401 f->output_data.nothing = 0;
1402 f->terminal = 0; /* Now the frame is dead. */
1404 /* If needed, delete the terminal that this frame was on.
1405 (This must be done after the frame is killed.) */
1406 terminal->reference_count--;
1407 if (terminal->reference_count == 0)
1409 Lisp_Object tmp;
1410 XSETTERMINAL (tmp, terminal);
1412 kb = NULL;
1413 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
1415 else
1416 kb = terminal->kboard;
1419 /* If we've deleted the last_nonminibuf_frame, then try to find
1420 another one. */
1421 if (f == last_nonminibuf_frame)
1423 Lisp_Object frames;
1425 last_nonminibuf_frame = 0;
1427 for (frames = Vframe_list;
1428 CONSP (frames);
1429 frames = XCDR (frames))
1431 f = XFRAME (XCAR (frames));
1432 if (!FRAME_MINIBUF_ONLY_P (f))
1434 last_nonminibuf_frame = f;
1435 break;
1440 /* If there's no other frame on the same kboard, get out of
1441 single-kboard state if we're in it for this kboard. */
1442 if (kb != NULL)
1444 Lisp_Object frames;
1445 /* Some frame we found on the same kboard, or nil if there are none. */
1446 Lisp_Object frame_on_same_kboard;
1448 frame_on_same_kboard = Qnil;
1450 for (frames = Vframe_list;
1451 CONSP (frames);
1452 frames = XCDR (frames))
1454 Lisp_Object this;
1455 struct frame *f1;
1457 this = XCAR (frames);
1458 if (!FRAMEP (this))
1459 abort ();
1460 f1 = XFRAME (this);
1462 if (kb == FRAME_KBOARD (f1))
1463 frame_on_same_kboard = this;
1466 if (NILP (frame_on_same_kboard))
1467 not_single_kboard_state (kb);
1471 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1472 find another one. Prefer minibuffer-only frames, but also notice
1473 frames with other windows. */
1474 if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
1476 Lisp_Object frames;
1478 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1479 Lisp_Object frame_with_minibuf;
1480 /* Some frame we found on the same kboard, or nil if there are none. */
1481 Lisp_Object frame_on_same_kboard;
1483 frame_on_same_kboard = Qnil;
1484 frame_with_minibuf = Qnil;
1486 for (frames = Vframe_list;
1487 CONSP (frames);
1488 frames = XCDR (frames))
1490 Lisp_Object this;
1491 struct frame *f1;
1493 this = XCAR (frames);
1494 if (!FRAMEP (this))
1495 abort ();
1496 f1 = XFRAME (this);
1498 /* Consider only frames on the same kboard
1499 and only those with minibuffers. */
1500 if (kb == FRAME_KBOARD (f1)
1501 && FRAME_HAS_MINIBUF_P (f1))
1503 frame_with_minibuf = this;
1504 if (FRAME_MINIBUF_ONLY_P (f1))
1505 break;
1508 if (kb == FRAME_KBOARD (f1))
1509 frame_on_same_kboard = this;
1512 if (!NILP (frame_on_same_kboard))
1514 /* We know that there must be some frame with a minibuffer out
1515 there. If this were not true, all of the frames present
1516 would have to be minibufferless, which implies that at some
1517 point their minibuffer frames must have been deleted, but
1518 that is prohibited at the top; you can't delete surrogate
1519 minibuffer frames. */
1520 if (NILP (frame_with_minibuf))
1521 abort ();
1523 kb->Vdefault_minibuffer_frame = frame_with_minibuf;
1525 else
1526 /* No frames left on this kboard--say no minibuffer either. */
1527 kb->Vdefault_minibuffer_frame = Qnil;
1530 /* Cause frame titles to update--necessary if we now have just one frame. */
1531 if (!tooltip_frame)
1532 update_mode_lines = 1;
1534 return Qnil;
1537 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1538 doc: /* Delete FRAME, permanently eliminating it from use.
1539 FRAME defaults to the selected frame.
1541 A frame may not be deleted if its minibuffer is used by other frames.
1542 Normally, you may not delete a frame if all other frames are invisible,
1543 but if the second optional argument FORCE is non-nil, you may do so.
1545 This function runs `delete-frame-functions' before actually
1546 deleting the frame, unless the frame is a tooltip.
1547 The functions are run with one argument, the frame to be deleted. */)
1548 (frame, force)
1549 Lisp_Object frame, force;
1551 return delete_frame (frame, !NILP (force) ? Qt : Qnil);
1555 /* Return mouse position in character cell units. */
1557 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1558 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1559 The position is given in character cells, where (0, 0) is the
1560 upper-left corner of the frame, X is the horizontal offset, and Y is
1561 the vertical offset.
1562 If Emacs is running on a mouseless terminal or hasn't been programmed
1563 to read the mouse position, it returns the selected frame for FRAME
1564 and nil for X and Y.
1565 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1566 passing the normal return value to that function as an argument,
1567 and returns whatever that function returns. */)
1570 FRAME_PTR f;
1571 Lisp_Object lispy_dummy;
1572 enum scroll_bar_part party_dummy;
1573 Lisp_Object x, y, retval;
1574 int col, row;
1575 unsigned long long_dummy;
1576 struct gcpro gcpro1;
1578 f = SELECTED_FRAME ();
1579 x = y = Qnil;
1581 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1582 /* It's okay for the hook to refrain from storing anything. */
1583 if (FRAME_TERMINAL (f)->mouse_position_hook)
1584 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1585 &lispy_dummy, &party_dummy,
1586 &x, &y,
1587 &long_dummy);
1588 if (! NILP (x))
1590 col = XINT (x);
1591 row = XINT (y);
1592 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1593 XSETINT (x, col);
1594 XSETINT (y, row);
1596 #endif
1597 XSETFRAME (lispy_dummy, f);
1598 retval = Fcons (lispy_dummy, Fcons (x, y));
1599 GCPRO1 (retval);
1600 if (!NILP (Vmouse_position_function))
1601 retval = call1 (Vmouse_position_function, retval);
1602 RETURN_UNGCPRO (retval);
1605 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1606 Smouse_pixel_position, 0, 0, 0,
1607 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1608 The position is given in pixel units, where (0, 0) is the
1609 upper-left corner of the frame, X is the horizontal offset, and Y is
1610 the vertical offset.
1611 If Emacs is running on a mouseless terminal or hasn't been programmed
1612 to read the mouse position, it returns the selected frame for FRAME
1613 and nil for X and Y. */)
1616 FRAME_PTR f;
1617 Lisp_Object lispy_dummy;
1618 enum scroll_bar_part party_dummy;
1619 Lisp_Object x, y;
1620 unsigned long long_dummy;
1622 f = SELECTED_FRAME ();
1623 x = y = Qnil;
1625 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1626 /* It's okay for the hook to refrain from storing anything. */
1627 if (FRAME_TERMINAL (f)->mouse_position_hook)
1628 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1629 &lispy_dummy, &party_dummy,
1630 &x, &y,
1631 &long_dummy);
1632 #endif
1633 XSETFRAME (lispy_dummy, f);
1634 return Fcons (lispy_dummy, Fcons (x, y));
1637 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1638 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1639 Coordinates are relative to the frame, not a window,
1640 so the coordinates of the top left character in the frame
1641 may be nonzero due to left-hand scroll bars or the menu bar.
1643 The position is given in character cells, where (0, 0) is the
1644 upper-left corner of the frame, X is the horizontal offset, and Y is
1645 the vertical offset.
1647 This function is a no-op for an X frame that is not visible.
1648 If you have just created a frame, you must wait for it to become visible
1649 before calling this function on it, like this.
1650 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1651 (frame, x, y)
1652 Lisp_Object frame, x, y;
1654 CHECK_LIVE_FRAME (frame);
1655 CHECK_NUMBER (x);
1656 CHECK_NUMBER (y);
1658 /* I think this should be done with a hook. */
1659 #ifdef HAVE_WINDOW_SYSTEM
1660 if (FRAME_WINDOW_P (XFRAME (frame)))
1661 /* Warping the mouse will cause enternotify and focus events. */
1662 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1663 #else
1664 #if defined (MSDOS) && defined (HAVE_MOUSE)
1665 if (FRAME_MSDOS_P (XFRAME (frame)))
1667 Fselect_frame (frame, Qnil);
1668 mouse_moveto (XINT (x), XINT (y));
1670 #else
1671 #ifdef HAVE_GPM
1673 Fselect_frame (frame, Qnil);
1674 term_mouse_moveto (XINT (x), XINT (y));
1676 #endif
1677 #endif
1678 #endif
1680 return Qnil;
1683 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1684 Sset_mouse_pixel_position, 3, 3, 0,
1685 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1686 The position is given in pixels, where (0, 0) is the upper-left corner
1687 of the frame, X is the horizontal offset, and Y is the vertical offset.
1689 Note, this is a no-op for an X frame that is not visible.
1690 If you have just created a frame, you must wait for it to become visible
1691 before calling this function on it, like this.
1692 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1693 (frame, x, y)
1694 Lisp_Object frame, x, y;
1696 CHECK_LIVE_FRAME (frame);
1697 CHECK_NUMBER (x);
1698 CHECK_NUMBER (y);
1700 /* I think this should be done with a hook. */
1701 #ifdef HAVE_WINDOW_SYSTEM
1702 if (FRAME_WINDOW_P (XFRAME (frame)))
1703 /* Warping the mouse will cause enternotify and focus events. */
1704 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1705 #else
1706 #if defined (MSDOS) && defined (HAVE_MOUSE)
1707 if (FRAME_MSDOS_P (XFRAME (frame)))
1709 Fselect_frame (frame, Qnil);
1710 mouse_moveto (XINT (x), XINT (y));
1712 #else
1713 #ifdef HAVE_GPM
1715 Fselect_frame (frame, Qnil);
1716 term_mouse_moveto (XINT (x), XINT (y));
1718 #endif
1719 #endif
1720 #endif
1722 return Qnil;
1725 static void make_frame_visible_1 P_ ((Lisp_Object));
1727 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1728 0, 1, "",
1729 doc: /* Make the frame FRAME visible (assuming it is an X window).
1730 If omitted, FRAME defaults to the currently selected frame. */)
1731 (frame)
1732 Lisp_Object frame;
1734 if (NILP (frame))
1735 frame = selected_frame;
1737 CHECK_LIVE_FRAME (frame);
1739 /* I think this should be done with a hook. */
1740 #ifdef HAVE_WINDOW_SYSTEM
1741 if (FRAME_WINDOW_P (XFRAME (frame)))
1743 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1744 x_make_frame_visible (XFRAME (frame));
1746 #endif
1748 make_frame_visible_1 (XFRAME (frame)->root_window);
1750 /* Make menu bar update for the Buffers and Frames menus. */
1751 windows_or_buffers_changed++;
1753 return frame;
1756 /* Update the display_time slot of the buffers shown in WINDOW
1757 and all its descendents. */
1759 static void
1760 make_frame_visible_1 (window)
1761 Lisp_Object window;
1763 struct window *w;
1765 for (;!NILP (window); window = w->next)
1767 w = XWINDOW (window);
1769 if (!NILP (w->buffer))
1770 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1772 if (!NILP (w->vchild))
1773 make_frame_visible_1 (w->vchild);
1774 if (!NILP (w->hchild))
1775 make_frame_visible_1 (w->hchild);
1779 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1780 0, 2, "",
1781 doc: /* Make the frame FRAME invisible.
1782 If omitted, FRAME defaults to the currently selected frame.
1783 On graphical displays, invisible frames are not updated and are
1784 usually not displayed at all, even in a window system's \"taskbar\".
1786 Normally you may not make FRAME invisible if all other frames are invisible,
1787 but if the second optional argument FORCE is non-nil, you may do so.
1789 This function has no effect on text-only terminal frames. Such frames
1790 are always considered visible, whether or not they are currently being
1791 displayed in the terminal. */)
1792 (frame, force)
1793 Lisp_Object frame, force;
1795 if (NILP (frame))
1796 frame = selected_frame;
1798 CHECK_LIVE_FRAME (frame);
1800 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1801 error ("Attempt to make invisible the sole visible or iconified 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 do_switch_frame (next_frame (frame, Qt), 0, 0, Qnil)
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_make_frame_invisible (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 ("iconify-frame", Ficonify_frame, Siconify_frame,
1831 0, 1, "",
1832 doc: /* Make the frame FRAME into an icon.
1833 If omitted, FRAME defaults to the currently selected frame. */)
1834 (frame)
1835 Lisp_Object frame;
1837 if (NILP (frame))
1838 frame = selected_frame;
1840 CHECK_LIVE_FRAME (frame);
1842 #if 0 /* This isn't logically necessary, and it can do GC. */
1843 /* Don't let the frame remain selected. */
1844 if (EQ (frame, selected_frame))
1845 Fhandle_switch_frame (next_frame (frame, Qt));
1846 #endif
1848 /* Don't allow minibuf_window to remain on a deleted frame. */
1849 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1851 struct frame *sf = XFRAME (selected_frame);
1852 Fset_window_buffer (sf->minibuffer_window,
1853 XWINDOW (minibuf_window)->buffer, Qnil);
1854 minibuf_window = sf->minibuffer_window;
1857 /* I think this should be done with a hook. */
1858 #ifdef HAVE_WINDOW_SYSTEM
1859 if (FRAME_WINDOW_P (XFRAME (frame)))
1860 x_iconify_frame (XFRAME (frame));
1861 #endif
1863 /* Make menu bar update for the Buffers and Frames menus. */
1864 windows_or_buffers_changed++;
1866 return Qnil;
1869 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1870 1, 1, 0,
1871 doc: /* Return t if FRAME is \"visible\" (actually in use for display).
1872 Return the symbol `icon' if FRAME is iconified or \"minimized\".
1873 Return nil if FRAME was made invisible, via `make-frame-invisible'.
1874 On graphical displays, invisible frames are not updated and are
1875 usually not displayed at all, even in a window system's \"taskbar\".
1877 If FRAME is a text-only terminal frame, this always returns t.
1878 Such frames are always considered visible, whether or not they are
1879 currently being displayed on the terminal. */)
1880 (frame)
1881 Lisp_Object frame;
1883 CHECK_LIVE_FRAME (frame);
1885 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1887 if (FRAME_VISIBLE_P (XFRAME (frame)))
1888 return Qt;
1889 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1890 return Qicon;
1891 return Qnil;
1894 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1895 0, 0, 0,
1896 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1899 Lisp_Object tail, frame;
1900 struct frame *f;
1901 Lisp_Object value;
1903 value = Qnil;
1904 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1906 frame = XCAR (tail);
1907 if (!FRAMEP (frame))
1908 continue;
1909 f = XFRAME (frame);
1910 if (FRAME_VISIBLE_P (f))
1911 value = Fcons (frame, value);
1913 return value;
1917 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1918 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
1919 If FRAME is invisible or iconified, make it visible.
1920 If you don't specify a frame, the selected frame is used.
1921 If Emacs is displaying on an ordinary terminal or some other device which
1922 doesn't support multiple overlapping frames, this function selects FRAME. */)
1923 (frame)
1924 Lisp_Object frame;
1926 struct frame *f;
1927 if (NILP (frame))
1928 frame = selected_frame;
1930 CHECK_LIVE_FRAME (frame);
1932 f = XFRAME (frame);
1934 if (FRAME_TERMCAP_P (f))
1935 /* On a text-only terminal select FRAME. */
1936 Fselect_frame (frame, Qnil);
1937 else
1938 /* Do like the documentation says. */
1939 Fmake_frame_visible (frame);
1941 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1942 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
1944 return Qnil;
1947 /* Should we have a corresponding function called Flower_Power? */
1948 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1949 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
1950 If you don't specify a frame, the selected frame is used.
1951 If Emacs is displaying on an ordinary terminal or some other device which
1952 doesn't support multiple overlapping frames, this function does nothing. */)
1953 (frame)
1954 Lisp_Object frame;
1956 struct frame *f;
1958 if (NILP (frame))
1959 frame = selected_frame;
1961 CHECK_LIVE_FRAME (frame);
1963 f = XFRAME (frame);
1965 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1966 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
1968 return Qnil;
1972 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1973 1, 2, 0,
1974 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
1975 In other words, switch-frame events caused by events in FRAME will
1976 request a switch to FOCUS-FRAME, and `last-event-frame' will be
1977 FOCUS-FRAME after reading an event typed at FRAME.
1979 If FOCUS-FRAME is omitted or nil, any existing redirection is
1980 cancelled, and the frame again receives its own keystrokes.
1982 Focus redirection is useful for temporarily redirecting keystrokes to
1983 a surrogate minibuffer frame when a frame doesn't have its own
1984 minibuffer window.
1986 A frame's focus redirection can be changed by `select-frame'. If frame
1987 FOO is selected, and then a different frame BAR is selected, any
1988 frames redirecting their focus to FOO are shifted to redirect their
1989 focus to BAR. This allows focus redirection to work properly when the
1990 user switches from one frame to another using `select-window'.
1992 This means that a frame whose focus is redirected to itself is treated
1993 differently from a frame whose focus is redirected to nil; the former
1994 is affected by `select-frame', while the latter is not.
1996 The redirection lasts until `redirect-frame-focus' is called to change it. */)
1997 (frame, focus_frame)
1998 Lisp_Object frame, focus_frame;
2000 struct frame *f;
2002 /* Note that we don't check for a live frame here. It's reasonable
2003 to redirect the focus of a frame you're about to delete, if you
2004 know what other frame should receive those keystrokes. */
2005 CHECK_FRAME (frame);
2007 if (! NILP (focus_frame))
2008 CHECK_LIVE_FRAME (focus_frame);
2010 f = XFRAME (frame);
2012 f->focus_frame = focus_frame;
2014 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
2015 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
2017 return Qnil;
2021 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
2022 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
2023 This returns nil if FRAME's focus is not redirected.
2024 See `redirect-frame-focus'. */)
2025 (frame)
2026 Lisp_Object frame;
2028 CHECK_LIVE_FRAME (frame);
2030 return FRAME_FOCUS_FRAME (XFRAME (frame));
2035 /* Return the value of frame parameter PROP in frame FRAME. */
2037 Lisp_Object
2038 get_frame_param (frame, prop)
2039 register struct frame *frame;
2040 Lisp_Object prop;
2042 register Lisp_Object tem;
2044 tem = Fassq (prop, frame->param_alist);
2045 if (EQ (tem, Qnil))
2046 return tem;
2047 return Fcdr (tem);
2050 /* Return the buffer-predicate of the selected frame. */
2052 Lisp_Object
2053 frame_buffer_predicate (frame)
2054 Lisp_Object frame;
2056 return XFRAME (frame)->buffer_predicate;
2059 /* Return the buffer-list of the selected frame. */
2061 Lisp_Object
2062 frame_buffer_list (frame)
2063 Lisp_Object frame;
2065 return XFRAME (frame)->buffer_list;
2068 /* Set the buffer-list of the selected frame. */
2070 void
2071 set_frame_buffer_list (frame, list)
2072 Lisp_Object frame, list;
2074 XFRAME (frame)->buffer_list = list;
2077 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2079 void
2080 frames_discard_buffer (buffer)
2081 Lisp_Object buffer;
2083 Lisp_Object frame, tail;
2085 FOR_EACH_FRAME (tail, frame)
2087 XFRAME (frame)->buffer_list
2088 = Fdelq (buffer, XFRAME (frame)->buffer_list);
2089 XFRAME (frame)->buried_buffer_list
2090 = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
2094 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2095 If the alist already has an element for PROP, we change it. */
2097 void
2098 store_in_alist (alistptr, prop, val)
2099 Lisp_Object *alistptr, val;
2100 Lisp_Object prop;
2102 register Lisp_Object tem;
2104 tem = Fassq (prop, *alistptr);
2105 if (EQ (tem, Qnil))
2106 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2107 else
2108 Fsetcdr (tem, val);
2111 static int
2112 frame_name_fnn_p (str, len)
2113 char *str;
2114 EMACS_INT len;
2116 if (len > 1 && str[0] == 'F')
2118 char *end_ptr;
2120 strtol (str + 1, &end_ptr, 10);
2122 if (end_ptr == str + len)
2123 return 1;
2125 return 0;
2128 /* Set the name of the terminal frame. Also used by MSDOS frames.
2129 Modeled after x_set_name which is used for WINDOW frames. */
2131 static void
2132 set_term_frame_name (f, name)
2133 struct frame *f;
2134 Lisp_Object name;
2136 f->explicit_name = ! NILP (name);
2138 /* If NAME is nil, set the name to F<num>. */
2139 if (NILP (name))
2141 char namebuf[20];
2143 /* Check for no change needed in this very common case
2144 before we do any consing. */
2145 if (frame_name_fnn_p (SDATA (f->name),
2146 SBYTES (f->name)))
2147 return;
2149 tty_frame_count++;
2150 sprintf (namebuf, "F%d", tty_frame_count);
2151 name = build_string (namebuf);
2153 else
2155 CHECK_STRING (name);
2157 /* Don't change the name if it's already NAME. */
2158 if (! NILP (Fstring_equal (name, f->name)))
2159 return;
2161 /* Don't allow the user to set the frame name to F<num>, so it
2162 doesn't clash with the names we generate for terminal frames. */
2163 if (frame_name_fnn_p (SDATA (name), SBYTES (name)))
2164 error ("Frame names of the form F<num> are usurped by Emacs");
2167 f->name = name;
2168 update_mode_lines = 1;
2171 void
2172 store_frame_param (f, prop, val)
2173 struct frame *f;
2174 Lisp_Object prop, val;
2176 register Lisp_Object old_alist_elt;
2178 /* The buffer-list parameters are stored in a special place and not
2179 in the alist. */
2180 if (EQ (prop, Qbuffer_list))
2182 f->buffer_list = val;
2183 return;
2185 if (EQ (prop, Qburied_buffer_list))
2187 f->buried_buffer_list = val;
2188 return;
2191 /* If PROP is a symbol which is supposed to have frame-local values,
2192 and it is set up based on this frame, switch to the global
2193 binding. That way, we can create or alter the frame-local binding
2194 without messing up the symbol's status. */
2195 if (SYMBOLP (prop))
2197 struct Lisp_Symbol *sym = XSYMBOL (prop);
2198 start:
2199 switch (sym->redirect)
2201 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2202 case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
2203 case SYMBOL_LOCALIZED:
2204 { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
2205 if (blv->frame_local && BLV_FOUND (blv) && XFRAME (blv->where) == f)
2206 swap_in_global_binding (sym);
2207 break;
2209 default: abort ();
2213 /* The tty color needed to be set before the frame's parameter
2214 alist was updated with the new value. This is not true any more,
2215 but we still do this test early on. */
2216 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2217 && f == FRAME_TTY (f)->previous_frame)
2218 /* Force redisplay of this tty. */
2219 FRAME_TTY (f)->previous_frame = NULL;
2221 /* Update the frame parameter alist. */
2222 old_alist_elt = Fassq (prop, f->param_alist);
2223 if (EQ (old_alist_elt, Qnil))
2224 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
2225 else
2226 Fsetcdr (old_alist_elt, val);
2228 /* Update some other special parameters in their special places
2229 in addition to the alist. */
2231 if (EQ (prop, Qbuffer_predicate))
2232 f->buffer_predicate = val;
2234 if (! FRAME_WINDOW_P (f))
2236 if (EQ (prop, Qmenu_bar_lines))
2237 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2238 else if (EQ (prop, Qname))
2239 set_term_frame_name (f, val);
2242 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2244 if (! MINI_WINDOW_P (XWINDOW (val)))
2245 error ("Surrogate minibuffer windows must be minibuffer windows");
2247 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2248 && !EQ (val, f->minibuffer_window))
2249 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2251 /* Install the chosen minibuffer window, with proper buffer. */
2252 f->minibuffer_window = val;
2256 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2257 doc: /* Return the parameters-alist of frame FRAME.
2258 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2259 The meaningful PARMs depend on the kind of frame.
2260 If FRAME is omitted, return information on the currently selected frame. */)
2261 (frame)
2262 Lisp_Object frame;
2264 Lisp_Object alist;
2265 FRAME_PTR f;
2266 int height, width;
2267 struct gcpro gcpro1;
2269 if (NILP (frame))
2270 frame = selected_frame;
2272 CHECK_FRAME (frame);
2273 f = XFRAME (frame);
2275 if (!FRAME_LIVE_P (f))
2276 return Qnil;
2278 alist = Fcopy_alist (f->param_alist);
2279 GCPRO1 (alist);
2281 if (!FRAME_WINDOW_P (f))
2283 int fg = FRAME_FOREGROUND_PIXEL (f);
2284 int bg = FRAME_BACKGROUND_PIXEL (f);
2285 Lisp_Object elt;
2287 /* If the frame's parameter alist says the colors are
2288 unspecified and reversed, take the frame's background pixel
2289 for foreground and vice versa. */
2290 elt = Fassq (Qforeground_color, alist);
2291 if (CONSP (elt) && STRINGP (XCDR (elt)))
2293 if (strncmp (SDATA (XCDR (elt)),
2294 unspecified_bg,
2295 SCHARS (XCDR (elt))) == 0)
2296 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2297 else if (strncmp (SDATA (XCDR (elt)),
2298 unspecified_fg,
2299 SCHARS (XCDR (elt))) == 0)
2300 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2302 else
2303 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2304 elt = Fassq (Qbackground_color, alist);
2305 if (CONSP (elt) && STRINGP (XCDR (elt)))
2307 if (strncmp (SDATA (XCDR (elt)),
2308 unspecified_fg,
2309 SCHARS (XCDR (elt))) == 0)
2310 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2311 else if (strncmp (SDATA (XCDR (elt)),
2312 unspecified_bg,
2313 SCHARS (XCDR (elt))) == 0)
2314 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2316 else
2317 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2318 store_in_alist (&alist, intern ("font"),
2319 build_string (FRAME_MSDOS_P (f)
2320 ? "ms-dos"
2321 : FRAME_W32_P (f) ? "w32term"
2322 :"tty"));
2324 store_in_alist (&alist, Qname, f->name);
2325 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2326 store_in_alist (&alist, Qheight, make_number (height));
2327 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2328 store_in_alist (&alist, Qwidth, make_number (width));
2329 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2330 store_in_alist (&alist, Qminibuffer,
2331 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2332 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2333 : FRAME_MINIBUF_WINDOW (f)));
2334 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2335 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
2336 store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
2338 /* I think this should be done with a hook. */
2339 #ifdef HAVE_WINDOW_SYSTEM
2340 if (FRAME_WINDOW_P (f))
2341 x_report_frame_params (f, &alist);
2342 else
2343 #endif
2345 /* This ought to be correct in f->param_alist for an X frame. */
2346 Lisp_Object lines;
2347 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2348 store_in_alist (&alist, Qmenu_bar_lines, lines);
2351 UNGCPRO;
2352 return alist;
2356 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2357 doc: /* Return FRAME's value for parameter PARAMETER.
2358 If FRAME is nil, describe the currently selected frame. */)
2359 (frame, parameter)
2360 Lisp_Object frame, parameter;
2362 struct frame *f;
2363 Lisp_Object value;
2365 if (NILP (frame))
2366 frame = selected_frame;
2367 else
2368 CHECK_FRAME (frame);
2369 CHECK_SYMBOL (parameter);
2371 f = XFRAME (frame);
2372 value = Qnil;
2374 if (FRAME_LIVE_P (f))
2376 /* Avoid consing in frequent cases. */
2377 if (EQ (parameter, Qname))
2378 value = f->name;
2379 #ifdef HAVE_X_WINDOWS
2380 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2381 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2382 #endif /* HAVE_X_WINDOWS */
2383 else if (EQ (parameter, Qbackground_color)
2384 || EQ (parameter, Qforeground_color))
2386 value = Fassq (parameter, f->param_alist);
2387 if (CONSP (value))
2389 value = XCDR (value);
2390 /* Fframe_parameters puts the actual fg/bg color names,
2391 even if f->param_alist says otherwise. This is
2392 important when param_alist's notion of colors is
2393 "unspecified". We need to do the same here. */
2394 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2396 const char *color_name;
2397 EMACS_INT csz;
2399 if (EQ (parameter, Qbackground_color))
2401 color_name = SDATA (value);
2402 csz = SCHARS (value);
2403 if (strncmp (color_name, unspecified_bg, csz) == 0)
2404 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2405 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2406 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2408 else if (EQ (parameter, Qforeground_color))
2410 color_name = SDATA (value);
2411 csz = SCHARS (value);
2412 if (strncmp (color_name, unspecified_fg, csz) == 0)
2413 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2414 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2415 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2419 else
2420 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2422 else if (EQ (parameter, Qdisplay_type)
2423 || EQ (parameter, Qbackground_mode))
2424 value = Fcdr (Fassq (parameter, f->param_alist));
2425 else
2426 /* FIXME: Avoid this code path at all (as well as code duplication)
2427 by sharing more code with Fframe_parameters. */
2428 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2431 return value;
2435 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2436 Smodify_frame_parameters, 2, 2, 0,
2437 doc: /* Modify the parameters of frame FRAME according to ALIST.
2438 If FRAME is nil, it defaults to the selected frame.
2439 ALIST is an alist of parameters to change and their new values.
2440 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2441 The meaningful PARMs depend on the kind of frame.
2442 Undefined PARMs are ignored, but stored in the frame's parameter list
2443 so that `frame-parameters' will return them.
2445 The value of frame parameter FOO can also be accessed
2446 as a frame-local binding for the variable FOO, if you have
2447 enabled such bindings for that variable with `make-variable-frame-local'.
2448 Note that this functionality is obsolete as of Emacs 22.2, and its
2449 use is not recommended. Explicitly check for a frame-parameter instead. */)
2450 (frame, alist)
2451 Lisp_Object frame, alist;
2453 FRAME_PTR f;
2454 register Lisp_Object tail, prop, val;
2456 if (EQ (frame, Qnil))
2457 frame = selected_frame;
2458 CHECK_LIVE_FRAME (frame);
2459 f = XFRAME (frame);
2461 /* I think this should be done with a hook. */
2462 #ifdef HAVE_WINDOW_SYSTEM
2463 if (FRAME_WINDOW_P (f))
2464 x_set_frame_parameters (f, alist);
2465 else
2466 #endif
2467 #ifdef MSDOS
2468 if (FRAME_MSDOS_P (f))
2469 IT_set_frame_parameters (f, alist);
2470 else
2471 #endif
2474 int length = XINT (Flength (alist));
2475 int i;
2476 Lisp_Object *parms
2477 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2478 Lisp_Object *values
2479 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2481 /* Extract parm names and values into those vectors. */
2483 i = 0;
2484 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2486 Lisp_Object elt;
2488 elt = XCAR (tail);
2489 parms[i] = Fcar (elt);
2490 values[i] = Fcdr (elt);
2491 i++;
2494 /* Now process them in reverse of specified order. */
2495 for (i--; i >= 0; i--)
2497 prop = parms[i];
2498 val = values[i];
2499 store_frame_param (f, prop, val);
2501 /* Changing the background color might change the background
2502 mode, so that we have to load new defface specs.
2503 Call frame-set-background-mode to do that. */
2504 if (EQ (prop, Qbackground_color))
2505 call1 (Qframe_set_background_mode, frame);
2508 return Qnil;
2511 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2512 0, 1, 0,
2513 doc: /* Height in pixels of a line in the font in frame FRAME.
2514 If FRAME is omitted, the selected frame is used.
2515 For a terminal frame, the value is always 1. */)
2516 (frame)
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_char_height (f));
2529 else
2530 #endif
2531 return make_number (1);
2535 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2536 0, 1, 0,
2537 doc: /* Width in pixels of characters in the font in frame FRAME.
2538 If FRAME is omitted, the selected frame is used.
2539 On a graphical screen, the width is the standard width of the default font.
2540 For a terminal screen, the value is always 1. */)
2541 (frame)
2542 Lisp_Object frame;
2544 struct frame *f;
2546 if (NILP (frame))
2547 frame = selected_frame;
2548 CHECK_FRAME (frame);
2549 f = XFRAME (frame);
2551 #ifdef HAVE_WINDOW_SYSTEM
2552 if (FRAME_WINDOW_P (f))
2553 return make_number (x_char_width (f));
2554 else
2555 #endif
2556 return make_number (1);
2559 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2560 Sframe_pixel_height, 0, 1, 0,
2561 doc: /* Return a FRAME's height in pixels.
2562 If FRAME is omitted, the selected frame is used. The exact value
2563 of the result depends on the window-system and toolkit in use:
2565 In the Gtk+ version of Emacs, it includes only any window (including
2566 the minibuffer or eacho area), mode line, and header line. It does not
2567 include the tool bar or menu bar.
2569 With the Motif or Lucid toolkits, it also includes the tool bar (but
2570 not the menu bar).
2572 In a graphical version with no toolkit, it includes both the tool bar
2573 and menu bar.
2575 For a text-only terminal, it includes the menu bar. In this case, the
2576 result is really in characters rather than pixels (i.e., is identical
2577 to `frame-height'). */)
2578 (frame)
2579 Lisp_Object frame;
2581 struct frame *f;
2583 if (NILP (frame))
2584 frame = selected_frame;
2585 CHECK_FRAME (frame);
2586 f = XFRAME (frame);
2588 #ifdef HAVE_WINDOW_SYSTEM
2589 if (FRAME_WINDOW_P (f))
2590 return make_number (x_pixel_height (f));
2591 else
2592 #endif
2593 return make_number (FRAME_LINES (f));
2596 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2597 Sframe_pixel_width, 0, 1, 0,
2598 doc: /* Return FRAME's width in pixels.
2599 For a terminal frame, the result really gives the width in characters.
2600 If FRAME is omitted, the selected frame is used. */)
2601 (frame)
2602 Lisp_Object frame;
2604 struct frame *f;
2606 if (NILP (frame))
2607 frame = selected_frame;
2608 CHECK_FRAME (frame);
2609 f = XFRAME (frame);
2611 #ifdef HAVE_WINDOW_SYSTEM
2612 if (FRAME_WINDOW_P (f))
2613 return make_number (x_pixel_width (f));
2614 else
2615 #endif
2616 return make_number (FRAME_COLS (f));
2619 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2620 doc: /* Specify that the frame FRAME has LINES lines.
2621 Optional third arg non-nil means that redisplay should use LINES lines
2622 but that the idea of the actual height of the frame should not be changed. */)
2623 (frame, lines, pretend)
2624 Lisp_Object frame, lines, pretend;
2626 register struct frame *f;
2628 CHECK_NUMBER (lines);
2629 if (NILP (frame))
2630 frame = selected_frame;
2631 CHECK_LIVE_FRAME (frame);
2632 f = XFRAME (frame);
2634 /* I think this should be done with a hook. */
2635 #ifdef HAVE_WINDOW_SYSTEM
2636 if (FRAME_WINDOW_P (f))
2638 if (XINT (lines) != FRAME_LINES (f))
2639 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
2640 do_pending_window_change (0);
2642 else
2643 #endif
2644 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2645 return Qnil;
2648 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2649 doc: /* Specify that the frame FRAME has COLS columns.
2650 Optional third arg non-nil means that redisplay should use COLS columns
2651 but that the idea of the actual width of the frame should not be changed. */)
2652 (frame, cols, pretend)
2653 Lisp_Object frame, cols, pretend;
2655 register struct frame *f;
2656 CHECK_NUMBER (cols);
2657 if (NILP (frame))
2658 frame = selected_frame;
2659 CHECK_LIVE_FRAME (frame);
2660 f = XFRAME (frame);
2662 /* I think this should be done with a hook. */
2663 #ifdef HAVE_WINDOW_SYSTEM
2664 if (FRAME_WINDOW_P (f))
2666 if (XINT (cols) != FRAME_COLS (f))
2667 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
2668 do_pending_window_change (0);
2670 else
2671 #endif
2672 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2673 return Qnil;
2676 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2677 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2678 (frame, cols, rows)
2679 Lisp_Object frame, cols, rows;
2681 register struct frame *f;
2683 CHECK_LIVE_FRAME (frame);
2684 CHECK_NUMBER (cols);
2685 CHECK_NUMBER (rows);
2686 f = XFRAME (frame);
2688 /* I think this should be done with a hook. */
2689 #ifdef HAVE_WINDOW_SYSTEM
2690 if (FRAME_WINDOW_P (f))
2692 if (XINT (rows) != FRAME_LINES (f)
2693 || XINT (cols) != FRAME_COLS (f)
2694 || f->new_text_lines || f->new_text_cols)
2695 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2696 do_pending_window_change (0);
2698 else
2699 #endif
2700 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2702 return Qnil;
2705 DEFUN ("set-frame-position", Fset_frame_position,
2706 Sset_frame_position, 3, 3, 0,
2707 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2708 This is actually the position of the upper left corner of the frame.
2709 Negative values for XOFFSET or YOFFSET are interpreted relative to
2710 the rightmost or bottommost possible position (that stays within the screen). */)
2711 (frame, xoffset, yoffset)
2712 Lisp_Object frame, xoffset, yoffset;
2714 register struct frame *f;
2716 CHECK_LIVE_FRAME (frame);
2717 CHECK_NUMBER (xoffset);
2718 CHECK_NUMBER (yoffset);
2719 f = XFRAME (frame);
2721 /* I think this should be done with a hook. */
2722 #ifdef HAVE_WINDOW_SYSTEM
2723 if (FRAME_WINDOW_P (f))
2724 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2725 #endif
2727 return Qt;
2731 /***********************************************************************
2732 Frame Parameters
2733 ***********************************************************************/
2735 /* Connect the frame-parameter names for X frames
2736 to the ways of passing the parameter values to the window system.
2738 The name of a parameter, as a Lisp symbol,
2739 has an `x-frame-parameter' property which is an integer in Lisp
2740 that is an index in this table. */
2742 struct frame_parm_table {
2743 char *name;
2744 Lisp_Object *variable;
2747 static struct frame_parm_table frame_parms[] =
2749 {"auto-raise", &Qauto_raise},
2750 {"auto-lower", &Qauto_lower},
2751 {"background-color", 0},
2752 {"border-color", &Qborder_color},
2753 {"border-width", &Qborder_width},
2754 {"cursor-color", &Qcursor_color},
2755 {"cursor-type", &Qcursor_type},
2756 {"font", 0},
2757 {"foreground-color", 0},
2758 {"icon-name", &Qicon_name},
2759 {"icon-type", &Qicon_type},
2760 {"internal-border-width", &Qinternal_border_width},
2761 {"menu-bar-lines", &Qmenu_bar_lines},
2762 {"mouse-color", &Qmouse_color},
2763 {"name", &Qname},
2764 {"scroll-bar-width", &Qscroll_bar_width},
2765 {"title", &Qtitle},
2766 {"unsplittable", &Qunsplittable},
2767 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2768 {"visibility", &Qvisibility},
2769 {"tool-bar-lines", &Qtool_bar_lines},
2770 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2771 {"scroll-bar-background", &Qscroll_bar_background},
2772 {"screen-gamma", &Qscreen_gamma},
2773 {"line-spacing", &Qline_spacing},
2774 {"left-fringe", &Qleft_fringe},
2775 {"right-fringe", &Qright_fringe},
2776 {"wait-for-wm", &Qwait_for_wm},
2777 {"fullscreen", &Qfullscreen},
2778 {"font-backend", &Qfont_backend},
2779 {"alpha", &Qalpha},
2780 {"sticky", &Qsticky},
2783 #ifdef HAVE_WINDOW_SYSTEM
2785 extern Lisp_Object Qbox;
2786 extern Lisp_Object Qtop;
2788 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2789 wanted positions of the WM window (not Emacs window).
2790 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2791 window (FRAME_X_WINDOW).
2794 void
2795 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2796 struct frame *f;
2797 int *width;
2798 int *height;
2799 int *top_pos;
2800 int *left_pos;
2802 int newwidth = FRAME_COLS (f);
2803 int newheight = FRAME_LINES (f);
2804 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2806 *top_pos = f->top_pos;
2807 *left_pos = f->left_pos;
2809 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
2811 int ph;
2813 ph = x_display_pixel_height (dpyinfo);
2814 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2815 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2816 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2817 *top_pos = 0;
2820 if (f->want_fullscreen & FULLSCREEN_WIDTH)
2822 int pw;
2824 pw = x_display_pixel_width (dpyinfo);
2825 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2826 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2827 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2828 *left_pos = 0;
2831 *width = newwidth;
2832 *height = newheight;
2836 /* Change the parameters of frame F as specified by ALIST.
2837 If a parameter is not specially recognized, do nothing special;
2838 otherwise call the `x_set_...' function for that parameter.
2839 Except for certain geometry properties, always call store_frame_param
2840 to store the new value in the parameter alist. */
2842 void
2843 x_set_frame_parameters (f, alist)
2844 FRAME_PTR f;
2845 Lisp_Object alist;
2847 Lisp_Object tail;
2849 /* If both of these parameters are present, it's more efficient to
2850 set them both at once. So we wait until we've looked at the
2851 entire list before we set them. */
2852 int width, height;
2854 /* Same here. */
2855 Lisp_Object left, top;
2857 /* Same with these. */
2858 Lisp_Object icon_left, icon_top;
2860 /* Record in these vectors all the parms specified. */
2861 Lisp_Object *parms;
2862 Lisp_Object *values;
2863 int i, p;
2864 int left_no_change = 0, top_no_change = 0;
2865 int icon_left_no_change = 0, icon_top_no_change = 0;
2866 int size_changed = 0;
2867 struct gcpro gcpro1, gcpro2;
2869 i = 0;
2870 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2871 i++;
2873 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2874 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2876 /* Extract parm names and values into those vectors. */
2878 i = 0;
2879 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2881 Lisp_Object elt;
2883 elt = XCAR (tail);
2884 parms[i] = Fcar (elt);
2885 values[i] = Fcdr (elt);
2886 i++;
2888 /* TAIL and ALIST are not used again below here. */
2889 alist = tail = Qnil;
2891 GCPRO2 (*parms, *values);
2892 gcpro1.nvars = i;
2893 gcpro2.nvars = i;
2895 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2896 because their values appear in VALUES and strings are not valid. */
2897 top = left = Qunbound;
2898 icon_left = icon_top = Qunbound;
2900 /* Provide default values for HEIGHT and WIDTH. */
2901 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2902 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2904 /* Process foreground_color and background_color before anything else.
2905 They are independent of other properties, but other properties (e.g.,
2906 cursor_color) are dependent upon them. */
2907 /* Process default font as well, since fringe widths depends on it. */
2908 for (p = 0; p < i; p++)
2910 Lisp_Object prop, val;
2912 prop = parms[p];
2913 val = values[p];
2914 if (EQ (prop, Qforeground_color)
2915 || EQ (prop, Qbackground_color)
2916 || EQ (prop, Qfont))
2918 register Lisp_Object param_index, old_value;
2920 old_value = get_frame_param (f, prop);
2921 if (NILP (Fequal (val, old_value)))
2923 store_frame_param (f, prop, val);
2925 param_index = Fget (prop, Qx_frame_parameter);
2926 if (NATNUMP (param_index)
2927 && (XFASTINT (param_index)
2928 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2929 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2930 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2935 /* Now process them in reverse of specified order. */
2936 for (i--; i >= 0; i--)
2938 Lisp_Object prop, val;
2940 prop = parms[i];
2941 val = values[i];
2943 if (EQ (prop, Qwidth) && NATNUMP (val))
2945 size_changed = 1;
2946 width = XFASTINT (val);
2948 else if (EQ (prop, Qheight) && NATNUMP (val))
2950 size_changed = 1;
2951 height = XFASTINT (val);
2953 else if (EQ (prop, Qtop))
2954 top = val;
2955 else if (EQ (prop, Qleft))
2956 left = val;
2957 else if (EQ (prop, Qicon_top))
2958 icon_top = val;
2959 else if (EQ (prop, Qicon_left))
2960 icon_left = val;
2961 else if (EQ (prop, Qforeground_color)
2962 || EQ (prop, Qbackground_color)
2963 || EQ (prop, Qfont))
2964 /* Processed above. */
2965 continue;
2966 else
2968 register Lisp_Object param_index, old_value;
2970 old_value = get_frame_param (f, prop);
2972 store_frame_param (f, prop, val);
2974 param_index = Fget (prop, Qx_frame_parameter);
2975 if (NATNUMP (param_index)
2976 && (XFASTINT (param_index)
2977 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2978 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2979 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2983 /* Don't die if just one of these was set. */
2984 if (EQ (left, Qunbound))
2986 left_no_change = 1;
2987 if (f->left_pos < 0)
2988 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
2989 else
2990 XSETINT (left, f->left_pos);
2992 if (EQ (top, Qunbound))
2994 top_no_change = 1;
2995 if (f->top_pos < 0)
2996 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
2997 else
2998 XSETINT (top, f->top_pos);
3001 /* If one of the icon positions was not set, preserve or default it. */
3002 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
3004 icon_left_no_change = 1;
3005 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
3006 if (NILP (icon_left))
3007 XSETINT (icon_left, 0);
3009 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
3011 icon_top_no_change = 1;
3012 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
3013 if (NILP (icon_top))
3014 XSETINT (icon_top, 0);
3017 /* Don't set these parameters unless they've been explicitly
3018 specified. The window might be mapped or resized while we're in
3019 this function, and we don't want to override that unless the lisp
3020 code has asked for it.
3022 Don't set these parameters unless they actually differ from the
3023 window's current parameters; the window may not actually exist
3024 yet. */
3026 Lisp_Object frame;
3028 check_frame_size (f, &height, &width);
3030 XSETFRAME (frame, f);
3032 if (size_changed
3033 && (width != FRAME_COLS (f)
3034 || height != FRAME_LINES (f)
3035 || f->new_text_lines || f->new_text_cols))
3036 Fset_frame_size (frame, make_number (width), make_number (height));
3038 if ((!NILP (left) || !NILP (top))
3039 && ! (left_no_change && top_no_change)
3040 && ! (NUMBERP (left) && XINT (left) == f->left_pos
3041 && NUMBERP (top) && XINT (top) == f->top_pos))
3043 int leftpos = 0;
3044 int toppos = 0;
3046 /* Record the signs. */
3047 f->size_hint_flags &= ~ (XNegative | YNegative);
3048 if (EQ (left, Qminus))
3049 f->size_hint_flags |= XNegative;
3050 else if (INTEGERP (left))
3052 leftpos = XINT (left);
3053 if (leftpos < 0)
3054 f->size_hint_flags |= XNegative;
3056 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3057 && CONSP (XCDR (left))
3058 && INTEGERP (XCAR (XCDR (left))))
3060 leftpos = - XINT (XCAR (XCDR (left)));
3061 f->size_hint_flags |= XNegative;
3063 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3064 && CONSP (XCDR (left))
3065 && INTEGERP (XCAR (XCDR (left))))
3067 leftpos = XINT (XCAR (XCDR (left)));
3070 if (EQ (top, Qminus))
3071 f->size_hint_flags |= YNegative;
3072 else if (INTEGERP (top))
3074 toppos = XINT (top);
3075 if (toppos < 0)
3076 f->size_hint_flags |= YNegative;
3078 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3079 && CONSP (XCDR (top))
3080 && INTEGERP (XCAR (XCDR (top))))
3082 toppos = - XINT (XCAR (XCDR (top)));
3083 f->size_hint_flags |= YNegative;
3085 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3086 && CONSP (XCDR (top))
3087 && INTEGERP (XCAR (XCDR (top))))
3089 toppos = XINT (XCAR (XCDR (top)));
3093 /* Store the numeric value of the position. */
3094 f->top_pos = toppos;
3095 f->left_pos = leftpos;
3097 f->win_gravity = NorthWestGravity;
3099 /* Actually set that position, and convert to absolute. */
3100 x_set_offset (f, leftpos, toppos, -1);
3103 if ((!NILP (icon_left) || !NILP (icon_top))
3104 && ! (icon_left_no_change && icon_top_no_change))
3105 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3108 UNGCPRO;
3112 /* Insert a description of internally-recorded parameters of frame X
3113 into the parameter alist *ALISTPTR that is to be given to the user.
3114 Only parameters that are specific to the X window system
3115 and whose values are not correctly recorded in the frame's
3116 param_alist need to be considered here. */
3118 void
3119 x_report_frame_params (f, alistptr)
3120 struct frame *f;
3121 Lisp_Object *alistptr;
3123 char buf[16];
3124 Lisp_Object tem;
3126 /* Represent negative positions (off the top or left screen edge)
3127 in a way that Fmodify_frame_parameters will understand correctly. */
3128 XSETINT (tem, f->left_pos);
3129 if (f->left_pos >= 0)
3130 store_in_alist (alistptr, Qleft, tem);
3131 else
3132 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
3134 XSETINT (tem, f->top_pos);
3135 if (f->top_pos >= 0)
3136 store_in_alist (alistptr, Qtop, tem);
3137 else
3138 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
3140 store_in_alist (alistptr, Qborder_width,
3141 make_number (f->border_width));
3142 store_in_alist (alistptr, Qinternal_border_width,
3143 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
3144 store_in_alist (alistptr, Qleft_fringe,
3145 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
3146 store_in_alist (alistptr, Qright_fringe,
3147 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
3148 store_in_alist (alistptr, Qscroll_bar_width,
3149 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3150 ? make_number (0)
3151 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3152 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3153 /* nil means "use default width"
3154 for non-toolkit scroll bar.
3155 ruler-mode.el depends on this. */
3156 : Qnil));
3157 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
3158 store_in_alist (alistptr, Qwindow_id,
3159 build_string (buf));
3160 #ifdef HAVE_X_WINDOWS
3161 #ifdef USE_X_TOOLKIT
3162 /* Tooltip frame may not have this widget. */
3163 if (FRAME_X_OUTPUT (f)->widget)
3164 #endif
3165 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
3166 store_in_alist (alistptr, Qouter_window_id,
3167 build_string (buf));
3168 #endif
3169 store_in_alist (alistptr, Qicon_name, f->icon_name);
3170 FRAME_SAMPLE_VISIBILITY (f);
3171 store_in_alist (alistptr, Qvisibility,
3172 (FRAME_VISIBLE_P (f) ? Qt
3173 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3174 store_in_alist (alistptr, Qdisplay,
3175 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
3177 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
3178 tem = Qnil;
3179 else
3180 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
3181 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
3182 store_in_alist (alistptr, Qparent_id, tem);
3186 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3187 the previous value of that parameter, NEW_VALUE is the new value. */
3189 void
3190 x_set_fullscreen (f, new_value, old_value)
3191 struct frame *f;
3192 Lisp_Object new_value, old_value;
3194 if (NILP (new_value))
3195 f->want_fullscreen = FULLSCREEN_NONE;
3196 else if (EQ (new_value, Qfullboth) || EQ (new_value, Qfullscreen))
3197 f->want_fullscreen = FULLSCREEN_BOTH;
3198 else if (EQ (new_value, Qfullwidth))
3199 f->want_fullscreen = FULLSCREEN_WIDTH;
3200 else if (EQ (new_value, Qfullheight))
3201 f->want_fullscreen = FULLSCREEN_HEIGHT;
3202 else if (EQ (new_value, Qmaximized))
3203 f->want_fullscreen = FULLSCREEN_MAXIMIZED;
3205 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
3206 FRAME_TERMINAL (f)->fullscreen_hook (f);
3210 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3211 the previous value of that parameter, NEW_VALUE is the new value. */
3213 void
3214 x_set_line_spacing (f, new_value, old_value)
3215 struct frame *f;
3216 Lisp_Object new_value, old_value;
3218 if (NILP (new_value))
3219 f->extra_line_spacing = 0;
3220 else if (NATNUMP (new_value))
3221 f->extra_line_spacing = XFASTINT (new_value);
3222 else
3223 signal_error ("Invalid line-spacing", new_value);
3224 if (FRAME_VISIBLE_P (f))
3225 redraw_frame (f);
3229 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3230 the previous value of that parameter, NEW_VALUE is the new value. */
3232 void
3233 x_set_screen_gamma (f, new_value, old_value)
3234 struct frame *f;
3235 Lisp_Object new_value, old_value;
3237 Lisp_Object bgcolor;
3239 if (NILP (new_value))
3240 f->gamma = 0;
3241 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3242 /* The value 0.4545 is the normal viewing gamma. */
3243 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3244 else
3245 signal_error ("Invalid screen-gamma", new_value);
3247 /* Apply the new gamma value to the frame background. */
3248 bgcolor = Fassq (Qbackground_color, f->param_alist);
3249 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3251 Lisp_Object index = Fget (Qbackground_color, Qx_frame_parameter);
3252 if (NATNUMP (index)
3253 && (XFASTINT (index)
3254 < sizeof (frame_parms)/sizeof (frame_parms[0]))
3255 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
3256 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
3257 (f, bgcolor, Qnil);
3260 Fclear_face_cache (Qnil);
3264 void
3265 x_set_font (f, arg, oldval)
3266 struct frame *f;
3267 Lisp_Object arg, oldval;
3269 Lisp_Object frame, font_object, font_param = Qnil;
3270 int fontset = -1;
3272 /* Set the frame parameter back to the old value because we may
3273 fail to use ARG as the new parameter value. */
3274 store_frame_param (f, Qfont, oldval);
3276 /* ARG is a fontset name, a font name, a cons of fontset name and a
3277 font object, or a font object. In the last case, this function
3278 never fail. */
3279 if (STRINGP (arg))
3281 font_param = arg;
3282 fontset = fs_query_fontset (arg, 0);
3283 if (fontset < 0)
3285 font_object = font_open_by_name (f, SDATA (arg));
3286 if (NILP (font_object))
3287 error ("Font `%s' is not defined", SDATA (arg));
3288 arg = AREF (font_object, FONT_NAME_INDEX);
3290 else if (fontset > 0)
3292 Lisp_Object ascii_font = fontset_ascii (fontset);
3294 font_object = font_open_by_name (f, SDATA (ascii_font));
3295 if (NILP (font_object))
3296 error ("Font `%s' is not defined", SDATA (arg));
3297 arg = AREF (font_object, FONT_NAME_INDEX);
3299 else
3300 error ("The default fontset can't be used for a frame font");
3302 else if (CONSP (arg) && STRINGP (XCAR (arg)) && FONT_OBJECT_P (XCDR (arg)))
3304 /* This is the case that the ASCII font of F's fontset XCAR
3305 (arg) is changed to the font XCDR (arg) by
3306 `set-fontset-font'. */
3307 fontset = fs_query_fontset (XCAR (arg), 0);
3308 if (fontset < 0)
3309 error ("Unknown fontset: %s", SDATA (XCAR (arg)));
3310 font_object = XCDR (arg);
3311 arg = AREF (font_object, FONT_NAME_INDEX);
3312 font_param = Ffont_get (font_object, QCname);
3314 else if (FONT_OBJECT_P (arg))
3316 font_object = arg;
3317 font_param = Ffont_get (font_object, QCname);
3318 /* This is to store the XLFD font name in the frame parameter for
3319 backward compatibility. We should store the font-object
3320 itself in the future. */
3321 arg = AREF (font_object, FONT_NAME_INDEX);
3322 fontset = FRAME_FONTSET (f);
3323 /* Check if we can use the current fontset. If not, set FONTSET
3324 to -1 to generate a new fontset from FONT-OBJECT. */
3325 if (fontset >= 0)
3327 Lisp_Object ascii_font = fontset_ascii (fontset);
3328 Lisp_Object spec = font_spec_from_name (ascii_font);
3330 if (! font_match_p (spec, font_object))
3331 fontset = -1;
3334 else
3335 signal_error ("Invalid font", arg);
3337 if (! NILP (Fequal (font_object, oldval)))
3338 return;
3340 x_new_font (f, font_object, fontset);
3341 store_frame_param (f, Qfont, arg);
3342 #ifdef HAVE_X_WINDOWS
3343 store_frame_param (f, Qfont_param, font_param);
3344 #endif
3345 /* Recalculate toolbar height. */
3346 f->n_tool_bar_rows = 0;
3347 /* Ensure we redraw it. */
3348 clear_current_matrices (f);
3350 recompute_basic_faces (f);
3352 do_pending_window_change (0);
3354 /* We used to call face-set-after-frame-default here, but it leads to
3355 recursive calls (since that function can set the `default' face's
3356 font which in turns changes the frame's `font' parameter).
3357 Also I don't know what this call is meant to do, but it seems the
3358 wrong way to do it anyway (it does a lot more work than what seems
3359 reasonable in response to a change to `font'). */
3363 void
3364 x_set_font_backend (f, new_value, old_value)
3365 struct frame *f;
3366 Lisp_Object new_value, old_value;
3368 if (! NILP (new_value)
3369 && !CONSP (new_value))
3371 char *p0, *p1;
3373 CHECK_STRING (new_value);
3374 p0 = p1 = SDATA (new_value);
3375 new_value = Qnil;
3376 while (*p0)
3378 while (*p1 && ! isspace (*p1) && *p1 != ',') p1++;
3379 if (p0 < p1)
3380 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3381 new_value);
3382 if (*p1)
3384 int c;
3386 while ((c = *++p1) && isspace (c));
3388 p0 = p1;
3390 new_value = Fnreverse (new_value);
3393 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3394 return;
3396 if (FRAME_FONT (f))
3397 free_all_realized_faces (Qnil);
3399 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
3400 if (NILP (new_value))
3402 if (NILP (old_value))
3403 error ("No font backend available");
3404 font_update_drivers (f, old_value);
3405 error ("None of specified font backends are available");
3407 store_frame_param (f, Qfont_backend, new_value);
3409 if (FRAME_FONT (f))
3411 Lisp_Object frame;
3413 XSETFRAME (frame, f);
3414 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3415 ++face_change_count;
3416 ++windows_or_buffers_changed;
3421 void
3422 x_set_fringe_width (f, new_value, old_value)
3423 struct frame *f;
3424 Lisp_Object new_value, old_value;
3426 compute_fringe_widths (f, 1);
3429 void
3430 x_set_border_width (f, arg, oldval)
3431 struct frame *f;
3432 Lisp_Object arg, oldval;
3434 CHECK_NUMBER (arg);
3436 if (XINT (arg) == f->border_width)
3437 return;
3439 if (FRAME_X_WINDOW (f) != 0)
3440 error ("Cannot change the border width of a frame");
3442 f->border_width = XINT (arg);
3445 void
3446 x_set_internal_border_width (f, arg, oldval)
3447 struct frame *f;
3448 Lisp_Object arg, oldval;
3450 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
3452 CHECK_NUMBER (arg);
3453 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3454 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3455 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
3457 #ifdef USE_X_TOOLKIT
3458 if (FRAME_X_OUTPUT (f)->edit_widget)
3459 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3460 #endif
3462 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
3463 return;
3465 if (FRAME_X_WINDOW (f) != 0)
3467 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3468 SET_FRAME_GARBAGED (f);
3469 do_pending_window_change (0);
3471 else
3472 SET_FRAME_GARBAGED (f);
3475 void
3476 x_set_visibility (f, value, oldval)
3477 struct frame *f;
3478 Lisp_Object value, oldval;
3480 Lisp_Object frame;
3481 XSETFRAME (frame, f);
3483 if (NILP (value))
3484 Fmake_frame_invisible (frame, Qt);
3485 else if (EQ (value, Qicon))
3486 Ficonify_frame (frame);
3487 else
3488 Fmake_frame_visible (frame);
3491 void
3492 x_set_autoraise (f, arg, oldval)
3493 struct frame *f;
3494 Lisp_Object arg, oldval;
3496 f->auto_raise = !EQ (Qnil, arg);
3499 void
3500 x_set_autolower (f, arg, oldval)
3501 struct frame *f;
3502 Lisp_Object arg, oldval;
3504 f->auto_lower = !EQ (Qnil, arg);
3507 void
3508 x_set_unsplittable (f, arg, oldval)
3509 struct frame *f;
3510 Lisp_Object arg, oldval;
3512 f->no_split = !NILP (arg);
3515 void
3516 x_set_vertical_scroll_bars (f, arg, oldval)
3517 struct frame *f;
3518 Lisp_Object arg, oldval;
3520 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3521 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3522 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3523 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3525 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3526 = (NILP (arg)
3527 ? vertical_scroll_bar_none
3528 : EQ (Qleft, arg)
3529 ? vertical_scroll_bar_left
3530 : EQ (Qright, arg)
3531 ? vertical_scroll_bar_right
3532 : EQ (Qleft, Vdefault_frame_scroll_bars)
3533 ? vertical_scroll_bar_left
3534 : EQ (Qright, Vdefault_frame_scroll_bars)
3535 ? vertical_scroll_bar_right
3536 : vertical_scroll_bar_none);
3538 /* We set this parameter before creating the X window for the
3539 frame, so we can get the geometry right from the start.
3540 However, if the window hasn't been created yet, we shouldn't
3541 call x_set_window_size. */
3542 if (FRAME_X_WINDOW (f))
3543 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3544 do_pending_window_change (0);
3548 void
3549 x_set_scroll_bar_width (f, arg, oldval)
3550 struct frame *f;
3551 Lisp_Object arg, oldval;
3553 int wid = FRAME_COLUMN_WIDTH (f);
3555 if (NILP (arg))
3557 x_set_scroll_bar_default_width (f);
3559 if (FRAME_X_WINDOW (f))
3560 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3561 do_pending_window_change (0);
3563 else if (INTEGERP (arg) && XINT (arg) > 0
3564 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3566 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3567 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3569 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3570 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3571 if (FRAME_X_WINDOW (f))
3572 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3573 do_pending_window_change (0);
3576 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
3577 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3578 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3583 /* Return non-nil if frame F wants a bitmap icon. */
3585 Lisp_Object
3586 x_icon_type (f)
3587 FRAME_PTR f;
3589 Lisp_Object tem;
3591 tem = assq_no_quit (Qicon_type, f->param_alist);
3592 if (CONSP (tem))
3593 return XCDR (tem);
3594 else
3595 return Qnil;
3598 void
3599 x_set_alpha (f, arg, oldval)
3600 struct frame *f;
3601 Lisp_Object arg, oldval;
3603 double alpha = 1.0;
3604 double newval[2];
3605 int i, ialpha;
3606 Lisp_Object item;
3608 for (i = 0; i < 2; i++)
3610 newval[i] = 1.0;
3611 if (CONSP (arg))
3613 item = CAR (arg);
3614 arg = CDR (arg);
3616 else
3617 item = arg;
3619 if (NILP (item))
3620 alpha = - 1.0;
3621 else if (FLOATP (item))
3623 alpha = XFLOAT_DATA (item);
3624 if (alpha < 0.0 || 1.0 < alpha)
3625 args_out_of_range (make_float (0.0), make_float (1.0));
3627 else if (INTEGERP (item))
3629 ialpha = XINT (item);
3630 if (ialpha < 0 || 100 < ialpha)
3631 args_out_of_range (make_number (0), make_number (100));
3632 else
3633 alpha = ialpha / 100.0;
3635 else
3636 wrong_type_argument (Qnumberp, item);
3637 newval[i] = alpha;
3640 for (i = 0; i < 2; i++)
3641 f->alpha[i] = newval[i];
3643 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3644 BLOCK_INPUT;
3645 x_set_frame_alpha (f);
3646 UNBLOCK_INPUT;
3647 #endif
3649 return;
3653 /* Subroutines of creating an X frame. */
3655 /* Make sure that Vx_resource_name is set to a reasonable value.
3656 Fix it up, or set it to `emacs' if it is too hopeless. */
3658 void
3659 validate_x_resource_name ()
3661 int len = 0;
3662 /* Number of valid characters in the resource name. */
3663 int good_count = 0;
3664 /* Number of invalid characters in the resource name. */
3665 int bad_count = 0;
3666 Lisp_Object new;
3667 int i;
3669 if (!STRINGP (Vx_resource_class))
3670 Vx_resource_class = build_string (EMACS_CLASS);
3672 if (STRINGP (Vx_resource_name))
3674 unsigned char *p = SDATA (Vx_resource_name);
3675 int i;
3677 len = SBYTES (Vx_resource_name);
3679 /* Only letters, digits, - and _ are valid in resource names.
3680 Count the valid characters and count the invalid ones. */
3681 for (i = 0; i < len; i++)
3683 int c = p[i];
3684 if (! ((c >= 'a' && c <= 'z')
3685 || (c >= 'A' && c <= 'Z')
3686 || (c >= '0' && c <= '9')
3687 || c == '-' || c == '_'))
3688 bad_count++;
3689 else
3690 good_count++;
3693 else
3694 /* Not a string => completely invalid. */
3695 bad_count = 5, good_count = 0;
3697 /* If name is valid already, return. */
3698 if (bad_count == 0)
3699 return;
3701 /* If name is entirely invalid, or nearly so, use `emacs'. */
3702 if (good_count == 0
3703 || (good_count == 1 && bad_count > 0))
3705 Vx_resource_name = build_string ("emacs");
3706 return;
3709 /* Name is partly valid. Copy it and replace the invalid characters
3710 with underscores. */
3712 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3714 for (i = 0; i < len; i++)
3716 int c = SREF (new, i);
3717 if (! ((c >= 'a' && c <= 'z')
3718 || (c >= 'A' && c <= 'Z')
3719 || (c >= '0' && c <= '9')
3720 || c == '-' || c == '_'))
3721 SSET (new, i, '_');
3726 extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3727 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3730 /* Get specified attribute from resource database RDB.
3731 See Fx_get_resource below for other parameters. */
3733 static Lisp_Object
3734 xrdb_get_resource (rdb, attribute, class, component, subclass)
3735 XrmDatabase rdb;
3736 Lisp_Object attribute, class, component, subclass;
3738 register char *value;
3739 char *name_key;
3740 char *class_key;
3742 CHECK_STRING (attribute);
3743 CHECK_STRING (class);
3745 if (!NILP (component))
3746 CHECK_STRING (component);
3747 if (!NILP (subclass))
3748 CHECK_STRING (subclass);
3749 if (NILP (component) != NILP (subclass))
3750 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3752 validate_x_resource_name ();
3754 /* Allocate space for the components, the dots which separate them,
3755 and the final '\0'. Make them big enough for the worst case. */
3756 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3757 + (STRINGP (component)
3758 ? SBYTES (component) : 0)
3759 + SBYTES (attribute)
3760 + 3);
3762 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3763 + SBYTES (class)
3764 + (STRINGP (subclass)
3765 ? SBYTES (subclass) : 0)
3766 + 3);
3768 /* Start with emacs.FRAMENAME for the name (the specific one)
3769 and with `Emacs' for the class key (the general one). */
3770 strcpy (name_key, SDATA (Vx_resource_name));
3771 strcpy (class_key, SDATA (Vx_resource_class));
3773 strcat (class_key, ".");
3774 strcat (class_key, SDATA (class));
3776 if (!NILP (component))
3778 strcat (class_key, ".");
3779 strcat (class_key, SDATA (subclass));
3781 strcat (name_key, ".");
3782 strcat (name_key, SDATA (component));
3785 strcat (name_key, ".");
3786 strcat (name_key, SDATA (attribute));
3788 value = x_get_string_resource (rdb, name_key, class_key);
3790 if (value != (char *) 0 && *value)
3791 return build_string (value);
3792 else
3793 return Qnil;
3797 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3798 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3799 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3800 class, where INSTANCE is the name under which Emacs was invoked, or
3801 the name specified by the `-name' or `-rn' command-line arguments.
3803 The optional arguments COMPONENT and SUBCLASS add to the key and the
3804 class, respectively. You must specify both of them or neither.
3805 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3806 and the class is `Emacs.CLASS.SUBCLASS'. */)
3807 (attribute, class, component, subclass)
3808 Lisp_Object attribute, class, component, subclass;
3810 #ifdef HAVE_X_WINDOWS
3811 check_x ();
3812 #endif
3814 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3815 attribute, class, component, subclass);
3818 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3820 Lisp_Object
3821 display_x_get_resource (dpyinfo, attribute, class, component, subclass)
3822 Display_Info *dpyinfo;
3823 Lisp_Object attribute, class, component, subclass;
3825 return xrdb_get_resource (dpyinfo->xrdb,
3826 attribute, class, component, subclass);
3829 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
3830 /* Used when C code wants a resource value. */
3831 /* Called from oldXMenu/Create.c. */
3832 char *
3833 x_get_resource_string (attribute, class)
3834 char *attribute, *class;
3836 char *name_key;
3837 char *class_key;
3838 struct frame *sf = SELECTED_FRAME ();
3840 /* Allocate space for the components, the dots which separate them,
3841 and the final '\0'. */
3842 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3843 + strlen (attribute) + 2);
3844 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3845 + strlen (class) + 2);
3847 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3848 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3850 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3851 name_key, class_key);
3853 #endif
3855 /* Return the value of parameter PARAM.
3857 First search ALIST, then Vdefault_frame_alist, then the X defaults
3858 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3860 Convert the resource to the type specified by desired_type.
3862 If no default is specified, return Qunbound. If you call
3863 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3864 and don't let it get stored in any Lisp-visible variables! */
3866 Lisp_Object
3867 x_get_arg (dpyinfo, alist, param, attribute, class, type)
3868 Display_Info *dpyinfo;
3869 Lisp_Object alist, param;
3870 char *attribute;
3871 char *class;
3872 enum resource_types type;
3874 register Lisp_Object tem;
3876 tem = Fassq (param, alist);
3878 if (!NILP (tem))
3880 /* If we find this parm in ALIST, clear it out
3881 so that it won't be "left over" at the end. */
3882 Lisp_Object tail;
3883 XSETCAR (tem, Qnil);
3884 /* In case the parameter appears more than once in the alist,
3885 clear it out. */
3886 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3887 if (CONSP (XCAR (tail))
3888 && EQ (XCAR (XCAR (tail)), param))
3889 XSETCAR (XCAR (tail), Qnil);
3891 else
3892 tem = Fassq (param, Vdefault_frame_alist);
3894 /* If it wasn't specified in ALIST or the Lisp-level defaults,
3895 look in the X resources. */
3896 if (EQ (tem, Qnil))
3898 if (attribute && dpyinfo)
3900 tem = display_x_get_resource (dpyinfo,
3901 build_string (attribute),
3902 build_string (class),
3903 Qnil, Qnil);
3905 if (NILP (tem))
3906 return Qunbound;
3908 switch (type)
3910 case RES_TYPE_NUMBER:
3911 return make_number (atoi (SDATA (tem)));
3913 case RES_TYPE_BOOLEAN_NUMBER:
3914 if (!strcmp (SDATA (tem), "on")
3915 || !strcmp (SDATA (tem), "true"))
3916 return make_number (1);
3917 return make_number (atoi (SDATA (tem)));
3918 break;
3920 case RES_TYPE_FLOAT:
3921 return make_float (atof (SDATA (tem)));
3923 case RES_TYPE_BOOLEAN:
3924 tem = Fdowncase (tem);
3925 if (!strcmp (SDATA (tem), "on")
3926 #ifdef HAVE_NS
3927 || !strcmp(SDATA(tem), "yes")
3928 #endif
3929 || !strcmp (SDATA (tem), "true"))
3930 return Qt;
3931 else
3932 return Qnil;
3934 case RES_TYPE_STRING:
3935 return tem;
3937 case RES_TYPE_SYMBOL:
3938 /* As a special case, we map the values `true' and `on'
3939 to Qt, and `false' and `off' to Qnil. */
3941 Lisp_Object lower;
3942 lower = Fdowncase (tem);
3943 if (!strcmp (SDATA (lower), "on")
3944 #ifdef HAVE_NS
3945 || !strcmp(SDATA(lower), "yes")
3946 #endif
3947 || !strcmp (SDATA (lower), "true"))
3948 return Qt;
3949 else if (!strcmp (SDATA (lower), "off")
3950 #ifdef HAVE_NS
3951 || !strcmp(SDATA(lower), "no")
3952 #endif
3953 || !strcmp (SDATA (lower), "false"))
3954 return Qnil;
3955 else
3956 return Fintern (tem, Qnil);
3959 default:
3960 abort ();
3963 else
3964 return Qunbound;
3966 return Fcdr (tem);
3969 Lisp_Object
3970 x_frame_get_arg (f, alist, param, attribute, class, type)
3971 struct frame *f;
3972 Lisp_Object alist, param;
3973 char *attribute;
3974 char *class;
3975 enum resource_types type;
3977 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3978 alist, param, attribute, class, type);
3981 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
3983 Lisp_Object
3984 x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
3985 struct frame *f;
3986 Lisp_Object alist, param;
3987 char *attribute;
3988 char *class;
3989 enum resource_types type;
3991 Lisp_Object value;
3993 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3994 attribute, class, type);
3995 if (! NILP (value) && ! EQ (value, Qunbound))
3996 store_frame_param (f, param, value);
3998 return value;
4002 /* Record in frame F the specified or default value according to ALIST
4003 of the parameter named PROP (a Lisp symbol).
4004 If no value is specified for PROP, look for an X default for XPROP
4005 on the frame named NAME.
4006 If that is not found either, use the value DEFLT. */
4008 Lisp_Object
4009 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
4010 struct frame *f;
4011 Lisp_Object alist;
4012 Lisp_Object prop;
4013 Lisp_Object deflt;
4014 char *xprop;
4015 char *xclass;
4016 enum resource_types type;
4018 Lisp_Object tem;
4020 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
4021 if (EQ (tem, Qunbound))
4022 tem = deflt;
4023 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
4024 return tem;
4030 /* NS used to define x-parse-geometry in ns-win.el, but that confused
4031 make-docfile: the documentation string in ns-win.el was used for
4032 x-parse-geometry even in non-NS builds.
4034 With two definitions of x-parse-geometry in this file, various
4035 things still get confused (eg M-x apropos documentation), so that
4036 it is best if the two definitions just share the same doc-string.
4038 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4039 doc: /* Parse a display geometry string STRING.
4040 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4041 The properties returned may include `top', `left', `height', and `width'.
4042 For X, the value of `left' or `top' may be an integer,
4043 or a list (+ N) meaning N pixels relative to top/left corner,
4044 or a list (- N) meaning -N pixels relative to bottom/right corner.
4045 On Nextstep, this just calls `ns-parse-geometry'. */)
4046 (string)
4047 Lisp_Object string;
4049 #ifdef HAVE_NS
4050 call1 (Qns_parse_geometry, string);
4051 #else
4052 int geometry, x, y;
4053 unsigned int width, height;
4054 Lisp_Object result;
4056 CHECK_STRING (string);
4058 geometry = XParseGeometry ((char *) SDATA (string),
4059 &x, &y, &width, &height);
4060 result = Qnil;
4061 if (geometry & XValue)
4063 Lisp_Object element;
4065 if (x >= 0 && (geometry & XNegative))
4066 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
4067 else if (x < 0 && ! (geometry & XNegative))
4068 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
4069 else
4070 element = Fcons (Qleft, make_number (x));
4071 result = Fcons (element, result);
4074 if (geometry & YValue)
4076 Lisp_Object element;
4078 if (y >= 0 && (geometry & YNegative))
4079 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
4080 else if (y < 0 && ! (geometry & YNegative))
4081 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
4082 else
4083 element = Fcons (Qtop, make_number (y));
4084 result = Fcons (element, result);
4087 if (geometry & WidthValue)
4088 result = Fcons (Fcons (Qwidth, make_number (width)), result);
4089 if (geometry & HeightValue)
4090 result = Fcons (Fcons (Qheight, make_number (height)), result);
4092 return result;
4093 #endif /* HAVE_NS */
4097 /* Calculate the desired size and position of frame F.
4098 Return the flags saying which aspects were specified.
4100 Also set the win_gravity and size_hint_flags of F.
4102 Adjust height for toolbar if TOOLBAR_P is 1.
4104 This function does not make the coordinates positive. */
4106 #define DEFAULT_ROWS 35
4107 #define DEFAULT_COLS 80
4110 x_figure_window_size (f, parms, toolbar_p)
4111 struct frame *f;
4112 Lisp_Object parms;
4113 int toolbar_p;
4115 register Lisp_Object tem0, tem1, tem2;
4116 long window_prompting = 0;
4117 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4119 /* Default values if we fall through.
4120 Actually, if that happens we should get
4121 window manager prompting. */
4122 SET_FRAME_COLS (f, DEFAULT_COLS);
4123 FRAME_LINES (f) = DEFAULT_ROWS;
4124 /* Window managers expect that if program-specified
4125 positions are not (0,0), they're intentional, not defaults. */
4126 f->top_pos = 0;
4127 f->left_pos = 0;
4129 /* Ensure that old new_text_cols and new_text_lines will not override the
4130 values set here. */
4131 /* ++KFS: This was specific to W32, but seems ok for all platforms */
4132 f->new_text_cols = f->new_text_lines = 0;
4134 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4135 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4136 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4137 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4139 if (!EQ (tem0, Qunbound))
4141 CHECK_NUMBER (tem0);
4142 FRAME_LINES (f) = XINT (tem0);
4144 if (!EQ (tem1, Qunbound))
4146 CHECK_NUMBER (tem1);
4147 SET_FRAME_COLS (f, XINT (tem1));
4149 if (!NILP (tem2) && !EQ (tem2, Qunbound))
4150 window_prompting |= USSize;
4151 else
4152 window_prompting |= PSize;
4155 f->scroll_bar_actual_width
4156 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
4158 /* This used to be done _before_ calling x_figure_window_size, but
4159 since the height is reset here, this was really a no-op. I
4160 assume that moving it here does what Gerd intended (although he
4161 no longer can remember what that was... ++KFS, 2003-03-25. */
4163 /* Add the tool-bar height to the initial frame height so that the
4164 user gets a text display area of the size he specified with -g or
4165 via .Xdefaults. Later changes of the tool-bar height don't
4166 change the frame size. This is done so that users can create
4167 tall Emacs frames without having to guess how tall the tool-bar
4168 will get. */
4169 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4171 int margin, relief, bar_height;
4173 relief = (tool_bar_button_relief >= 0
4174 ? tool_bar_button_relief
4175 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4177 if (INTEGERP (Vtool_bar_button_margin)
4178 && XINT (Vtool_bar_button_margin) > 0)
4179 margin = XFASTINT (Vtool_bar_button_margin);
4180 else if (CONSP (Vtool_bar_button_margin)
4181 && INTEGERP (XCDR (Vtool_bar_button_margin))
4182 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
4183 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4184 else
4185 margin = 0;
4187 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4188 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
4191 compute_fringe_widths (f, 0);
4193 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
4194 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
4196 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4197 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4198 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4199 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4201 if (EQ (tem0, Qminus))
4203 f->top_pos = 0;
4204 window_prompting |= YNegative;
4206 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
4207 && CONSP (XCDR (tem0))
4208 && INTEGERP (XCAR (XCDR (tem0))))
4210 f->top_pos = - XINT (XCAR (XCDR (tem0)));
4211 window_prompting |= YNegative;
4213 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
4214 && CONSP (XCDR (tem0))
4215 && INTEGERP (XCAR (XCDR (tem0))))
4217 f->top_pos = XINT (XCAR (XCDR (tem0)));
4219 else if (EQ (tem0, Qunbound))
4220 f->top_pos = 0;
4221 else
4223 CHECK_NUMBER (tem0);
4224 f->top_pos = XINT (tem0);
4225 if (f->top_pos < 0)
4226 window_prompting |= YNegative;
4229 if (EQ (tem1, Qminus))
4231 f->left_pos = 0;
4232 window_prompting |= XNegative;
4234 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
4235 && CONSP (XCDR (tem1))
4236 && INTEGERP (XCAR (XCDR (tem1))))
4238 f->left_pos = - XINT (XCAR (XCDR (tem1)));
4239 window_prompting |= XNegative;
4241 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
4242 && CONSP (XCDR (tem1))
4243 && INTEGERP (XCAR (XCDR (tem1))))
4245 f->left_pos = XINT (XCAR (XCDR (tem1)));
4247 else if (EQ (tem1, Qunbound))
4248 f->left_pos = 0;
4249 else
4251 CHECK_NUMBER (tem1);
4252 f->left_pos = XINT (tem1);
4253 if (f->left_pos < 0)
4254 window_prompting |= XNegative;
4257 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
4258 window_prompting |= USPosition;
4259 else
4260 window_prompting |= PPosition;
4263 if (window_prompting & XNegative)
4265 if (window_prompting & YNegative)
4266 f->win_gravity = SouthEastGravity;
4267 else
4268 f->win_gravity = NorthEastGravity;
4270 else
4272 if (window_prompting & YNegative)
4273 f->win_gravity = SouthWestGravity;
4274 else
4275 f->win_gravity = NorthWestGravity;
4278 f->size_hint_flags = window_prompting;
4280 return window_prompting;
4285 #endif /* HAVE_WINDOW_SYSTEM */
4287 void
4288 frame_make_pointer_invisible ()
4290 if (! NILP (Vmake_pointer_invisible))
4292 struct frame *f;
4293 if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
4294 return;
4296 f = SELECTED_FRAME ();
4297 if (f && !f->pointer_invisible
4298 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4300 f->mouse_moved = 0;
4301 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 1);
4302 f->pointer_invisible = 1;
4307 void
4308 frame_make_pointer_visible ()
4310 /* We don't check Vmake_pointer_invisible here in case the
4311 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4312 struct frame *f;
4314 if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
4315 return;
4317 f = SELECTED_FRAME ();
4318 if (f && f->pointer_invisible && f->mouse_moved
4319 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4321 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 0);
4322 f->pointer_invisible = 0;
4328 /***********************************************************************
4329 Initialization
4330 ***********************************************************************/
4332 void
4333 syms_of_frame ()
4335 Qframep = intern_c_string ("framep");
4336 staticpro (&Qframep);
4337 Qframe_live_p = intern_c_string ("frame-live-p");
4338 staticpro (&Qframe_live_p);
4339 Qexplicit_name = intern_c_string ("explicit-name");
4340 staticpro (&Qexplicit_name);
4341 Qheight = intern_c_string ("height");
4342 staticpro (&Qheight);
4343 Qicon = intern_c_string ("icon");
4344 staticpro (&Qicon);
4345 Qminibuffer = intern_c_string ("minibuffer");
4346 staticpro (&Qminibuffer);
4347 Qmodeline = intern_c_string ("modeline");
4348 staticpro (&Qmodeline);
4349 Qonly = intern_c_string ("only");
4350 staticpro (&Qonly);
4351 Qwidth = intern_c_string ("width");
4352 staticpro (&Qwidth);
4353 Qgeometry = intern_c_string ("geometry");
4354 staticpro (&Qgeometry);
4355 Qicon_left = intern_c_string ("icon-left");
4356 staticpro (&Qicon_left);
4357 Qicon_top = intern_c_string ("icon-top");
4358 staticpro (&Qicon_top);
4359 Qleft = intern_c_string ("left");
4360 staticpro (&Qleft);
4361 Qright = intern_c_string ("right");
4362 staticpro (&Qright);
4363 Quser_position = intern_c_string ("user-position");
4364 staticpro (&Quser_position);
4365 Quser_size = intern_c_string ("user-size");
4366 staticpro (&Quser_size);
4367 Qwindow_id = intern_c_string ("window-id");
4368 staticpro (&Qwindow_id);
4369 #ifdef HAVE_X_WINDOWS
4370 Qouter_window_id = intern_c_string ("outer-window-id");
4371 staticpro (&Qouter_window_id);
4372 #endif
4373 Qparent_id = intern_c_string ("parent-id");
4374 staticpro (&Qparent_id);
4375 Qx = intern_c_string ("x");
4376 staticpro (&Qx);
4377 Qw32 = intern_c_string ("w32");
4378 staticpro (&Qw32);
4379 Qpc = intern_c_string ("pc");
4380 staticpro (&Qpc);
4381 Qmac = intern_c_string ("mac");
4382 staticpro (&Qmac);
4383 Qns = intern_c_string ("ns");
4384 staticpro (&Qns);
4385 Qvisible = intern_c_string ("visible");
4386 staticpro (&Qvisible);
4387 Qbuffer_predicate = intern_c_string ("buffer-predicate");
4388 staticpro (&Qbuffer_predicate);
4389 Qbuffer_list = intern_c_string ("buffer-list");
4390 staticpro (&Qbuffer_list);
4391 Qburied_buffer_list = intern_c_string ("buried-buffer-list");
4392 staticpro (&Qburied_buffer_list);
4393 Qdisplay_type = intern_c_string ("display-type");
4394 staticpro (&Qdisplay_type);
4395 Qbackground_mode = intern_c_string ("background-mode");
4396 staticpro (&Qbackground_mode);
4397 Qnoelisp = intern_c_string ("noelisp");
4398 staticpro (&Qnoelisp);
4399 Qtty_color_mode = intern_c_string ("tty-color-mode");
4400 staticpro (&Qtty_color_mode);
4401 Qtty = intern_c_string ("tty");
4402 staticpro (&Qtty);
4403 Qtty_type = intern_c_string ("tty-type");
4404 staticpro (&Qtty_type);
4406 Qface_set_after_frame_default = intern_c_string ("face-set-after-frame-default");
4407 staticpro (&Qface_set_after_frame_default);
4409 Qfullwidth = intern_c_string ("fullwidth");
4410 staticpro (&Qfullwidth);
4411 Qfullheight = intern_c_string ("fullheight");
4412 staticpro (&Qfullheight);
4413 Qfullboth = intern_c_string ("fullboth");
4414 staticpro (&Qfullboth);
4415 Qmaximized = intern_c_string ("maximized");
4416 staticpro (&Qmaximized);
4417 Qx_resource_name = intern_c_string ("x-resource-name");
4418 staticpro (&Qx_resource_name);
4420 Qx_frame_parameter = intern_c_string ("x-frame-parameter");
4421 staticpro (&Qx_frame_parameter);
4423 Qterminal = intern_c_string ("terminal");
4424 staticpro (&Qterminal);
4425 Qterminal_live_p = intern_c_string ("terminal-live-p");
4426 staticpro (&Qterminal_live_p);
4428 #ifdef HAVE_NS
4429 Qns_parse_geometry = intern_c_string ("ns-parse-geometry");
4430 staticpro (&Qns_parse_geometry);
4431 #endif
4434 int i;
4436 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4438 Lisp_Object v = intern_c_string (frame_parms[i].name);
4439 if (frame_parms[i].variable)
4441 *frame_parms[i].variable = v;
4442 staticpro (frame_parms[i].variable);
4444 Fput (v, Qx_frame_parameter, make_number (i));
4448 #ifdef HAVE_WINDOW_SYSTEM
4449 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4450 doc: /* The name Emacs uses to look up X resources.
4451 `x-get-resource' uses this as the first component of the instance name
4452 when requesting resource values.
4453 Emacs initially sets `x-resource-name' to the name under which Emacs
4454 was invoked, or to the value specified with the `-name' or `-rn'
4455 switches, if present.
4457 It may be useful to bind this variable locally around a call
4458 to `x-get-resource'. See also the variable `x-resource-class'. */);
4459 Vx_resource_name = Qnil;
4461 DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4462 doc: /* The class Emacs uses to look up X resources.
4463 `x-get-resource' uses this as the first component of the instance class
4464 when requesting resource values.
4466 Emacs initially sets `x-resource-class' to "Emacs".
4468 Setting this variable permanently is not a reasonable thing to do,
4469 but binding this variable locally around a call to `x-get-resource'
4470 is a reasonable practice. See also the variable `x-resource-name'. */);
4471 Vx_resource_class = build_string (EMACS_CLASS);
4473 DEFVAR_LISP ("frame-alpha-lower-limit", &Vframe_alpha_lower_limit,
4474 doc: /* The lower limit of the frame opacity (alpha transparency).
4475 The value should range from 0 (invisible) to 100 (completely opaque).
4476 You can also use a floating number between 0.0 and 1.0.
4477 The default is 20. */);
4478 Vframe_alpha_lower_limit = make_number (20);
4479 #endif
4481 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
4482 doc: /* Alist of default values for frame creation.
4483 These may be set in your init file, like this:
4484 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4485 These override values given in window system configuration data,
4486 including X Windows' defaults database.
4487 For values specific to the first Emacs frame, see `initial-frame-alist'.
4488 For window-system specific values, see `window-system-default-frame-alist'.
4489 For values specific to the separate minibuffer frame, see
4490 `minibuffer-frame-alist'.
4491 The `menu-bar-lines' element of the list controls whether new frames
4492 have menu bars; `menu-bar-mode' works by altering this element.
4493 Setting this variable does not affect existing frames, only new ones. */);
4494 Vdefault_frame_alist = Qnil;
4496 DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
4497 doc: /* Default position of scroll bars on this window-system. */);
4498 #ifdef HAVE_WINDOW_SYSTEM
4499 #if defined(HAVE_NTGUI) || defined(NS_IMPL_COCOA) || (defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS))
4500 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
4501 default. */
4502 Vdefault_frame_scroll_bars = Qright;
4503 #else
4504 Vdefault_frame_scroll_bars = Qleft;
4505 #endif
4506 #else
4507 Vdefault_frame_scroll_bars = Qnil;
4508 #endif
4510 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
4511 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4513 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
4514 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4515 `mouse-position' calls this function, passing its usual return value as
4516 argument, and returns whatever this function returns.
4517 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4518 which need to do mouse handling at the Lisp level. */);
4519 Vmouse_position_function = Qnil;
4521 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
4522 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4523 If the value is an integer, highlighting is only shown after moving the
4524 mouse, while keyboard input turns off the highlight even when the mouse
4525 is over the clickable text. However, the mouse shape still indicates
4526 when the mouse is over clickable text. */);
4527 Vmouse_highlight = Qt;
4529 DEFVAR_LISP ("make-pointer-invisible", &Vmake_pointer_invisible,
4530 doc: /* If non-nil, make pointer invisible while typing.
4531 The pointer becomes visible again when the mouse is moved. */);
4532 Vmake_pointer_invisible = Qt;
4534 DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
4535 doc: /* Functions to be run before deleting a frame.
4536 The functions are run with one arg, the frame to be deleted.
4537 See `delete-frame'.
4539 Note that functions in this list may be called just before the frame is
4540 actually deleted, or some time later (or even both when an earlier function
4541 in `delete-frame-functions' (indirectly) calls `delete-frame'
4542 recursively). */);
4543 Vdelete_frame_functions = Qnil;
4544 Qdelete_frame_functions = intern_c_string ("delete-frame-functions");
4545 staticpro (&Qdelete_frame_functions);
4547 DEFVAR_LISP ("menu-bar-mode", &Vmenu_bar_mode,
4548 doc: /* Non-nil if Menu-Bar mode is enabled. */);
4549 Vmenu_bar_mode = Qt;
4551 DEFVAR_LISP ("tool-bar-mode", &Vtool_bar_mode,
4552 doc: /* Non-nil if Tool-Bar mode is enabled. */);
4553 Vtool_bar_mode = Qt;
4555 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4556 doc: /* Minibufferless frames use this frame's minibuffer.
4558 Emacs cannot create minibufferless frames unless this is set to an
4559 appropriate surrogate.
4561 Emacs consults this variable only when creating minibufferless
4562 frames; once the frame is created, it sticks with its assigned
4563 minibuffer, no matter what this variable is set to. This means that
4564 this variable doesn't necessarily say anything meaningful about the
4565 current set of frames, or where the minibuffer is currently being
4566 displayed.
4568 This variable is local to the current terminal and cannot be buffer-local. */);
4570 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse,
4571 doc: /* Non-nil if window system changes focus when you move the mouse.
4572 You should set this variable to tell Emacs how your window manager
4573 handles focus, since there is no way in general for Emacs to find out
4574 automatically. See also `mouse-autoselect-window'. */);
4575 #ifdef HAVE_WINDOW_SYSTEM
4576 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
4577 focus_follows_mouse = 0;
4578 #else
4579 focus_follows_mouse = 1;
4580 #endif
4581 #else
4582 focus_follows_mouse = 0;
4583 #endif
4585 staticpro (&Vframe_list);
4587 defsubr (&Sframep);
4588 defsubr (&Sframe_live_p);
4589 defsubr (&Swindow_system);
4590 defsubr (&Smake_terminal_frame);
4591 defsubr (&Shandle_switch_frame);
4592 defsubr (&Sselect_frame);
4593 defsubr (&Sselected_frame);
4594 defsubr (&Sframe_list);
4595 defsubr (&Snext_frame);
4596 defsubr (&Sprevious_frame);
4597 defsubr (&Sother_visible_frames_p);
4598 defsubr (&Sdelete_frame);
4599 defsubr (&Smouse_position);
4600 defsubr (&Smouse_pixel_position);
4601 defsubr (&Sset_mouse_position);
4602 defsubr (&Sset_mouse_pixel_position);
4603 #if 0
4604 defsubr (&Sframe_configuration);
4605 defsubr (&Srestore_frame_configuration);
4606 #endif
4607 defsubr (&Smake_frame_visible);
4608 defsubr (&Smake_frame_invisible);
4609 defsubr (&Siconify_frame);
4610 defsubr (&Sframe_visible_p);
4611 defsubr (&Svisible_frame_list);
4612 defsubr (&Sraise_frame);
4613 defsubr (&Slower_frame);
4614 defsubr (&Sredirect_frame_focus);
4615 defsubr (&Sframe_focus);
4616 defsubr (&Sframe_parameters);
4617 defsubr (&Sframe_parameter);
4618 defsubr (&Smodify_frame_parameters);
4619 defsubr (&Sframe_char_height);
4620 defsubr (&Sframe_char_width);
4621 defsubr (&Sframe_pixel_height);
4622 defsubr (&Sframe_pixel_width);
4623 defsubr (&Sset_frame_height);
4624 defsubr (&Sset_frame_width);
4625 defsubr (&Sset_frame_size);
4626 defsubr (&Sset_frame_position);
4628 #ifdef HAVE_WINDOW_SYSTEM
4629 defsubr (&Sx_get_resource);
4630 defsubr (&Sx_parse_geometry);
4631 #endif
4635 /* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039
4636 (do not change this comment) */