emacs-lisp/package.el (package--read-pkg-desc): Fix tar-desc reference.
[emacs.git] / src / frame.c
blob890e8972617069b00ac6b09c8c5274496a7b4bf1
1 /* Generic frame functions.
3 Copyright (C) 1993-1995, 1997, 1999-2015 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 <errno.h>
24 #include <limits.h>
26 #include <c-ctype.h>
28 #include "lisp.h"
29 #include "character.h"
31 #ifdef HAVE_WINDOW_SYSTEM
32 #include TERM_HEADER
33 #endif /* HAVE_WINDOW_SYSTEM */
35 #include "buffer.h"
36 /* These help us bind and responding to switch-frame events. */
37 #include "commands.h"
38 #include "keyboard.h"
39 #include "frame.h"
40 #include "blockinput.h"
41 #include "termchar.h"
42 #include "termhooks.h"
43 #include "dispextern.h"
44 #include "window.h"
45 #include "font.h"
46 #ifdef HAVE_WINDOW_SYSTEM
47 #include "fontset.h"
48 #endif
49 #include "cm.h"
50 #ifdef MSDOS
51 #include "msdos.h"
52 #include "dosfns.h"
53 #endif
54 #ifdef USE_X_TOOLKIT
55 #include "widget.h"
56 #endif
58 /* The currently selected frame. */
60 Lisp_Object selected_frame;
62 /* A frame which is not just a mini-buffer, or NULL if there are no such
63 frames. This is usually the most recent such frame that was selected. */
65 static struct frame *last_nonminibuf_frame;
67 /* False means there are no visible garbaged frames. */
68 bool frame_garbaged;
70 /* The default tool bar height for future frames. */
71 #if defined USE_GTK || defined HAVE_NS
72 enum { frame_default_tool_bar_height = 0 };
73 #else
74 int frame_default_tool_bar_height;
75 #endif
77 #ifdef HAVE_WINDOW_SYSTEM
78 static void x_report_frame_params (struct frame *, Lisp_Object *);
79 #endif
81 /* These setters are used only in this file, so they can be private. */
82 static void
83 fset_buffer_predicate (struct frame *f, Lisp_Object val)
85 f->buffer_predicate = val;
87 static void
88 fset_minibuffer_window (struct frame *f, Lisp_Object val)
90 f->minibuffer_window = val;
93 struct frame *
94 decode_live_frame (register Lisp_Object frame)
96 if (NILP (frame))
97 frame = selected_frame;
98 CHECK_LIVE_FRAME (frame);
99 return XFRAME (frame);
102 struct frame *
103 decode_any_frame (register Lisp_Object frame)
105 if (NILP (frame))
106 frame = selected_frame;
107 CHECK_FRAME (frame);
108 return XFRAME (frame);
111 #ifdef HAVE_WINDOW_SYSTEM
113 bool
114 window_system_available (struct frame *f)
116 return f ? FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f) : x_display_list != NULL;
119 #endif /* HAVE_WINDOW_SYSTEM */
121 struct frame *
122 decode_window_system_frame (Lisp_Object frame)
124 struct frame *f = decode_live_frame (frame);
126 if (!window_system_available (f))
127 error ("Window system frame should be used");
128 return f;
131 void
132 check_window_system (struct frame *f)
134 if (!window_system_available (f))
135 error (f ? "Window system frame should be used"
136 : "Window system is not in use or not initialized");
139 /* Return the value of frame parameter PROP in frame FRAME. */
141 Lisp_Object
142 get_frame_param (register struct frame *frame, Lisp_Object prop)
144 register Lisp_Object tem;
146 tem = Fassq (prop, frame->param_alist);
147 if (EQ (tem, Qnil))
148 return tem;
149 return Fcdr (tem);
152 /* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
153 state of frame F would be affected by a vertical (horizontal if
154 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
155 parameter that is changed. */
156 bool
157 frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
159 return (EQ (frame_inhibit_implied_resize, Qt)
160 || (CONSP (frame_inhibit_implied_resize)
161 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))
162 || !NILP (get_frame_param (f, Qfullscreen))
163 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
166 static void
167 set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
169 int nlines;
170 int olines = FRAME_MENU_BAR_LINES (f);
172 /* Right now, menu bars don't work properly in minibuf-only frames;
173 most of the commands try to apply themselves to the minibuffer
174 frame itself, and get an error because you can't switch buffers
175 in or split the minibuffer window. */
176 if (FRAME_MINIBUF_ONLY_P (f))
177 return;
179 if (TYPE_RANGED_INTEGERP (int, value))
180 nlines = XINT (value);
181 else
182 nlines = 0;
184 if (nlines != olines)
186 windows_or_buffers_changed = 14;
187 FRAME_MENU_BAR_LINES (f) = nlines;
188 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
189 change_frame_size (f, FRAME_COLS (f),
190 FRAME_LINES (f) + olines - nlines,
191 0, 1, 0, 0);
195 Lisp_Object Vframe_list;
198 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
199 doc: /* Return non-nil if OBJECT is a frame.
200 Value is:
201 t for a termcap frame (a character-only terminal),
202 'x' for an Emacs frame that is really an X window,
203 'w32' for an Emacs frame that is a window on MS-Windows display,
204 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
205 'pc' for a direct-write MS-DOS frame.
206 See also `frame-live-p'. */)
207 (Lisp_Object object)
209 if (!FRAMEP (object))
210 return Qnil;
211 switch (XFRAME (object)->output_method)
213 case output_initial: /* The initial frame is like a termcap frame. */
214 case output_termcap:
215 return Qt;
216 case output_x_window:
217 return Qx;
218 case output_w32:
219 return Qw32;
220 case output_msdos_raw:
221 return Qpc;
222 case output_ns:
223 return Qns;
224 default:
225 emacs_abort ();
229 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
230 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
231 Value is nil if OBJECT is not a live frame. If object is a live
232 frame, the return value indicates what sort of terminal device it is
233 displayed on. See the documentation of `framep' for possible
234 return values. */)
235 (Lisp_Object object)
237 return ((FRAMEP (object)
238 && FRAME_LIVE_P (XFRAME (object)))
239 ? Fframep (object)
240 : Qnil);
243 DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
244 doc: /* The name of the window system that FRAME is displaying through.
245 The value is a symbol:
246 nil for a termcap frame (a character-only terminal),
247 'x' for an Emacs frame that is really an X window,
248 'w32' for an Emacs frame that is a window on MS-Windows display,
249 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
250 'pc' for a direct-write MS-DOS frame.
252 FRAME defaults to the currently selected frame.
254 Use of this function as a predicate is deprecated. Instead,
255 use `display-graphic-p' or any of the other `display-*-p'
256 predicates which report frame's specific UI-related capabilities. */)
257 (Lisp_Object frame)
259 Lisp_Object type;
260 if (NILP (frame))
261 frame = selected_frame;
263 type = Fframep (frame);
265 if (NILP (type))
266 wrong_type_argument (Qframep, frame);
268 if (EQ (type, Qt))
269 return Qnil;
270 else
271 return type;
274 /* Placeholder used by temacs -nw before window.el is loaded. */
275 DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
276 Sframe_windows_min_size, 4, 4, 0,
277 doc: /* */
278 attributes: const)
279 (Lisp_Object frame, Lisp_Object horizontal,
280 Lisp_Object ignore, Lisp_Object pixelwise)
282 return make_number (0);
285 static int
286 frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
287 Lisp_Object ignore, Lisp_Object pixelwise)
289 return XINT (call4 (Qframe_windows_min_size, frame, horizontal,
290 ignore, pixelwise));
294 /* Make sure windows sizes of frame F are OK. new_width and new_height
295 are in pixels. A value of -1 means no change is requested for that
296 size (but the frame may still have to be resized to accommodate
297 windows with their minimum sizes). This can either issue a request
298 to resize the frame externally (via x_set_window_size), to resize the
299 frame internally (via resize_frame_windows) or do nothing at all.
301 The argument INHIBIT can assume the following values:
303 0 means to unconditionally call x_set_window_size even if sizes
304 apparently do not change. Fx_create_frame uses this to pass the
305 initial size to the window manager.
307 1 means to call x_set_window_size if the outer frame size really
308 changes. Fset_frame_size, Fset_frame_height, ... use this.
310 2 means to call x_set_window_size provided frame_inhibit_resize
311 allows it. The menu and tool bar code use this ("3" won't work
312 here in general because menu and tool bar are often not counted in
313 the frame's text height).
315 3 means call x_set_window_size if window minimum sizes must be
316 preserved or frame_inhibit_resize allows it. x_set_left_fringe,
317 x_set_scroll_bar_width, x_new_font ... use (or should use) this.
319 4 means call x_set_window_size only if window minimum sizes must be
320 preserved. x_set_right_divider_width, x_set_border_width and the
321 code responsible for wrapping the tool bar use this.
323 5 means to never call x_set_window_size. change_frame_size uses
324 this.
326 Note that even when x_set_window_size is not called, individual
327 windows may have to be resized (via `window--sanitize-window-sizes')
328 in order to support minimum size constraints.
330 PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
331 symbol of the parameter changed (like `menu-bar-lines', `font', ...).
332 This is passed on to frame_inhibit_resize to let the latter decide on
333 a case-by-case basis whether the frame may be resized externally. */
334 void
335 adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
336 bool pretend, Lisp_Object parameter)
338 int unit_width = FRAME_COLUMN_WIDTH (f);
339 int unit_height = FRAME_LINE_HEIGHT (f);
340 int old_pixel_width = FRAME_PIXEL_WIDTH (f);
341 int old_pixel_height = FRAME_PIXEL_HEIGHT (f);
342 int old_cols = FRAME_COLS (f);
343 int old_lines = FRAME_LINES (f);
344 int new_pixel_width, new_pixel_height;
345 /* The following two values are calculated from the old frame pixel
346 sizes and any "new" settings for tool bar, menu bar and internal
347 borders. We do it this way to detect whether we have to call
348 x_set_window_size as consequence of the new settings. */
349 int windows_width = FRAME_WINDOWS_WIDTH (f);
350 int windows_height = FRAME_WINDOWS_HEIGHT (f);
351 int min_windows_width, min_windows_height;
352 /* These are a bit tedious, maybe we should use a macro. */
353 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
354 int old_windows_width = WINDOW_PIXEL_WIDTH (r);
355 int old_windows_height
356 = (WINDOW_PIXEL_HEIGHT (r)
357 + (FRAME_HAS_MINIBUF_P (f)
358 ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f)))
359 : 0));
360 int new_windows_width, new_windows_height;
361 int old_text_width = FRAME_TEXT_WIDTH (f);
362 int old_text_height = FRAME_TEXT_HEIGHT (f);
363 /* If a size is < 0 use the old value. */
364 int new_text_width = (new_width >= 0) ? new_width : old_text_width;
365 int new_text_height = (new_height >= 0) ? new_height : old_text_height;
366 int new_cols, new_lines;
367 bool inhibit_horizontal, inhibit_vertical;
368 Lisp_Object frame;
370 XSETFRAME (frame, f);
372 /* `make-frame' initializes Vframe_adjust_size_history to (Qt) and
373 strips its car when exiting. Just in case make sure its size never
374 exceeds 100. */
375 if (!NILP (Fconsp (Vframe_adjust_size_history))
376 && EQ (Fcar (Vframe_adjust_size_history), Qt)
377 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
378 Vframe_adjust_size_history =
379 Fcons (Qt, Fcons (list5 (make_number (0),
380 make_number (new_text_width),
381 make_number (new_text_height),
382 make_number (inhibit), parameter),
383 Fcdr (Vframe_adjust_size_history)));
385 /* The following two values are calculated from the old window body
386 sizes and any "new" settings for scroll bars, dividers, fringes and
387 margins (though the latter should have been processed already). */
388 min_windows_width
389 = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qt : Qnil, Qt);
390 min_windows_height
391 = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
393 if (inhibit >= 2 && inhibit <= 4)
394 /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay
395 within the limits and either frame_inhibit_resize tells us to do
396 so or INHIBIT equals 4. */
398 inhibit_horizontal = ((windows_width >= min_windows_width
399 && (inhibit == 4
400 || frame_inhibit_resize (f, true, parameter)))
401 ? true : false);
402 inhibit_vertical = ((windows_height >= min_windows_height
403 && (inhibit == 4
404 || frame_inhibit_resize (f, false, parameter)))
405 ? true : false);
407 else
408 /* Otherwise inhibit if INHIBIT equals 5. */
409 inhibit_horizontal = inhibit_vertical = inhibit == 5;
411 new_pixel_width = ((inhibit_horizontal && (inhibit < 5))
412 ? old_pixel_width
413 : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
414 min_windows_width
415 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
416 new_windows_width = new_pixel_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
417 new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_pixel_width);
418 new_cols = new_text_width / unit_width;
420 new_pixel_height = ((inhibit_vertical && (inhibit < 5))
421 ? old_pixel_height
422 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
423 min_windows_height
424 + FRAME_TOP_MARGIN_HEIGHT (f)
425 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
426 new_windows_height = (new_pixel_height
427 - FRAME_TOP_MARGIN_HEIGHT (f)
428 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
429 new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_pixel_height);
430 new_lines = new_text_height / unit_height;
432 #ifdef HAVE_WINDOW_SYSTEM
433 if (FRAME_WINDOW_P (f)
434 && f->can_x_set_window_size
435 && ((!inhibit_horizontal
436 && (new_pixel_width != old_pixel_width
437 || inhibit == 0 || inhibit == 2))
438 || (!inhibit_vertical
439 && (new_pixel_height != old_pixel_height
440 || inhibit == 0 || inhibit == 2))))
441 /* We are either allowed to change the frame size or the minimum
442 sizes request such a change. Do not care for fixing minimum
443 sizes here, we do that eventually when we're called from
444 change_frame_size. */
446 /* Make sure we respect fullheight and fullwidth. */
447 if (inhibit_horizontal)
448 new_text_width = old_text_width;
449 else if (inhibit_vertical)
450 new_text_height = old_text_height;
452 if (!NILP (Fconsp (Vframe_adjust_size_history))
453 && EQ (Fcar (Vframe_adjust_size_history), Qt)
454 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
455 Vframe_adjust_size_history =
456 Fcons (Qt, Fcons (list5 (make_number (1),
457 make_number (new_text_width),
458 make_number (new_text_height),
459 make_number (new_cols),
460 make_number (new_lines)),
461 Fcdr (Vframe_adjust_size_history)));
463 x_set_window_size (f, 0, new_text_width, new_text_height, 1);
464 f->resized_p = true;
466 return;
468 #endif
470 if (new_text_width == old_text_width
471 && new_text_height == old_text_height
472 && new_windows_width == old_windows_width
473 && new_windows_height == old_windows_height
474 && new_pixel_width == old_pixel_width
475 && new_pixel_height == old_pixel_height
476 && new_cols == old_cols
477 && new_lines == old_lines)
478 /* No change. Sanitize window sizes and return. */
480 sanitize_window_sizes (frame, Qt);
481 sanitize_window_sizes (frame, Qnil);
483 return;
486 block_input ();
488 #ifdef MSDOS
489 /* We only can set screen dimensions to certain values supported
490 by our video hardware. Try to find the smallest size greater
491 or equal to the requested dimensions. */
492 dos_set_window_size (&new_lines, &new_cols);
493 #endif
495 if (new_windows_width != old_windows_width)
497 resize_frame_windows (f, new_windows_width, 1, 1);
499 /* MSDOS frames cannot PRETEND, as they change frame size by
500 manipulating video hardware. */
501 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
502 FrameCols (FRAME_TTY (f)) = new_cols;
504 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
505 if (WINDOWP (f->tool_bar_window))
507 XWINDOW (f->tool_bar_window)->pixel_width = new_windows_width;
508 XWINDOW (f->tool_bar_window)->total_cols
509 = new_windows_width / unit_width;
511 #endif
514 if (new_windows_height != old_windows_height
515 /* When the top margin has changed we have to recalculate the top
516 edges of all windows. No such calculation is necessary for the
517 left edges. */
518 || WINDOW_TOP_PIXEL_EDGE (r) != FRAME_TOP_MARGIN_HEIGHT (f))
520 resize_frame_windows (f, new_windows_height, 0, 1);
522 /* MSDOS frames cannot PRETEND, as they change frame size by
523 manipulating video hardware. */
524 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
525 FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
528 /* Assign new sizes. */
529 FRAME_TEXT_WIDTH (f) = new_text_width;
530 FRAME_TEXT_HEIGHT (f) = new_text_height;
531 FRAME_PIXEL_WIDTH (f) = new_pixel_width;
532 FRAME_PIXEL_HEIGHT (f) = new_pixel_height;
533 SET_FRAME_COLS (f, new_cols);
534 SET_FRAME_LINES (f, new_lines);
536 if (!NILP (Fconsp (Vframe_adjust_size_history))
537 && EQ (Fcar (Vframe_adjust_size_history), Qt)
538 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
539 Vframe_adjust_size_history =
540 Fcons (Qt, Fcons (list5 (make_number (2),
541 make_number (new_text_width),
542 make_number (new_text_height),
543 make_number (new_cols),
544 make_number (new_lines)),
545 Fcdr (Vframe_adjust_size_history)));
548 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
549 int text_area_x, text_area_y, text_area_width, text_area_height;
551 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
552 &text_area_height);
553 if (w->cursor.x >= text_area_x + text_area_width)
554 w->cursor.hpos = w->cursor.x = 0;
555 if (w->cursor.y >= text_area_y + text_area_height)
556 w->cursor.vpos = w->cursor.y = 0;
559 /* Sanitize window sizes. */
560 sanitize_window_sizes (frame, Qt);
561 sanitize_window_sizes (frame, Qnil);
563 adjust_frame_glyphs (f);
564 calculate_costs (f);
565 SET_FRAME_GARBAGED (f);
567 /* A frame was "resized" if one of its pixelsizes changed, even if its
568 X window wasn't resized at all. */
569 f->resized_p = (new_pixel_width != old_pixel_width
570 || new_pixel_height != old_pixel_height);
572 unblock_input ();
574 run_window_configuration_change_hook (f);
577 /* Allocate basically initialized frame. */
579 static struct frame *
580 allocate_frame (void)
582 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct frame, face_cache, PVEC_FRAME);
585 struct frame *
586 make_frame (bool mini_p)
588 Lisp_Object frame;
589 register struct frame *f;
590 register struct window *rw, *mw;
591 register Lisp_Object root_window;
592 register Lisp_Object mini_window;
594 f = allocate_frame ();
595 XSETFRAME (frame, f);
597 #ifdef USE_GTK
598 /* Initialize Lisp data. Note that allocate_frame initializes all
599 Lisp data to nil, so do it only for slots which should not be nil. */
600 fset_tool_bar_position (f, Qtop);
601 #endif
603 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
604 non-Lisp data, so do it only for slots which should not be zero.
605 To avoid subtle bugs and for the sake of readability, it's better to
606 initialize enum members explicitly even if their values are zero. */
607 f->wants_modeline = true;
608 f->redisplay = true;
609 f->garbaged = true;
610 f->can_x_set_window_size = false;
611 f->can_run_window_configuration_change_hook = false;
612 f->tool_bar_redisplayed_once = false;
613 f->column_width = 1; /* !FRAME_WINDOW_P value. */
614 f->line_height = 1; /* !FRAME_WINDOW_P value. */
615 #ifdef HAVE_WINDOW_SYSTEM
616 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
617 f->horizontal_scroll_bars = false;
618 f->want_fullscreen = FULLSCREEN_NONE;
619 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
620 f->last_tool_bar_item = -1;
621 #endif
622 #endif
624 root_window = make_window ();
625 rw = XWINDOW (root_window);
626 if (mini_p)
628 mini_window = make_window ();
629 mw = XWINDOW (mini_window);
630 wset_next (rw, mini_window);
631 wset_prev (mw, root_window);
632 mw->mini = 1;
633 wset_frame (mw, frame);
634 fset_minibuffer_window (f, mini_window);
636 else
638 mini_window = Qnil;
639 wset_next (rw, Qnil);
640 fset_minibuffer_window (f, Qnil);
643 wset_frame (rw, frame);
645 /* 10 is arbitrary,
646 just so that there is "something there."
647 Correct size will be set up later with adjust_frame_size. */
649 SET_FRAME_COLS (f, 10);
650 SET_FRAME_LINES (f, 10);
651 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
652 SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
654 rw->total_cols = 10;
655 rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
656 rw->total_lines = mini_p ? 9 : 10;
657 rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
659 if (mini_p)
661 mw->top_line = rw->total_lines;
662 mw->pixel_top = rw->pixel_height;
663 mw->total_cols = rw->total_cols;
664 mw->pixel_width = rw->pixel_width;
665 mw->total_lines = 1;
666 mw->pixel_height = FRAME_LINE_HEIGHT (f);
669 /* Choose a buffer for the frame's root window. */
671 Lisp_Object buf = Fcurrent_buffer ();
673 /* If current buffer is hidden, try to find another one. */
674 if (BUFFER_HIDDEN_P (XBUFFER (buf)))
675 buf = other_buffer_safely (buf);
677 /* Use set_window_buffer, not Fset_window_buffer, and don't let
678 hooks be run by it. The reason is that the whole frame/window
679 arrangement is not yet fully initialized at this point. Windows
680 don't have the right size, glyph matrices aren't initialized
681 etc. Running Lisp functions at this point surely ends in a
682 SEGV. */
683 set_window_buffer (root_window, buf, 0, 0);
684 fset_buffer_list (f, list1 (buf));
687 if (mini_p)
689 set_window_buffer (mini_window,
690 (NILP (Vminibuffer_list)
691 ? get_minibuffer (0)
692 : Fcar (Vminibuffer_list)),
693 0, 0);
694 /* No horizontal scroll bars in minibuffers. */
695 wset_horizontal_scroll_bar (mw, Qnil);
698 fset_root_window (f, root_window);
699 fset_selected_window (f, root_window);
700 /* Make sure this window seems more recently used than
701 a newly-created, never-selected window. */
702 XWINDOW (f->selected_window)->use_time = ++window_select_count;
704 return f;
707 #ifdef HAVE_WINDOW_SYSTEM
708 /* Make a frame using a separate minibuffer window on another frame.
709 MINI_WINDOW is the minibuffer window to use. nil means use the
710 default (the global minibuffer). */
712 struct frame *
713 make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lisp_Object display)
715 register struct frame *f;
716 struct gcpro gcpro1;
718 if (!NILP (mini_window))
719 CHECK_LIVE_WINDOW (mini_window);
721 if (!NILP (mini_window)
722 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
723 error ("Frame and minibuffer must be on the same terminal");
725 /* Make a frame containing just a root window. */
726 f = make_frame (0);
728 if (NILP (mini_window))
730 /* Use default-minibuffer-frame if possible. */
731 if (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
732 || ! FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame))))
734 Lisp_Object frame_dummy;
736 XSETFRAME (frame_dummy, f);
737 GCPRO1 (frame_dummy);
738 /* If there's no minibuffer frame to use, create one. */
739 kset_default_minibuffer_frame
740 (kb, call1 (intern ("make-initial-minibuffer-frame"), display));
741 UNGCPRO;
744 mini_window
745 = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
748 fset_minibuffer_window (f, mini_window);
750 /* Make the chosen minibuffer window display the proper minibuffer,
751 unless it is already showing a minibuffer. */
752 if (NILP (Fmemq (XWINDOW (mini_window)->contents, Vminibuffer_list)))
753 /* Use set_window_buffer instead of Fset_window_buffer (see
754 discussion of bug#11984, bug#12025, bug#12026). */
755 set_window_buffer (mini_window,
756 (NILP (Vminibuffer_list)
757 ? get_minibuffer (0)
758 : Fcar (Vminibuffer_list)), 0, 0);
759 return f;
762 /* Make a frame containing only a minibuffer window. */
764 struct frame *
765 make_minibuffer_frame (void)
767 /* First make a frame containing just a root window, no minibuffer. */
769 register struct frame *f = make_frame (0);
770 register Lisp_Object mini_window;
771 register Lisp_Object frame;
773 XSETFRAME (frame, f);
775 f->auto_raise = 0;
776 f->auto_lower = 0;
777 f->no_split = 1;
778 f->wants_modeline = 0;
780 /* Now label the root window as also being the minibuffer.
781 Avoid infinite looping on the window chain by marking next pointer
782 as nil. */
784 mini_window = f->root_window;
785 fset_minibuffer_window (f, mini_window);
786 XWINDOW (mini_window)->mini = 1;
787 wset_next (XWINDOW (mini_window), Qnil);
788 wset_prev (XWINDOW (mini_window), Qnil);
789 wset_frame (XWINDOW (mini_window), frame);
791 /* Put the proper buffer in that window. */
793 /* Use set_window_buffer instead of Fset_window_buffer (see
794 discussion of bug#11984, bug#12025, bug#12026). */
795 set_window_buffer (mini_window,
796 (NILP (Vminibuffer_list)
797 ? get_minibuffer (0)
798 : Fcar (Vminibuffer_list)), 0, 0);
799 return f;
801 #endif /* HAVE_WINDOW_SYSTEM */
803 /* Construct a frame that refers to a terminal. */
805 static printmax_t tty_frame_count;
807 struct frame *
808 make_initial_frame (void)
810 struct frame *f;
811 struct terminal *terminal;
812 Lisp_Object frame;
814 eassert (initial_kboard);
816 /* The first call must initialize Vframe_list. */
817 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
818 Vframe_list = Qnil;
820 terminal = init_initial_terminal ();
822 f = make_frame (1);
823 XSETFRAME (frame, f);
825 Vframe_list = Fcons (frame, Vframe_list);
827 tty_frame_count = 1;
828 fset_name (f, build_pure_c_string ("F1"));
830 SET_FRAME_VISIBLE (f, 1);
832 f->output_method = terminal->type;
833 f->terminal = terminal;
834 f->terminal->reference_count++;
835 f->output_data.nothing = 0;
837 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
838 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
840 #ifdef HAVE_WINDOW_SYSTEM
841 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
842 f->horizontal_scroll_bars = false;
843 #endif
845 /* The default value of menu-bar-mode is t. */
846 set_menu_bar_lines (f, make_number (1), Qnil);
848 if (!noninteractive)
849 init_frame_faces (f);
851 last_nonminibuf_frame = f;
853 return f;
857 static struct frame *
858 make_terminal_frame (struct terminal *terminal)
860 register struct frame *f;
861 Lisp_Object frame;
862 char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
864 if (!terminal->name)
865 error ("Terminal is not live, can't create new frames on it");
867 f = make_frame (1);
869 XSETFRAME (frame, f);
870 Vframe_list = Fcons (frame, Vframe_list);
872 fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count));
874 SET_FRAME_VISIBLE (f, 1);
876 f->terminal = terminal;
877 f->terminal->reference_count++;
878 #ifdef MSDOS
879 f->output_data.tty->display_info = &the_only_display_info;
880 if (!inhibit_window_system
881 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
882 || XFRAME (selected_frame)->output_method == output_msdos_raw))
883 f->output_method = output_msdos_raw;
884 else
885 f->output_method = output_termcap;
886 #else /* not MSDOS */
887 f->output_method = output_termcap;
888 create_tty_output (f);
889 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
890 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
891 #endif /* not MSDOS */
893 #ifdef HAVE_WINDOW_SYSTEM
894 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
895 f->horizontal_scroll_bars = false;
896 #endif
898 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
899 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f);
900 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
901 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f);
903 /* Set the top frame to the newly created frame. */
904 if (FRAMEP (FRAME_TTY (f)->top_frame)
905 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
906 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */
908 FRAME_TTY (f)->top_frame = frame;
910 if (!noninteractive)
911 init_frame_faces (f);
913 return f;
916 /* Get a suitable value for frame parameter PARAMETER for a newly
917 created frame, based on (1) the user-supplied frame parameter
918 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
920 static Lisp_Object
921 get_future_frame_param (Lisp_Object parameter,
922 Lisp_Object supplied_parms,
923 char *current_value)
925 Lisp_Object result;
927 result = Fassq (parameter, supplied_parms);
928 if (NILP (result))
929 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
930 if (NILP (result) && current_value != NULL)
931 result = build_string (current_value);
932 if (!NILP (result) && !STRINGP (result))
933 result = XCDR (result);
934 if (NILP (result) || !STRINGP (result))
935 result = Qnil;
937 return result;
940 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
941 1, 1, 0,
942 doc: /* Create an additional terminal frame, possibly on another terminal.
943 This function takes one argument, an alist specifying frame parameters.
945 You can create multiple frames on a single text terminal, but only one
946 of them (the selected terminal frame) is actually displayed.
948 In practice, generally you don't need to specify any parameters,
949 except when you want to create a new frame on another terminal.
950 In that case, the `tty' parameter specifies the device file to open,
951 and the `tty-type' parameter specifies the terminal type. Example:
953 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
955 Note that changing the size of one terminal frame automatically
956 affects all frames on the same terminal device. */)
957 (Lisp_Object parms)
959 struct frame *f;
960 struct terminal *t = NULL;
961 Lisp_Object frame, tem;
962 struct frame *sf = SELECTED_FRAME ();
964 #ifdef MSDOS
965 if (sf->output_method != output_msdos_raw
966 && sf->output_method != output_termcap)
967 emacs_abort ();
968 #else /* not MSDOS */
970 #ifdef WINDOWSNT /* This should work now! */
971 if (sf->output_method != output_termcap)
972 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
973 #endif
974 #endif /* not MSDOS */
977 Lisp_Object terminal;
979 terminal = Fassq (Qterminal, parms);
980 if (CONSP (terminal))
982 terminal = XCDR (terminal);
983 t = decode_live_terminal (terminal);
985 #ifdef MSDOS
986 if (t && t != the_only_display_info.terminal)
987 /* msdos.c assumes a single tty_display_info object. */
988 error ("Multiple terminals are not supported on this platform");
989 if (!t)
990 t = the_only_display_info.terminal;
991 #endif
994 if (!t)
996 char *name = 0, *type = 0;
997 Lisp_Object tty, tty_type;
998 USE_SAFE_ALLOCA;
1000 tty = get_future_frame_param
1001 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
1002 ? FRAME_TTY (XFRAME (selected_frame))->name
1003 : NULL));
1004 if (!NILP (tty))
1005 SAFE_ALLOCA_STRING (name, tty);
1007 tty_type = get_future_frame_param
1008 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
1009 ? FRAME_TTY (XFRAME (selected_frame))->type
1010 : NULL));
1011 if (!NILP (tty_type))
1012 SAFE_ALLOCA_STRING (type, tty_type);
1014 t = init_tty (name, type, 0); /* Errors are not fatal. */
1015 SAFE_FREE ();
1018 f = make_terminal_frame (t);
1021 int width, height;
1022 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1023 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0, Qnil);
1026 adjust_frame_glyphs (f);
1027 calculate_costs (f);
1028 XSETFRAME (frame, f);
1030 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
1031 store_in_alist (&parms, Qtty,
1032 (t->display_info.tty->name
1033 ? build_string (t->display_info.tty->name)
1034 : Qnil));
1035 Fmodify_frame_parameters (frame, parms);
1037 /* Make the frame face alist be frame-specific, so that each
1038 frame could change its face definitions independently. */
1039 fset_face_alist (f, Fcopy_alist (sf->face_alist));
1040 /* Simple Fcopy_alist isn't enough, because we need the contents of
1041 the vectors which are the CDRs of associations in face_alist to
1042 be copied as well. */
1043 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
1044 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
1045 return frame;
1049 /* Perform the switch to frame FRAME.
1051 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
1052 FRAME1 as frame.
1054 If TRACK is non-zero and the frame that currently has the focus
1055 redirects its focus to the selected frame, redirect that focused
1056 frame's focus to FRAME instead.
1058 FOR_DELETION non-zero means that the selected frame is being
1059 deleted, which includes the possibility that the frame's terminal
1060 is dead.
1062 The value of NORECORD is passed as argument to Fselect_window. */
1064 Lisp_Object
1065 do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
1067 struct frame *sf = SELECTED_FRAME ();
1069 /* If FRAME is a switch-frame event, extract the frame we should
1070 switch to. */
1071 if (CONSP (frame)
1072 && EQ (XCAR (frame), Qswitch_frame)
1073 && CONSP (XCDR (frame)))
1074 frame = XCAR (XCDR (frame));
1076 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
1077 a switch-frame event to arrive after a frame is no longer live,
1078 especially when deleting the initial frame during startup. */
1079 CHECK_FRAME (frame);
1080 if (! FRAME_LIVE_P (XFRAME (frame)))
1081 return Qnil;
1083 if (sf == XFRAME (frame))
1084 return frame;
1086 /* If a frame's focus has been redirected toward the currently
1087 selected frame, we should change the redirection to point to the
1088 newly selected frame. This means that if the focus is redirected
1089 from a minibufferless frame to a surrogate minibuffer frame, we
1090 can use `other-window' to switch between all the frames using
1091 that minibuffer frame, and the focus redirection will follow us
1092 around. */
1093 #if 0
1094 /* This is too greedy; it causes inappropriate focus redirection
1095 that's hard to get rid of. */
1096 if (track)
1098 Lisp_Object tail;
1100 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1102 Lisp_Object focus;
1104 if (!FRAMEP (XCAR (tail)))
1105 emacs_abort ();
1107 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
1109 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
1110 Fredirect_frame_focus (XCAR (tail), frame);
1113 #else /* ! 0 */
1114 /* Instead, apply it only to the frame we're pointing to. */
1115 #ifdef HAVE_WINDOW_SYSTEM
1116 if (track && FRAME_WINDOW_P (XFRAME (frame)))
1118 Lisp_Object focus, xfocus;
1120 xfocus = x_get_focus_frame (XFRAME (frame));
1121 if (FRAMEP (xfocus))
1123 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
1124 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
1125 Fredirect_frame_focus (xfocus, frame);
1128 #endif /* HAVE_X_WINDOWS */
1129 #endif /* ! 0 */
1131 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
1132 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
1134 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
1136 struct frame *f = XFRAME (frame);
1137 struct tty_display_info *tty = FRAME_TTY (f);
1138 Lisp_Object top_frame = tty->top_frame;
1140 /* Don't mark the frame garbaged and/or obscured if we are
1141 switching to the frame that is already the top frame of that
1142 TTY. */
1143 if (!EQ (frame, top_frame))
1145 if (FRAMEP (top_frame))
1146 /* Mark previously displayed frame as now obscured. */
1147 SET_FRAME_VISIBLE (XFRAME (top_frame), 2);
1148 SET_FRAME_VISIBLE (f, 1);
1149 /* If the new TTY frame changed dimensions, we need to
1150 resync term.c's idea of the frame size with the new
1151 frame's data. */
1152 if (FRAME_COLS (f) != FrameCols (tty))
1153 FrameCols (tty) = FRAME_COLS (f);
1154 if (FRAME_TOTAL_LINES (f) != FrameRows (tty))
1155 FrameRows (tty) = FRAME_TOTAL_LINES (f);
1157 tty->top_frame = frame;
1160 selected_frame = frame;
1161 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
1162 last_nonminibuf_frame = XFRAME (selected_frame);
1164 Fselect_window (XFRAME (frame)->selected_window, norecord);
1166 /* We want to make sure that the next event generates a frame-switch
1167 event to the appropriate frame. This seems kludgy to me, but
1168 before you take it out, make sure that evaluating something like
1169 (select-window (frame-root-window (new-frame))) doesn't end up
1170 with your typing being interpreted in the new frame instead of
1171 the one you're actually typing in. */
1172 internal_last_event_frame = Qnil;
1174 return frame;
1177 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
1178 doc: /* Select FRAME.
1179 Subsequent editing commands apply to its selected window.
1180 Optional argument NORECORD means to neither change the order of
1181 recently selected windows nor the buffer list.
1183 The selection of FRAME lasts until the next time the user does
1184 something to select a different frame, or until the next time
1185 this function is called. If you are using a window system, the
1186 previously selected frame may be restored as the selected frame
1187 when returning to the command loop, because it still may have
1188 the window system's input focus. On a text terminal, the next
1189 redisplay will display FRAME.
1191 This function returns FRAME, or nil if FRAME has been deleted. */)
1192 (Lisp_Object frame, Lisp_Object norecord)
1194 return do_switch_frame (frame, 1, 0, norecord);
1197 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "^e",
1198 doc: /* Handle a switch-frame event EVENT.
1199 Switch-frame events are usually bound to this function.
1200 A switch-frame event tells Emacs that the window manager has requested
1201 that the user's events be directed to the frame mentioned in the event.
1202 This function selects the selected window of the frame of EVENT.
1204 If EVENT is frame object, handle it as if it were a switch-frame event
1205 to that frame. */)
1206 (Lisp_Object event)
1208 /* Preserve prefix arg that the command loop just cleared. */
1209 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
1210 run_hook (Qmouse_leave_buffer_hook);
1211 /* `switch-frame' implies a focus in. */
1212 call1 (intern ("handle-focus-in"), event);
1213 return do_switch_frame (event, 0, 0, Qnil);
1216 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1217 doc: /* Return the frame that is now selected. */)
1218 (void)
1220 return selected_frame;
1223 DEFUN ("frame-list", Fframe_list, Sframe_list,
1224 0, 0, 0,
1225 doc: /* Return a list of all live frames. */)
1226 (void)
1228 Lisp_Object frames;
1229 frames = Fcopy_sequence (Vframe_list);
1230 #ifdef HAVE_WINDOW_SYSTEM
1231 if (FRAMEP (tip_frame))
1232 frames = Fdelq (tip_frame, frames);
1233 #endif
1234 return frames;
1237 /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1238 same tty (for tty frames) or among frames which uses FRAME's keyboard.
1239 If MINIBUF is nil, do not consider minibuffer-only candidate.
1240 If MINIBUF is `visible', do not consider an invisible candidate.
1241 If MINIBUF is a window, consider only its own frame and candidate now
1242 using that window as the minibuffer.
1243 If MINIBUF is 0, consider candidate if it is visible or iconified.
1244 Otherwise consider any candidate and return nil if CANDIDATE is not
1245 acceptable. */
1247 static Lisp_Object
1248 candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf)
1250 struct frame *c = XFRAME (candidate), *f = XFRAME (frame);
1252 if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f)
1253 && FRAME_KBOARD (c) == FRAME_KBOARD (f))
1254 || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f)
1255 && FRAME_TTY (c) == FRAME_TTY (f)))
1257 if (NILP (minibuf))
1259 if (!FRAME_MINIBUF_ONLY_P (c))
1260 return candidate;
1262 else if (EQ (minibuf, Qvisible))
1264 if (FRAME_VISIBLE_P (c))
1265 return candidate;
1267 else if (WINDOWP (minibuf))
1269 if (EQ (FRAME_MINIBUF_WINDOW (c), minibuf)
1270 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), candidate)
1271 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1272 FRAME_FOCUS_FRAME (c)))
1273 return candidate;
1275 else if (XFASTINT (minibuf) == 0)
1277 if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c))
1278 return candidate;
1280 else
1281 return candidate;
1283 return Qnil;
1286 /* Return the next frame in the frame list after FRAME. */
1288 static Lisp_Object
1289 next_frame (Lisp_Object frame, Lisp_Object minibuf)
1291 Lisp_Object f, tail;
1292 int passed = 0;
1294 /* There must always be at least one frame in Vframe_list. */
1295 eassert (CONSP (Vframe_list));
1297 while (passed < 2)
1298 FOR_EACH_FRAME (tail, f)
1300 if (passed)
1302 f = candidate_frame (f, frame, minibuf);
1303 if (!NILP (f))
1304 return f;
1306 if (EQ (frame, f))
1307 passed++;
1309 return frame;
1312 /* Return the previous frame in the frame list before FRAME. */
1314 static Lisp_Object
1315 prev_frame (Lisp_Object frame, Lisp_Object minibuf)
1317 Lisp_Object f, tail, prev = Qnil;
1319 /* There must always be at least one frame in Vframe_list. */
1320 eassert (CONSP (Vframe_list));
1322 FOR_EACH_FRAME (tail, f)
1324 if (EQ (frame, f) && !NILP (prev))
1325 return prev;
1326 f = candidate_frame (f, frame, minibuf);
1327 if (!NILP (f))
1328 prev = f;
1331 /* We've scanned the entire list. */
1332 if (NILP (prev))
1333 /* We went through the whole frame list without finding a single
1334 acceptable frame. Return the original frame. */
1335 return frame;
1336 else
1337 /* There were no acceptable frames in the list before FRAME; otherwise,
1338 we would have returned directly from the loop. Since PREV is the last
1339 acceptable frame in the list, return it. */
1340 return prev;
1344 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1345 doc: /* Return the next frame in the frame list after FRAME.
1346 It considers only frames on the same terminal as FRAME.
1347 By default, skip minibuffer-only frames.
1348 If omitted, FRAME defaults to the selected frame.
1349 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1350 If MINIFRAME is a window, include only its own frame
1351 and any frame now using that window as the minibuffer.
1352 If MINIFRAME is `visible', include all visible frames.
1353 If MINIFRAME is 0, include all visible and iconified frames.
1354 Otherwise, include all frames. */)
1355 (Lisp_Object frame, Lisp_Object miniframe)
1357 if (NILP (frame))
1358 frame = selected_frame;
1359 CHECK_LIVE_FRAME (frame);
1360 return next_frame (frame, miniframe);
1363 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1364 doc: /* Return the previous frame in the frame list before FRAME.
1365 It considers only frames on the same terminal as FRAME.
1366 By default, skip minibuffer-only frames.
1367 If omitted, FRAME defaults to the selected frame.
1368 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1369 If MINIFRAME is a window, include only its own frame
1370 and any frame now using that window as the minibuffer.
1371 If MINIFRAME is `visible', include all visible frames.
1372 If MINIFRAME is 0, include all visible and iconified frames.
1373 Otherwise, include all frames. */)
1374 (Lisp_Object frame, Lisp_Object miniframe)
1376 if (NILP (frame))
1377 frame = selected_frame;
1378 CHECK_LIVE_FRAME (frame);
1379 return prev_frame (frame, miniframe);
1382 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
1383 Slast_nonminibuf_frame, 0, 0, 0,
1384 doc: /* Return last non-minibuffer frame selected. */)
1385 (void)
1387 Lisp_Object frame = Qnil;
1389 if (last_nonminibuf_frame)
1390 XSETFRAME (frame, last_nonminibuf_frame);
1392 return frame;
1395 /* Return 1 if it is ok to delete frame F;
1396 0 if all frames aside from F are invisible.
1397 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1399 static int
1400 other_visible_frames (struct frame *f)
1402 Lisp_Object frames, this;
1404 FOR_EACH_FRAME (frames, this)
1406 if (f == XFRAME (this))
1407 continue;
1409 /* Verify that we can still talk to the frame's X window,
1410 and note any recent change in visibility. */
1411 #ifdef HAVE_X_WINDOWS
1412 if (FRAME_WINDOW_P (XFRAME (this)))
1413 x_sync (XFRAME (this));
1414 #endif
1416 if (FRAME_VISIBLE_P (XFRAME (this))
1417 || FRAME_ICONIFIED_P (XFRAME (this))
1418 /* Allow deleting the terminal frame when at least one X
1419 frame exists. */
1420 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1421 return 1;
1423 return 0;
1426 /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1427 window. Preferably use the selected frame's minibuffer window
1428 instead. If the selected frame doesn't have one, get some other
1429 frame's minibuffer window. SELECT non-zero means select the new
1430 minibuffer window. */
1431 static void
1432 check_minibuf_window (Lisp_Object frame, int select)
1434 struct frame *f = decode_live_frame (frame);
1436 XSETFRAME (frame, f);
1438 if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
1440 Lisp_Object frames, this, window = make_number (0);
1442 if (!EQ (frame, selected_frame)
1443 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
1444 window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
1445 else
1446 FOR_EACH_FRAME (frames, this)
1448 if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1450 window = FRAME_MINIBUF_WINDOW (XFRAME (this));
1451 break;
1455 /* Don't abort if no window was found (Bug#15247). */
1456 if (WINDOWP (window))
1458 /* Use set_window_buffer instead of Fset_window_buffer (see
1459 discussion of bug#11984, bug#12025, bug#12026). */
1460 set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
1461 minibuf_window = window;
1463 /* SELECT non-zero usually means that FRAME's minibuffer
1464 window was selected; select the new one. */
1465 if (select)
1466 Fselect_window (minibuf_window, Qnil);
1472 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1473 unconditionally. x_connection_closed and delete_terminal use
1474 this. Any other value of FORCE implements the semantics
1475 described for Fdelete_frame. */
1476 Lisp_Object
1477 delete_frame (Lisp_Object frame, Lisp_Object force)
1479 struct frame *f = decode_any_frame (frame);
1480 struct frame *sf;
1481 struct kboard *kb;
1483 int minibuffer_selected, is_tooltip_frame;
1485 if (! FRAME_LIVE_P (f))
1486 return Qnil;
1488 if (NILP (force) && !other_visible_frames (f))
1489 error ("Attempt to delete the sole visible or iconified frame");
1491 /* x_connection_closed must have set FORCE to `noelisp' in order
1492 to delete the last frame, if it is gone. */
1493 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1494 error ("Attempt to delete the only frame");
1496 XSETFRAME (frame, f);
1498 /* Does this frame have a minibuffer, and is it the surrogate
1499 minibuffer for any other frame? */
1500 if (FRAME_HAS_MINIBUF_P (f))
1502 Lisp_Object frames, this;
1504 FOR_EACH_FRAME (frames, this)
1506 Lisp_Object fminiw;
1508 if (EQ (this, frame))
1509 continue;
1511 fminiw = FRAME_MINIBUF_WINDOW (XFRAME (this));
1513 if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw))))
1515 /* If we MUST delete this frame, delete the other first.
1516 But do this only if FORCE equals `noelisp'. */
1517 if (EQ (force, Qnoelisp))
1518 delete_frame (this, Qnoelisp);
1519 else
1520 error ("Attempt to delete a surrogate minibuffer frame");
1525 is_tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
1527 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1528 frame is a tooltip. FORCE is set to `noelisp' when handling
1529 a disconnect from the terminal, so we don't dare call Lisp
1530 code. */
1531 if (NILP (Vrun_hooks) || is_tooltip_frame)
1533 else if (EQ (force, Qnoelisp))
1534 pending_funcalls
1535 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1536 pending_funcalls);
1537 else
1539 #ifdef HAVE_X_WINDOWS
1540 /* Also, save clipboard to the clipboard manager. */
1541 x_clipboard_manager_save_frame (frame);
1542 #endif
1544 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1547 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1548 if (! FRAME_LIVE_P (f))
1549 return Qnil;
1551 /* At this point, we are committed to deleting the frame.
1552 There is no more chance for errors to prevent it. */
1554 minibuffer_selected = EQ (minibuf_window, selected_window);
1555 sf = SELECTED_FRAME ();
1556 /* Don't let the frame remain selected. */
1557 if (f == sf)
1559 Lisp_Object tail;
1560 Lisp_Object frame1 = Qnil;
1562 /* Look for another visible frame on the same terminal.
1563 Do not call next_frame here because it may loop forever.
1564 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1565 FOR_EACH_FRAME (tail, frame1)
1566 if (!EQ (frame, frame1)
1567 && (FRAME_TERMINAL (XFRAME (frame))
1568 == FRAME_TERMINAL (XFRAME (frame1)))
1569 && FRAME_VISIBLE_P (XFRAME (frame1)))
1570 break;
1572 /* If there is none, find *some* other frame. */
1573 if (NILP (frame1) || EQ (frame1, frame))
1575 FOR_EACH_FRAME (tail, frame1)
1577 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1579 /* Do not change a text terminal's top-frame. */
1580 struct frame *f1 = XFRAME (frame1);
1581 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
1583 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
1584 if (!EQ (top_frame, frame))
1585 frame1 = top_frame;
1587 break;
1591 #ifdef NS_IMPL_COCOA
1592 else
1593 /* Under NS, there is no system mechanism for choosing a new
1594 window to get focus -- it is left to application code.
1595 So the portion of THIS application interfacing with NS
1596 needs to know about it. We call Fraise_frame, but the
1597 purpose is really to transfer focus. */
1598 Fraise_frame (frame1);
1599 #endif
1601 do_switch_frame (frame1, 0, 1, Qnil);
1602 sf = SELECTED_FRAME ();
1605 /* Don't allow minibuf_window to remain on a deleted frame. */
1606 check_minibuf_window (frame, minibuffer_selected);
1608 /* Don't let echo_area_window to remain on a deleted frame. */
1609 if (EQ (f->minibuffer_window, echo_area_window))
1610 echo_area_window = sf->minibuffer_window;
1612 /* Clear any X selections for this frame. */
1613 #ifdef HAVE_X_WINDOWS
1614 if (FRAME_X_P (f))
1615 x_clear_frame_selections (f);
1616 #endif
1618 /* Free glyphs.
1619 This function must be called before the window tree of the
1620 frame is deleted because windows contain dynamically allocated
1621 memory. */
1622 free_glyphs (f);
1624 #ifdef HAVE_WINDOW_SYSTEM
1625 /* Give chance to each font driver to free a frame specific data. */
1626 font_update_drivers (f, Qnil);
1627 #endif
1629 /* Mark all the windows that used to be on FRAME as deleted, and then
1630 remove the reference to them. */
1631 delete_all_child_windows (f->root_window);
1632 fset_root_window (f, Qnil);
1634 Vframe_list = Fdelq (frame, Vframe_list);
1635 SET_FRAME_VISIBLE (f, 0);
1637 /* Allow the vector of menu bar contents to be freed in the next
1638 garbage collection. The frame object itself may not be garbage
1639 collected until much later, because recent_keys and other data
1640 structures can still refer to it. */
1641 fset_menu_bar_vector (f, Qnil);
1643 /* If FRAME's buffer lists contains killed
1644 buffers, this helps GC to reclaim them. */
1645 fset_buffer_list (f, Qnil);
1646 fset_buried_buffer_list (f, Qnil);
1648 free_font_driver_list (f);
1649 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1650 xfree (f->namebuf);
1651 #endif
1652 xfree (f->decode_mode_spec_buffer);
1653 xfree (FRAME_INSERT_COST (f));
1654 xfree (FRAME_DELETEN_COST (f));
1655 xfree (FRAME_INSERTN_COST (f));
1656 xfree (FRAME_DELETE_COST (f));
1658 /* Since some events are handled at the interrupt level, we may get
1659 an event for f at any time; if we zero out the frame's terminal
1660 now, then we may trip up the event-handling code. Instead, we'll
1661 promise that the terminal of the frame must be valid until we
1662 have called the window-system-dependent frame destruction
1663 routine. */
1667 struct terminal *terminal;
1668 block_input ();
1669 if (FRAME_TERMINAL (f)->delete_frame_hook)
1670 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
1671 terminal = FRAME_TERMINAL (f);
1672 f->output_data.nothing = 0;
1673 f->terminal = 0; /* Now the frame is dead. */
1674 unblock_input ();
1676 /* If needed, delete the terminal that this frame was on.
1677 (This must be done after the frame is killed.) */
1678 terminal->reference_count--;
1679 #ifdef USE_GTK
1680 /* FIXME: Deleting the terminal crashes emacs because of a GTK
1681 bug.
1682 http://lists.gnu.org/archive/html/emacs-devel/2011-10/msg00363.html */
1683 if (terminal->reference_count == 0 && terminal->type == output_x_window)
1684 terminal->reference_count = 1;
1685 #endif /* USE_GTK */
1686 if (terminal->reference_count == 0)
1688 Lisp_Object tmp;
1689 XSETTERMINAL (tmp, terminal);
1691 kb = NULL;
1692 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
1694 else
1695 kb = terminal->kboard;
1698 /* If we've deleted the last_nonminibuf_frame, then try to find
1699 another one. */
1700 if (f == last_nonminibuf_frame)
1702 Lisp_Object frames, this;
1704 last_nonminibuf_frame = 0;
1706 FOR_EACH_FRAME (frames, this)
1708 f = XFRAME (this);
1709 if (!FRAME_MINIBUF_ONLY_P (f))
1711 last_nonminibuf_frame = f;
1712 break;
1717 /* If there's no other frame on the same kboard, get out of
1718 single-kboard state if we're in it for this kboard. */
1719 if (kb != NULL)
1721 Lisp_Object frames, this;
1722 /* Some frame we found on the same kboard, or nil if there are none. */
1723 Lisp_Object frame_on_same_kboard = Qnil;
1725 FOR_EACH_FRAME (frames, this)
1726 if (kb == FRAME_KBOARD (XFRAME (this)))
1727 frame_on_same_kboard = this;
1729 if (NILP (frame_on_same_kboard))
1730 not_single_kboard_state (kb);
1734 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1735 find another one. Prefer minibuffer-only frames, but also notice
1736 frames with other windows. */
1737 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1739 Lisp_Object frames, this;
1741 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1742 Lisp_Object frame_with_minibuf = Qnil;
1743 /* Some frame we found on the same kboard, or nil if there are none. */
1744 Lisp_Object frame_on_same_kboard = Qnil;
1746 FOR_EACH_FRAME (frames, this)
1748 struct frame *f1 = XFRAME (this);
1750 /* Consider only frames on the same kboard
1751 and only those with minibuffers. */
1752 if (kb == FRAME_KBOARD (f1)
1753 && FRAME_HAS_MINIBUF_P (f1))
1755 frame_with_minibuf = this;
1756 if (FRAME_MINIBUF_ONLY_P (f1))
1757 break;
1760 if (kb == FRAME_KBOARD (f1))
1761 frame_on_same_kboard = this;
1764 if (!NILP (frame_on_same_kboard))
1766 /* We know that there must be some frame with a minibuffer out
1767 there. If this were not true, all of the frames present
1768 would have to be minibufferless, which implies that at some
1769 point their minibuffer frames must have been deleted, but
1770 that is prohibited at the top; you can't delete surrogate
1771 minibuffer frames. */
1772 if (NILP (frame_with_minibuf))
1773 emacs_abort ();
1775 kset_default_minibuffer_frame (kb, frame_with_minibuf);
1777 else
1778 /* No frames left on this kboard--say no minibuffer either. */
1779 kset_default_minibuffer_frame (kb, Qnil);
1782 /* Cause frame titles to update--necessary if we now have just one frame. */
1783 if (!is_tooltip_frame)
1784 update_mode_lines = 15;
1786 return Qnil;
1789 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1790 doc: /* Delete FRAME, permanently eliminating it from use.
1791 FRAME defaults to the selected frame.
1793 A frame may not be deleted if its minibuffer is used by other frames.
1794 Normally, you may not delete a frame if all other frames are invisible,
1795 but if the second optional argument FORCE is non-nil, you may do so.
1797 This function runs `delete-frame-functions' before actually
1798 deleting the frame, unless the frame is a tooltip.
1799 The functions are run with one argument, the frame to be deleted. */)
1800 (Lisp_Object frame, Lisp_Object force)
1802 return delete_frame (frame, !NILP (force) ? Qt : Qnil);
1806 /* Return mouse position in character cell units. */
1808 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1809 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1810 The position is given in canonical character cells, where (0, 0) is the
1811 upper-left corner of the frame, X is the horizontal offset, and Y is the
1812 vertical offset, measured in units of the frame's default character size.
1813 If Emacs is running on a mouseless terminal or hasn't been programmed
1814 to read the mouse position, it returns the selected frame for FRAME
1815 and nil for X and Y.
1816 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1817 passing the normal return value to that function as an argument,
1818 and returns whatever that function returns. */)
1819 (void)
1821 struct frame *f;
1822 Lisp_Object lispy_dummy;
1823 Lisp_Object x, y, retval;
1824 struct gcpro gcpro1;
1826 f = SELECTED_FRAME ();
1827 x = y = Qnil;
1829 /* It's okay for the hook to refrain from storing anything. */
1830 if (FRAME_TERMINAL (f)->mouse_position_hook)
1832 enum scroll_bar_part party_dummy;
1833 Time time_dummy;
1834 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1835 &lispy_dummy, &party_dummy,
1836 &x, &y,
1837 &time_dummy);
1840 if (! NILP (x))
1842 int col = XINT (x);
1843 int row = XINT (y);
1844 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1845 XSETINT (x, col);
1846 XSETINT (y, row);
1848 XSETFRAME (lispy_dummy, f);
1849 retval = Fcons (lispy_dummy, Fcons (x, y));
1850 GCPRO1 (retval);
1851 if (!NILP (Vmouse_position_function))
1852 retval = call1 (Vmouse_position_function, retval);
1853 RETURN_UNGCPRO (retval);
1856 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1857 Smouse_pixel_position, 0, 0, 0,
1858 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1859 The position is given in pixel units, where (0, 0) is the
1860 upper-left corner of the frame, X is the horizontal offset, and Y is
1861 the vertical offset.
1862 If Emacs is running on a mouseless terminal or hasn't been programmed
1863 to read the mouse position, it returns the selected frame for FRAME
1864 and nil for X and Y. */)
1865 (void)
1867 struct frame *f;
1868 Lisp_Object lispy_dummy;
1869 Lisp_Object x, y, retval;
1870 struct gcpro gcpro1;
1872 f = SELECTED_FRAME ();
1873 x = y = Qnil;
1875 /* It's okay for the hook to refrain from storing anything. */
1876 if (FRAME_TERMINAL (f)->mouse_position_hook)
1878 enum scroll_bar_part party_dummy;
1879 Time time_dummy;
1880 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1881 &lispy_dummy, &party_dummy,
1882 &x, &y,
1883 &time_dummy);
1886 XSETFRAME (lispy_dummy, f);
1887 retval = Fcons (lispy_dummy, Fcons (x, y));
1888 GCPRO1 (retval);
1889 if (!NILP (Vmouse_position_function))
1890 retval = call1 (Vmouse_position_function, retval);
1891 RETURN_UNGCPRO (retval);
1894 #ifdef HAVE_WINDOW_SYSTEM
1896 /* On frame F, convert character coordinates X and Y to pixel
1897 coordinates *PIX_X and *PIX_Y. */
1899 static void
1900 frame_char_to_pixel_position (struct frame *f, int x, int y,
1901 int *pix_x, int *pix_y)
1903 *pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2;
1904 *pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2;
1906 if (*pix_x < 0)
1907 *pix_x = 0;
1908 if (*pix_x > FRAME_PIXEL_WIDTH (f))
1909 *pix_x = FRAME_PIXEL_WIDTH (f);
1911 if (*pix_y < 0)
1912 *pix_y = 0;
1913 if (*pix_y > FRAME_PIXEL_HEIGHT (f))
1914 *pix_y = FRAME_PIXEL_HEIGHT (f);
1917 /* On frame F, reposition mouse pointer to character coordinates X and Y. */
1919 static void
1920 frame_set_mouse_position (struct frame *f, int x, int y)
1922 int pix_x, pix_y;
1924 frame_char_to_pixel_position (f, x, y, &pix_x, &pix_y);
1925 frame_set_mouse_pixel_position (f, pix_x, pix_y);
1928 #endif /* HAVE_WINDOW_SYSTEM */
1930 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1931 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1932 Coordinates are relative to the frame, not a window,
1933 so the coordinates of the top left character in the frame
1934 may be nonzero due to left-hand scroll bars or the menu bar.
1936 The position is given in canonical character cells, where (0, 0) is
1937 the upper-left corner of the frame, X is the horizontal offset, and
1938 Y is the vertical offset, measured in units of the frame's default
1939 character size.
1941 This function is a no-op for an X frame that is not visible.
1942 If you have just created a frame, you must wait for it to become visible
1943 before calling this function on it, like this.
1944 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1945 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1947 CHECK_LIVE_FRAME (frame);
1948 CHECK_TYPE_RANGED_INTEGER (int, x);
1949 CHECK_TYPE_RANGED_INTEGER (int, y);
1951 /* I think this should be done with a hook. */
1952 #ifdef HAVE_WINDOW_SYSTEM
1953 if (FRAME_WINDOW_P (XFRAME (frame)))
1954 /* Warping the mouse will cause enternotify and focus events. */
1955 frame_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1956 #else
1957 #if defined (MSDOS)
1958 if (FRAME_MSDOS_P (XFRAME (frame)))
1960 Fselect_frame (frame, Qnil);
1961 mouse_moveto (XINT (x), XINT (y));
1963 #else
1964 #ifdef HAVE_GPM
1966 Fselect_frame (frame, Qnil);
1967 term_mouse_moveto (XINT (x), XINT (y));
1969 #endif
1970 #endif
1971 #endif
1973 return Qnil;
1976 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1977 Sset_mouse_pixel_position, 3, 3, 0,
1978 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1979 The position is given in pixels, where (0, 0) is the upper-left corner
1980 of the frame, X is the horizontal offset, and Y is the vertical offset.
1982 Note, this is a no-op for an X frame that is not visible.
1983 If you have just created a frame, you must wait for it to become visible
1984 before calling this function on it, like this.
1985 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1986 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1988 CHECK_LIVE_FRAME (frame);
1989 CHECK_TYPE_RANGED_INTEGER (int, x);
1990 CHECK_TYPE_RANGED_INTEGER (int, y);
1992 /* I think this should be done with a hook. */
1993 #ifdef HAVE_WINDOW_SYSTEM
1994 if (FRAME_WINDOW_P (XFRAME (frame)))
1995 /* Warping the mouse will cause enternotify and focus events. */
1996 frame_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1997 #else
1998 #if defined (MSDOS)
1999 if (FRAME_MSDOS_P (XFRAME (frame)))
2001 Fselect_frame (frame, Qnil);
2002 mouse_moveto (XINT (x), XINT (y));
2004 #else
2005 #ifdef HAVE_GPM
2007 Fselect_frame (frame, Qnil);
2008 term_mouse_moveto (XINT (x), XINT (y));
2010 #endif
2011 #endif
2012 #endif
2014 return Qnil;
2017 static void make_frame_visible_1 (Lisp_Object);
2019 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
2020 0, 1, "",
2021 doc: /* Make the frame FRAME visible (assuming it is an X window).
2022 If omitted, FRAME defaults to the currently selected frame. */)
2023 (Lisp_Object frame)
2025 struct frame *f = decode_live_frame (frame);
2027 /* I think this should be done with a hook. */
2028 #ifdef HAVE_WINDOW_SYSTEM
2029 if (FRAME_WINDOW_P (f))
2030 x_make_frame_visible (f);
2031 #endif
2033 make_frame_visible_1 (f->root_window);
2035 /* Make menu bar update for the Buffers and Frames menus. */
2036 /* windows_or_buffers_changed = 15; FIXME: Why? */
2038 XSETFRAME (frame, f);
2039 return frame;
2042 /* Update the display_time slot of the buffers shown in WINDOW
2043 and all its descendants. */
2045 static void
2046 make_frame_visible_1 (Lisp_Object window)
2048 struct window *w;
2050 for (; !NILP (window); window = w->next)
2052 w = XWINDOW (window);
2053 if (WINDOWP (w->contents))
2054 make_frame_visible_1 (w->contents);
2055 else
2056 bset_display_time (XBUFFER (w->contents), Fcurrent_time ());
2060 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
2061 0, 2, "",
2062 doc: /* Make the frame FRAME invisible.
2063 If omitted, FRAME defaults to the currently selected frame.
2064 On graphical displays, invisible frames are not updated and are
2065 usually not displayed at all, even in a window system's \"taskbar\".
2067 Normally you may not make FRAME invisible if all other frames are invisible,
2068 but if the second optional argument FORCE is non-nil, you may do so.
2070 This function has no effect on text terminal frames. Such frames are
2071 always considered visible, whether or not they are currently being
2072 displayed in the terminal. */)
2073 (Lisp_Object frame, Lisp_Object force)
2075 struct frame *f = decode_live_frame (frame);
2077 if (NILP (force) && !other_visible_frames (f))
2078 error ("Attempt to make invisible the sole visible or iconified frame");
2080 /* Don't allow minibuf_window to remain on an invisible frame. */
2081 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
2083 /* I think this should be done with a hook. */
2084 #ifdef HAVE_WINDOW_SYSTEM
2085 if (FRAME_WINDOW_P (f))
2086 x_make_frame_invisible (f);
2087 #endif
2089 /* Make menu bar update for the Buffers and Frames menus. */
2090 windows_or_buffers_changed = 16;
2092 return Qnil;
2095 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
2096 0, 1, "",
2097 doc: /* Make the frame FRAME into an icon.
2098 If omitted, FRAME defaults to the currently selected frame. */)
2099 (Lisp_Object frame)
2101 struct frame *f = decode_live_frame (frame);
2103 /* Don't allow minibuf_window to remain on an iconified frame. */
2104 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
2106 /* I think this should be done with a hook. */
2107 #ifdef HAVE_WINDOW_SYSTEM
2108 if (FRAME_WINDOW_P (f))
2109 x_iconify_frame (f);
2110 #endif
2112 /* Make menu bar update for the Buffers and Frames menus. */
2113 windows_or_buffers_changed = 17;
2115 return Qnil;
2118 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
2119 1, 1, 0,
2120 doc: /* Return t if FRAME is \"visible\" (actually in use for display).
2121 Return the symbol `icon' if FRAME is iconified or \"minimized\".
2122 Return nil if FRAME was made invisible, via `make-frame-invisible'.
2123 On graphical displays, invisible frames are not updated and are
2124 usually not displayed at all, even in a window system's \"taskbar\".
2126 If FRAME is a text terminal frame, this always returns t.
2127 Such frames are always considered visible, whether or not they are
2128 currently being displayed on the terminal. */)
2129 (Lisp_Object frame)
2131 CHECK_LIVE_FRAME (frame);
2133 if (FRAME_VISIBLE_P (XFRAME (frame)))
2134 return Qt;
2135 if (FRAME_ICONIFIED_P (XFRAME (frame)))
2136 return Qicon;
2137 return Qnil;
2140 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
2141 0, 0, 0,
2142 doc: /* Return a list of all frames now \"visible\" (being updated). */)
2143 (void)
2145 Lisp_Object tail, frame, value = Qnil;
2147 FOR_EACH_FRAME (tail, frame)
2148 if (FRAME_VISIBLE_P (XFRAME (frame)))
2149 value = Fcons (frame, value);
2151 return value;
2155 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
2156 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
2157 If FRAME is invisible or iconified, make it visible.
2158 If you don't specify a frame, the selected frame is used.
2159 If Emacs is displaying on an ordinary terminal or some other device which
2160 doesn't support multiple overlapping frames, this function selects FRAME. */)
2161 (Lisp_Object frame)
2163 struct frame *f = decode_live_frame (frame);
2165 XSETFRAME (frame, f);
2167 if (FRAME_TERMCAP_P (f))
2168 /* On a text terminal select FRAME. */
2169 Fselect_frame (frame, Qnil);
2170 else
2171 /* Do like the documentation says. */
2172 Fmake_frame_visible (frame);
2174 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2175 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
2177 return Qnil;
2180 /* Should we have a corresponding function called Flower_Power? */
2181 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
2182 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2183 If you don't specify a frame, the selected frame is used.
2184 If Emacs is displaying on an ordinary terminal or some other device which
2185 doesn't support multiple overlapping frames, this function does nothing. */)
2186 (Lisp_Object frame)
2188 struct frame *f = decode_live_frame (frame);
2190 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2191 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
2193 return Qnil;
2197 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
2198 1, 2, 0,
2199 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2200 In other words, switch-frame events caused by events in FRAME will
2201 request a switch to FOCUS-FRAME, and `last-event-frame' will be
2202 FOCUS-FRAME after reading an event typed at FRAME.
2204 If FOCUS-FRAME is nil, any existing redirection is canceled, and the
2205 frame again receives its own keystrokes.
2207 Focus redirection is useful for temporarily redirecting keystrokes to
2208 a surrogate minibuffer frame when a frame doesn't have its own
2209 minibuffer window.
2211 A frame's focus redirection can be changed by `select-frame'. If frame
2212 FOO is selected, and then a different frame BAR is selected, any
2213 frames redirecting their focus to FOO are shifted to redirect their
2214 focus to BAR. This allows focus redirection to work properly when the
2215 user switches from one frame to another using `select-window'.
2217 This means that a frame whose focus is redirected to itself is treated
2218 differently from a frame whose focus is redirected to nil; the former
2219 is affected by `select-frame', while the latter is not.
2221 The redirection lasts until `redirect-frame-focus' is called to change it. */)
2222 (Lisp_Object frame, Lisp_Object focus_frame)
2224 /* Note that we don't check for a live frame here. It's reasonable
2225 to redirect the focus of a frame you're about to delete, if you
2226 know what other frame should receive those keystrokes. */
2227 struct frame *f = decode_any_frame (frame);
2229 if (! NILP (focus_frame))
2230 CHECK_LIVE_FRAME (focus_frame);
2232 fset_focus_frame (f, focus_frame);
2234 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
2235 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
2237 return Qnil;
2241 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 0, 1, 0,
2242 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
2243 If FRAME is omitted or nil, the selected frame is used.
2244 Return nil if FRAME's focus is not redirected.
2245 See `redirect-frame-focus'. */)
2246 (Lisp_Object frame)
2248 return FRAME_FOCUS_FRAME (decode_live_frame (frame));
2251 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
2252 doc: /* Set the input focus to FRAME.
2253 FRAME nil means use the selected frame.
2254 If there is no window system support, this function does nothing. */)
2255 (Lisp_Object frame)
2257 #ifdef HAVE_WINDOW_SYSTEM
2258 x_focus_frame (decode_window_system_frame (frame));
2259 #endif
2260 return Qnil;
2263 DEFUN ("frame-can-run-window-configuration-change-hook",
2264 Fcan_run_window_configuration_change_hook,
2265 Scan_run_window_configuration_change_hook, 2, 2, 0,
2266 doc: /* Whether `window-configuration-change-hook' is run for frame FRAME.
2267 FRAME nil means use the selected frame. Second argument ALLOW non-nil
2268 means functions on `window-configuration-change-hook' are called
2269 whenever the window configuration of FRAME changes. ALLOW nil means
2270 these functions are not called.
2272 This function is currently called by `face-set-after-frame-default' only
2273 and should be otherwise used with utter care to avoid that running
2274 functions on `window-configuration-change-hook' is impeded forever. */)
2275 (Lisp_Object frame, Lisp_Object allow)
2277 struct frame *f = decode_live_frame (frame);
2279 f->can_run_window_configuration_change_hook = NILP (allow) ? false : true;
2280 return Qnil;
2284 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2286 void
2287 frames_discard_buffer (Lisp_Object buffer)
2289 Lisp_Object frame, tail;
2291 FOR_EACH_FRAME (tail, frame)
2293 fset_buffer_list
2294 (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buffer_list));
2295 fset_buried_buffer_list
2296 (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buried_buffer_list));
2300 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2301 If the alist already has an element for PROP, we change it. */
2303 void
2304 store_in_alist (Lisp_Object *alistptr, Lisp_Object prop, Lisp_Object val)
2306 register Lisp_Object tem;
2308 tem = Fassq (prop, *alistptr);
2309 if (EQ (tem, Qnil))
2310 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2311 else
2312 Fsetcdr (tem, val);
2315 static int
2316 frame_name_fnn_p (char *str, ptrdiff_t len)
2318 if (len > 1 && str[0] == 'F' && '0' <= str[1] && str[1] <= '9')
2320 char *p = str + 2;
2321 while ('0' <= *p && *p <= '9')
2322 p++;
2323 if (p == str + len)
2324 return 1;
2326 return 0;
2329 /* Set the name of the terminal frame. Also used by MSDOS frames.
2330 Modeled after x_set_name which is used for WINDOW frames. */
2332 static void
2333 set_term_frame_name (struct frame *f, Lisp_Object name)
2335 f->explicit_name = ! NILP (name);
2337 /* If NAME is nil, set the name to F<num>. */
2338 if (NILP (name))
2340 char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
2342 /* Check for no change needed in this very common case
2343 before we do any consing. */
2344 if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name)))
2345 return;
2347 name = make_formatted_string (namebuf, "F%"pMd, ++tty_frame_count);
2349 else
2351 CHECK_STRING (name);
2353 /* Don't change the name if it's already NAME. */
2354 if (! NILP (Fstring_equal (name, f->name)))
2355 return;
2357 /* Don't allow the user to set the frame name to F<num>, so it
2358 doesn't clash with the names we generate for terminal frames. */
2359 if (frame_name_fnn_p (SSDATA (name), SBYTES (name)))
2360 error ("Frame names of the form F<num> are usurped by Emacs");
2363 fset_name (f, name);
2364 update_mode_lines = 16;
2367 void
2368 store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
2370 register Lisp_Object old_alist_elt;
2372 /* The buffer-list parameters are stored in a special place and not
2373 in the alist. All buffers must be live. */
2374 if (EQ (prop, Qbuffer_list))
2376 Lisp_Object list = Qnil;
2377 for (; CONSP (val); val = XCDR (val))
2378 if (!NILP (Fbuffer_live_p (XCAR (val))))
2379 list = Fcons (XCAR (val), list);
2380 fset_buffer_list (f, Fnreverse (list));
2381 return;
2383 if (EQ (prop, Qburied_buffer_list))
2385 Lisp_Object list = Qnil;
2386 for (; CONSP (val); val = XCDR (val))
2387 if (!NILP (Fbuffer_live_p (XCAR (val))))
2388 list = Fcons (XCAR (val), list);
2389 fset_buried_buffer_list (f, Fnreverse (list));
2390 return;
2393 /* If PROP is a symbol which is supposed to have frame-local values,
2394 and it is set up based on this frame, switch to the global
2395 binding. That way, we can create or alter the frame-local binding
2396 without messing up the symbol's status. */
2397 if (SYMBOLP (prop))
2399 struct Lisp_Symbol *sym = XSYMBOL (prop);
2400 start:
2401 switch (sym->redirect)
2403 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2404 case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
2405 case SYMBOL_LOCALIZED:
2406 { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
2407 if (blv->frame_local && blv_found (blv) && XFRAME (blv->where) == f)
2408 swap_in_global_binding (sym);
2409 break;
2411 default: emacs_abort ();
2415 /* The tty color needed to be set before the frame's parameter
2416 alist was updated with the new value. This is not true any more,
2417 but we still do this test early on. */
2418 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2419 && f == FRAME_TTY (f)->previous_frame)
2420 /* Force redisplay of this tty. */
2421 FRAME_TTY (f)->previous_frame = NULL;
2423 /* Update the frame parameter alist. */
2424 old_alist_elt = Fassq (prop, f->param_alist);
2425 if (EQ (old_alist_elt, Qnil))
2426 fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
2427 else
2428 Fsetcdr (old_alist_elt, val);
2430 /* Update some other special parameters in their special places
2431 in addition to the alist. */
2433 if (EQ (prop, Qbuffer_predicate))
2434 fset_buffer_predicate (f, val);
2436 if (! FRAME_WINDOW_P (f))
2438 if (EQ (prop, Qmenu_bar_lines))
2439 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2440 else if (EQ (prop, Qname))
2441 set_term_frame_name (f, val);
2444 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2446 if (! MINI_WINDOW_P (XWINDOW (val)))
2447 error ("Surrogate minibuffer windows must be minibuffer windows");
2449 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2450 && !EQ (val, f->minibuffer_window))
2451 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2453 /* Install the chosen minibuffer window, with proper buffer. */
2454 fset_minibuffer_window (f, val);
2458 /* Return color matches UNSPEC on frame F or nil if UNSPEC
2459 is not an unspecified foreground or background color. */
2461 static Lisp_Object
2462 frame_unspecified_color (struct frame *f, Lisp_Object unspec)
2464 return (!strncmp (SSDATA (unspec), unspecified_bg, SBYTES (unspec))
2465 ? tty_color_name (f, FRAME_BACKGROUND_PIXEL (f))
2466 : (!strncmp (SSDATA (unspec), unspecified_fg, SBYTES (unspec))
2467 ? tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)) : Qnil));
2470 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2471 doc: /* Return the parameters-alist of frame FRAME.
2472 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2473 The meaningful PARMs depend on the kind of frame.
2474 If FRAME is omitted or nil, return information on the currently selected frame. */)
2475 (Lisp_Object frame)
2477 Lisp_Object alist;
2478 struct frame *f = decode_any_frame (frame);
2479 int height, width;
2480 struct gcpro gcpro1;
2482 if (!FRAME_LIVE_P (f))
2483 return Qnil;
2485 alist = Fcopy_alist (f->param_alist);
2486 GCPRO1 (alist);
2488 if (!FRAME_WINDOW_P (f))
2490 Lisp_Object elt;
2492 /* If the frame's parameter alist says the colors are
2493 unspecified and reversed, take the frame's background pixel
2494 for foreground and vice versa. */
2495 elt = Fassq (Qforeground_color, alist);
2496 if (CONSP (elt) && STRINGP (XCDR (elt)))
2498 elt = frame_unspecified_color (f, XCDR (elt));
2499 if (!NILP (elt))
2500 store_in_alist (&alist, Qforeground_color, elt);
2502 else
2503 store_in_alist (&alist, Qforeground_color,
2504 tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)));
2505 elt = Fassq (Qbackground_color, alist);
2506 if (CONSP (elt) && STRINGP (XCDR (elt)))
2508 elt = frame_unspecified_color (f, XCDR (elt));
2509 if (!NILP (elt))
2510 store_in_alist (&alist, Qbackground_color, elt);
2512 else
2513 store_in_alist (&alist, Qbackground_color,
2514 tty_color_name (f, FRAME_BACKGROUND_PIXEL (f)));
2515 store_in_alist (&alist, intern ("font"),
2516 build_string (FRAME_MSDOS_P (f)
2517 ? "ms-dos"
2518 : FRAME_W32_P (f) ? "w32term"
2519 :"tty"));
2521 store_in_alist (&alist, Qname, f->name);
2522 height = (f->new_height
2523 ? (f->new_pixelwise
2524 ? (f->new_height / FRAME_LINE_HEIGHT (f))
2525 : f->new_height)
2526 : FRAME_LINES (f));
2527 store_in_alist (&alist, Qheight, make_number (height));
2528 width = (f->new_width
2529 ? (f->new_pixelwise
2530 ? (f->new_width / FRAME_COLUMN_WIDTH (f))
2531 : f->new_width)
2532 : FRAME_COLS (f));
2533 store_in_alist (&alist, Qwidth, make_number (width));
2534 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2535 store_in_alist (&alist, Qminibuffer,
2536 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2537 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2538 : FRAME_MINIBUF_WINDOW (f)));
2539 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2540 store_in_alist (&alist, Qbuffer_list, f->buffer_list);
2541 store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
2543 /* I think this should be done with a hook. */
2544 #ifdef HAVE_WINDOW_SYSTEM
2545 if (FRAME_WINDOW_P (f))
2546 x_report_frame_params (f, &alist);
2547 else
2548 #endif
2550 /* This ought to be correct in f->param_alist for an X frame. */
2551 Lisp_Object lines;
2552 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2553 store_in_alist (&alist, Qmenu_bar_lines, lines);
2556 UNGCPRO;
2557 return alist;
2561 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2562 doc: /* Return FRAME's value for parameter PARAMETER.
2563 If FRAME is nil, describe the currently selected frame. */)
2564 (Lisp_Object frame, Lisp_Object parameter)
2566 struct frame *f = decode_any_frame (frame);
2567 Lisp_Object value = Qnil;
2569 CHECK_SYMBOL (parameter);
2571 XSETFRAME (frame, f);
2573 if (FRAME_LIVE_P (f))
2575 /* Avoid consing in frequent cases. */
2576 if (EQ (parameter, Qname))
2577 value = f->name;
2578 #ifdef HAVE_X_WINDOWS
2579 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2580 value = XCAR (FRAME_DISPLAY_INFO (f)->name_list_element);
2581 #endif /* HAVE_X_WINDOWS */
2582 else if (EQ (parameter, Qbackground_color)
2583 || EQ (parameter, Qforeground_color))
2585 value = Fassq (parameter, f->param_alist);
2586 if (CONSP (value))
2588 value = XCDR (value);
2589 /* Fframe_parameters puts the actual fg/bg color names,
2590 even if f->param_alist says otherwise. This is
2591 important when param_alist's notion of colors is
2592 "unspecified". We need to do the same here. */
2593 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2594 value = frame_unspecified_color (f, value);
2596 else
2597 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2599 else if (EQ (parameter, Qdisplay_type)
2600 || EQ (parameter, Qbackground_mode))
2601 value = Fcdr (Fassq (parameter, f->param_alist));
2602 else
2603 /* FIXME: Avoid this code path at all (as well as code duplication)
2604 by sharing more code with Fframe_parameters. */
2605 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2608 return value;
2612 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2613 Smodify_frame_parameters, 2, 2, 0,
2614 doc: /* Modify the parameters of frame FRAME according to ALIST.
2615 If FRAME is nil, it defaults to the selected frame.
2616 ALIST is an alist of parameters to change and their new values.
2617 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2618 The meaningful PARMs depend on the kind of frame.
2619 Undefined PARMs are ignored, but stored in the frame's parameter list
2620 so that `frame-parameters' will return them.
2622 The value of frame parameter FOO can also be accessed
2623 as a frame-local binding for the variable FOO, if you have
2624 enabled such bindings for that variable with `make-variable-frame-local'.
2625 Note that this functionality is obsolete as of Emacs 22.2, and its
2626 use is not recommended. Explicitly check for a frame-parameter instead. */)
2627 (Lisp_Object frame, Lisp_Object alist)
2629 struct frame *f = decode_live_frame (frame);
2630 register Lisp_Object prop, val;
2632 CHECK_LIST (alist);
2634 /* I think this should be done with a hook. */
2635 #ifdef HAVE_WINDOW_SYSTEM
2636 if (FRAME_WINDOW_P (f))
2637 x_set_frame_parameters (f, alist);
2638 else
2639 #endif
2640 #ifdef MSDOS
2641 if (FRAME_MSDOS_P (f))
2642 IT_set_frame_parameters (f, alist);
2643 else
2644 #endif
2647 EMACS_INT length = XFASTINT (Flength (alist));
2648 ptrdiff_t i;
2649 Lisp_Object *parms;
2650 Lisp_Object *values;
2651 USE_SAFE_ALLOCA;
2652 SAFE_ALLOCA_LISP (parms, 2 * length);
2653 values = parms + length;
2655 /* Extract parm names and values into those vectors. */
2657 for (i = 0; CONSP (alist); alist = XCDR (alist))
2659 Lisp_Object elt;
2661 elt = XCAR (alist);
2662 parms[i] = Fcar (elt);
2663 values[i] = Fcdr (elt);
2664 i++;
2667 /* Now process them in reverse of specified order. */
2668 while (--i >= 0)
2670 prop = parms[i];
2671 val = values[i];
2672 store_frame_param (f, prop, val);
2674 if (EQ (prop, Qforeground_color)
2675 || EQ (prop, Qbackground_color))
2676 update_face_from_frame_parameter (f, prop, val);
2679 SAFE_FREE ();
2681 return Qnil;
2684 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2685 0, 1, 0,
2686 doc: /* Height in pixels of a line in the font in frame FRAME.
2687 If FRAME is omitted or nil, the selected frame is used.
2688 For a terminal frame, the value is always 1. */)
2689 (Lisp_Object frame)
2691 #ifdef HAVE_WINDOW_SYSTEM
2692 struct frame *f = decode_any_frame (frame);
2694 if (FRAME_WINDOW_P (f))
2695 return make_number (FRAME_LINE_HEIGHT (f));
2696 else
2697 #endif
2698 return make_number (1);
2702 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2703 0, 1, 0,
2704 doc: /* Width in pixels of characters in the font in frame FRAME.
2705 If FRAME is omitted or nil, the selected frame is used.
2706 On a graphical screen, the width is the standard width of the default font.
2707 For a terminal screen, the value is always 1. */)
2708 (Lisp_Object frame)
2710 #ifdef HAVE_WINDOW_SYSTEM
2711 struct frame *f = decode_any_frame (frame);
2713 if (FRAME_WINDOW_P (f))
2714 return make_number (FRAME_COLUMN_WIDTH (f));
2715 else
2716 #endif
2717 return make_number (1);
2720 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2721 Sframe_pixel_height, 0, 1, 0,
2722 doc: /* Return a FRAME's height in pixels.
2723 If FRAME is omitted or nil, the selected frame is used. The exact value
2724 of the result depends on the window-system and toolkit in use:
2726 In the Gtk+ version of Emacs, it includes only any window (including
2727 the minibuffer or echo area), mode line, and header line. It does not
2728 include the tool bar or menu bar.
2730 With other graphical versions, it also includes the tool bar and the
2731 menu bar.
2733 For a text terminal, it includes the menu bar. In this case, the
2734 result is really in characters rather than pixels (i.e., is identical
2735 to `frame-height'). */)
2736 (Lisp_Object frame)
2738 struct frame *f = decode_any_frame (frame);
2740 #ifdef HAVE_WINDOW_SYSTEM
2741 if (FRAME_WINDOW_P (f))
2742 return make_number (FRAME_PIXEL_HEIGHT (f));
2743 else
2744 #endif
2745 return make_number (FRAME_TOTAL_LINES (f));
2748 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2749 Sframe_pixel_width, 0, 1, 0,
2750 doc: /* Return FRAME's width in pixels.
2751 For a terminal frame, the result really gives the width in characters.
2752 If FRAME is omitted or nil, the selected frame is used. */)
2753 (Lisp_Object frame)
2755 struct frame *f = decode_any_frame (frame);
2757 #ifdef HAVE_WINDOW_SYSTEM
2758 if (FRAME_WINDOW_P (f))
2759 return make_number (FRAME_PIXEL_WIDTH (f));
2760 else
2761 #endif
2762 return make_number (FRAME_TOTAL_COLS (f));
2765 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
2766 Stool_bar_pixel_width, 0, 1, 0,
2767 doc: /* Return width in pixels of FRAME's tool bar.
2768 The result is greater than zero only when the tool bar is on the left
2769 or right side of FRAME. If FRAME is omitted or nil, the selected frame
2770 is used. */)
2771 (Lisp_Object frame)
2773 #ifdef FRAME_TOOLBAR_WIDTH
2774 struct frame *f = decode_any_frame (frame);
2776 if (FRAME_WINDOW_P (f))
2777 return make_number (FRAME_TOOLBAR_WIDTH (f));
2778 #endif
2779 return make_number (0);
2782 DEFUN ("frame-text-cols", Fframe_text_cols, Sframe_text_cols, 0, 1, 0,
2783 doc: /* Return width in columns of FRAME's text area. */)
2784 (Lisp_Object frame)
2786 return make_number (FRAME_COLS (decode_any_frame (frame)));
2789 DEFUN ("frame-text-lines", Fframe_text_lines, Sframe_text_lines, 0, 1, 0,
2790 doc: /* Return height in lines of FRAME's text area. */)
2791 (Lisp_Object frame)
2793 return make_number (FRAME_LINES (decode_any_frame (frame)));
2796 DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0,
2797 doc: /* Return number of total columns of FRAME. */)
2798 (Lisp_Object frame)
2800 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame)));
2803 DEFUN ("frame-total-lines", Fframe_total_lines, Sframe_total_lines, 0, 1, 0,
2804 doc: /* Return number of total lines of FRAME. */)
2805 (Lisp_Object frame)
2807 return make_number (FRAME_TOTAL_LINES (decode_any_frame (frame)));
2810 DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0,
2811 doc: /* Return text area width of FRAME in pixels. */)
2812 (Lisp_Object frame)
2814 return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame)));
2817 DEFUN ("frame-text-height", Fframe_text_height, Sframe_text_height, 0, 1, 0,
2818 doc: /* Return text area height of FRAME in pixels. */)
2819 (Lisp_Object frame)
2821 return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame)));
2824 DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0,
2825 doc: /* Return scroll bar width of FRAME in pixels. */)
2826 (Lisp_Object frame)
2828 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame)));
2831 DEFUN ("frame-scroll-bar-height", Fscroll_bar_height, Sscroll_bar_height, 0, 1, 0,
2832 doc: /* Return scroll bar height of FRAME in pixels. */)
2833 (Lisp_Object frame)
2835 return make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (decode_any_frame (frame)));
2838 DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
2839 doc: /* Return fringe width of FRAME in pixels. */)
2840 (Lisp_Object frame)
2842 return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
2845 DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
2846 doc: /* Return border width of FRAME in pixels. */)
2847 (Lisp_Object frame)
2849 return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
2852 DEFUN ("frame-right-divider-width", Fright_divider_width, Sright_divider_width, 0, 1, 0,
2853 doc: /* Return width (in pixels) of vertical window dividers on FRAME. */)
2854 (Lisp_Object frame)
2856 return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame)));
2859 DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_width, 0, 1, 0,
2860 doc: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
2861 (Lisp_Object frame)
2863 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame)));
2866 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0,
2867 doc: /* Set text height of frame FRAME to HEIGHT lines.
2868 Optional third arg PRETEND non-nil means that redisplay should use
2869 HEIGHT lines but that the idea of the actual height of the frame should
2870 not be changed.
2872 Optional fourth argument PIXELWISE non-nil means that FRAME should be
2873 HEIGHT pixels high. Note: When `frame-resize-pixelwise' is nil, some
2874 window managers may refuse to honor a HEIGHT that is not an integer
2875 multiple of the default frame font height. */)
2876 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
2878 struct frame *f = decode_live_frame (frame);
2879 int pixel_height;
2881 CHECK_TYPE_RANGED_INTEGER (int, height);
2883 pixel_height = (!NILP (pixelwise)
2884 ? XINT (height)
2885 : XINT (height) * FRAME_LINE_HEIGHT (f));
2886 adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend), Qheight);
2888 return Qnil;
2891 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4, 0,
2892 doc: /* Set text width of frame FRAME to WIDTH columns.
2893 Optional third arg PRETEND non-nil means that redisplay should use WIDTH
2894 columns but that the idea of the actual width of the frame should not
2895 be changed.
2897 Optional fourth argument PIXELWISE non-nil means that FRAME should be
2898 WIDTH pixels wide. Note: When `frame-resize-pixelwise' is nil, some
2899 window managers may refuse to honor a WIDTH that is not an integer
2900 multiple of the default frame font width. */)
2901 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
2903 struct frame *f = decode_live_frame (frame);
2904 int pixel_width;
2906 CHECK_TYPE_RANGED_INTEGER (int, width);
2908 pixel_width = (!NILP (pixelwise)
2909 ? XINT (width)
2910 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2911 adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend), Qwidth);
2913 return Qnil;
2916 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
2917 doc: /* Set text size of FRAME to WIDTH by HEIGHT, measured in characters.
2918 Optional argument PIXELWISE non-nil means to measure in pixels. Note:
2919 When `frame-resize-pixelwise' is nil, some window managers may refuse to
2920 honor a WIDTH that is not an integer multiple of the default frame font
2921 width or a HEIGHT that is not an integer multiple of the default frame
2922 font height. */)
2923 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
2925 struct frame *f = decode_live_frame (frame);
2926 int pixel_width, pixel_height;
2928 CHECK_TYPE_RANGED_INTEGER (int, width);
2929 CHECK_TYPE_RANGED_INTEGER (int, height);
2931 pixel_width = (!NILP (pixelwise)
2932 ? XINT (width)
2933 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2934 pixel_height = (!NILP (pixelwise)
2935 ? XINT (height)
2936 : XINT (height) * FRAME_LINE_HEIGHT (f));
2937 adjust_frame_size (f, pixel_width, pixel_height, 1, 0, Qsize);
2939 return Qnil;
2942 DEFUN ("set-frame-position", Fset_frame_position,
2943 Sset_frame_position, 3, 3, 0,
2944 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2945 If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are
2946 actually the position of the upper left corner of the frame. Negative
2947 values for XOFFSET or YOFFSET are interpreted relative to the rightmost
2948 or bottommost possible position (that stays within the screen). */)
2949 (Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset)
2951 register struct frame *f = decode_live_frame (frame);
2953 CHECK_TYPE_RANGED_INTEGER (int, xoffset);
2954 CHECK_TYPE_RANGED_INTEGER (int, yoffset);
2956 /* I think this should be done with a hook. */
2957 #ifdef HAVE_WINDOW_SYSTEM
2958 if (FRAME_WINDOW_P (f))
2959 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2960 #endif
2962 return Qt;
2966 /***********************************************************************
2967 Frame Parameters
2968 ***********************************************************************/
2970 /* Connect the frame-parameter names for X frames
2971 to the ways of passing the parameter values to the window system.
2973 The name of a parameter, as a Lisp symbol,
2974 has an `x-frame-parameter' property which is an integer in Lisp
2975 that is an index in this table. */
2977 struct frame_parm_table {
2978 const char *name;
2979 int sym;
2982 static const struct frame_parm_table frame_parms[] =
2984 {"auto-raise", SYMBOL_INDEX (Qauto_raise)},
2985 {"auto-lower", SYMBOL_INDEX (Qauto_lower)},
2986 {"background-color", -1},
2987 {"border-color", SYMBOL_INDEX (Qborder_color)},
2988 {"border-width", SYMBOL_INDEX (Qborder_width)},
2989 {"cursor-color", SYMBOL_INDEX (Qcursor_color)},
2990 {"cursor-type", SYMBOL_INDEX (Qcursor_type)},
2991 {"font", -1},
2992 {"foreground-color", -1},
2993 {"icon-name", SYMBOL_INDEX (Qicon_name)},
2994 {"icon-type", SYMBOL_INDEX (Qicon_type)},
2995 {"internal-border-width", SYMBOL_INDEX (Qinternal_border_width)},
2996 {"right-divider-width", SYMBOL_INDEX (Qright_divider_width)},
2997 {"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width)},
2998 {"menu-bar-lines", SYMBOL_INDEX (Qmenu_bar_lines)},
2999 {"mouse-color", SYMBOL_INDEX (Qmouse_color)},
3000 {"name", SYMBOL_INDEX (Qname)},
3001 {"scroll-bar-width", SYMBOL_INDEX (Qscroll_bar_width)},
3002 {"scroll-bar-height", SYMBOL_INDEX (Qscroll_bar_height)},
3003 {"title", SYMBOL_INDEX (Qtitle)},
3004 {"unsplittable", SYMBOL_INDEX (Qunsplittable)},
3005 {"vertical-scroll-bars", SYMBOL_INDEX (Qvertical_scroll_bars)},
3006 {"horizontal-scroll-bars", SYMBOL_INDEX (Qhorizontal_scroll_bars)},
3007 {"visibility", SYMBOL_INDEX (Qvisibility)},
3008 {"tool-bar-lines", SYMBOL_INDEX (Qtool_bar_lines)},
3009 {"scroll-bar-foreground", SYMBOL_INDEX (Qscroll_bar_foreground)},
3010 {"scroll-bar-background", SYMBOL_INDEX (Qscroll_bar_background)},
3011 {"screen-gamma", SYMBOL_INDEX (Qscreen_gamma)},
3012 {"line-spacing", SYMBOL_INDEX (Qline_spacing)},
3013 {"left-fringe", SYMBOL_INDEX (Qleft_fringe)},
3014 {"right-fringe", SYMBOL_INDEX (Qright_fringe)},
3015 {"wait-for-wm", SYMBOL_INDEX (Qwait_for_wm)},
3016 {"fullscreen", SYMBOL_INDEX (Qfullscreen)},
3017 {"font-backend", SYMBOL_INDEX (Qfont_backend)},
3018 {"alpha", SYMBOL_INDEX (Qalpha)},
3019 {"sticky", SYMBOL_INDEX (Qsticky)},
3020 {"tool-bar-position", SYMBOL_INDEX (Qtool_bar_position)},
3023 #ifdef HAVE_WINDOW_SYSTEM
3025 /* Change the parameters of frame F as specified by ALIST.
3026 If a parameter is not specially recognized, do nothing special;
3027 otherwise call the `x_set_...' function for that parameter.
3028 Except for certain geometry properties, always call store_frame_param
3029 to store the new value in the parameter alist. */
3031 void
3032 x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3034 Lisp_Object tail;
3036 /* If both of these parameters are present, it's more efficient to
3037 set them both at once. So we wait until we've looked at the
3038 entire list before we set them. */
3039 int width IF_LINT (= 0), height IF_LINT (= 0);
3040 bool width_change = 0, height_change = 0;
3042 /* Same here. */
3043 Lisp_Object left, top;
3045 /* Same with these. */
3046 Lisp_Object icon_left, icon_top;
3048 /* Record in these vectors all the parms specified. */
3049 Lisp_Object *parms;
3050 Lisp_Object *values;
3051 ptrdiff_t i, p;
3052 bool left_no_change = 0, top_no_change = 0;
3053 #ifdef HAVE_X_WINDOWS
3054 bool icon_left_no_change = 0, icon_top_no_change = 0;
3055 #endif
3057 i = 0;
3058 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3059 i++;
3061 USE_SAFE_ALLOCA;
3062 SAFE_ALLOCA_LISP (parms, 2 * i);
3063 values = parms + i;
3065 /* Extract parm names and values into those vectors. */
3067 i = 0;
3068 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3070 Lisp_Object elt;
3072 elt = XCAR (tail);
3073 parms[i] = Fcar (elt);
3074 values[i] = Fcdr (elt);
3075 i++;
3077 /* TAIL and ALIST are not used again below here. */
3078 alist = tail = Qnil;
3080 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
3081 because their values appear in VALUES and strings are not valid. */
3082 top = left = Qunbound;
3083 icon_left = icon_top = Qunbound;
3085 /* Process foreground_color and background_color before anything else.
3086 They are independent of other properties, but other properties (e.g.,
3087 cursor_color) are dependent upon them. */
3088 /* Process default font as well, since fringe widths depends on it. */
3089 for (p = 0; p < i; p++)
3091 Lisp_Object prop, val;
3093 prop = parms[p];
3094 val = values[p];
3095 if (EQ (prop, Qforeground_color)
3096 || EQ (prop, Qbackground_color)
3097 || EQ (prop, Qfont))
3099 register Lisp_Object param_index, old_value;
3101 old_value = get_frame_param (f, prop);
3102 if (NILP (Fequal (val, old_value)))
3104 store_frame_param (f, prop, val);
3106 param_index = Fget (prop, Qx_frame_parameter);
3107 if (NATNUMP (param_index)
3108 && XFASTINT (param_index) < ARRAYELTS (frame_parms)
3109 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3110 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
3115 /* Now process them in reverse of specified order. */
3116 while (i-- != 0)
3118 Lisp_Object prop, val;
3120 prop = parms[i];
3121 val = values[i];
3123 if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX))
3125 width_change = 1;
3126 width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ;
3128 else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX))
3130 height_change = 1;
3131 height = XFASTINT (val) * FRAME_LINE_HEIGHT (f);
3133 else if (EQ (prop, Qtop))
3134 top = val;
3135 else if (EQ (prop, Qleft))
3136 left = val;
3137 else if (EQ (prop, Qicon_top))
3138 icon_top = val;
3139 else if (EQ (prop, Qicon_left))
3140 icon_left = val;
3141 else if (EQ (prop, Qforeground_color)
3142 || EQ (prop, Qbackground_color)
3143 || EQ (prop, Qfont))
3144 /* Processed above. */
3145 continue;
3146 else
3148 register Lisp_Object param_index, old_value;
3150 old_value = get_frame_param (f, prop);
3152 store_frame_param (f, prop, val);
3154 param_index = Fget (prop, Qx_frame_parameter);
3155 if (NATNUMP (param_index)
3156 && XFASTINT (param_index) < ARRAYELTS (frame_parms)
3157 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3158 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
3162 /* Don't die if just one of these was set. */
3163 if (EQ (left, Qunbound))
3165 left_no_change = 1;
3166 if (f->left_pos < 0)
3167 left = list2 (Qplus, make_number (f->left_pos));
3168 else
3169 XSETINT (left, f->left_pos);
3171 if (EQ (top, Qunbound))
3173 top_no_change = 1;
3174 if (f->top_pos < 0)
3175 top = list2 (Qplus, make_number (f->top_pos));
3176 else
3177 XSETINT (top, f->top_pos);
3180 /* If one of the icon positions was not set, preserve or default it. */
3181 if (! TYPE_RANGED_INTEGERP (int, icon_left))
3183 #ifdef HAVE_X_WINDOWS
3184 icon_left_no_change = 1;
3185 #endif
3186 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
3187 if (NILP (icon_left))
3188 XSETINT (icon_left, 0);
3190 if (! TYPE_RANGED_INTEGERP (int, icon_top))
3192 #ifdef HAVE_X_WINDOWS
3193 icon_top_no_change = 1;
3194 #endif
3195 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
3196 if (NILP (icon_top))
3197 XSETINT (icon_top, 0);
3200 /* Don't set these parameters unless they've been explicitly
3201 specified. The window might be mapped or resized while we're in
3202 this function, and we don't want to override that unless the lisp
3203 code has asked for it.
3205 Don't set these parameters unless they actually differ from the
3206 window's current parameters; the window may not actually exist
3207 yet. */
3209 Lisp_Object frame;
3211 XSETFRAME (frame, f);
3213 if ((width_change && width != FRAME_TEXT_WIDTH (f))
3214 || (height_change && height != FRAME_TEXT_HEIGHT (f))
3215 || (f->can_x_set_window_size && (f->new_height || f->new_width)))
3217 /* If necessary provide default values for HEIGHT and WIDTH. Do
3218 that here since otherwise a size change implied by an
3219 intermittent font change may get lost as in Bug#17142. */
3220 if (!width_change)
3221 width = (f->new_width
3222 ? (f->new_pixelwise
3223 ? f->new_width
3224 : (f->new_width * FRAME_COLUMN_WIDTH (f)))
3225 : FRAME_TEXT_WIDTH (f));
3227 if (!height_change)
3228 height = (f->new_height
3229 ? (f->new_pixelwise
3230 ? f->new_height
3231 : (f->new_height * FRAME_LINE_HEIGHT (f)))
3232 : FRAME_TEXT_HEIGHT (f));
3234 Fset_frame_size (frame, make_number (width), make_number (height), Qt);
3237 if ((!NILP (left) || !NILP (top))
3238 && ! (left_no_change && top_no_change)
3239 && ! (NUMBERP (left) && XINT (left) == f->left_pos
3240 && NUMBERP (top) && XINT (top) == f->top_pos))
3242 int leftpos = 0;
3243 int toppos = 0;
3245 /* Record the signs. */
3246 f->size_hint_flags &= ~ (XNegative | YNegative);
3247 if (EQ (left, Qminus))
3248 f->size_hint_flags |= XNegative;
3249 else if (TYPE_RANGED_INTEGERP (int, left))
3251 leftpos = XINT (left);
3252 if (leftpos < 0)
3253 f->size_hint_flags |= XNegative;
3255 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3256 && CONSP (XCDR (left))
3257 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
3259 leftpos = - XINT (XCAR (XCDR (left)));
3260 f->size_hint_flags |= XNegative;
3262 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3263 && CONSP (XCDR (left))
3264 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
3266 leftpos = XINT (XCAR (XCDR (left)));
3269 if (EQ (top, Qminus))
3270 f->size_hint_flags |= YNegative;
3271 else if (TYPE_RANGED_INTEGERP (int, top))
3273 toppos = XINT (top);
3274 if (toppos < 0)
3275 f->size_hint_flags |= YNegative;
3277 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3278 && CONSP (XCDR (top))
3279 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
3281 toppos = - XINT (XCAR (XCDR (top)));
3282 f->size_hint_flags |= YNegative;
3284 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3285 && CONSP (XCDR (top))
3286 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
3288 toppos = XINT (XCAR (XCDR (top)));
3292 /* Store the numeric value of the position. */
3293 f->top_pos = toppos;
3294 f->left_pos = leftpos;
3296 f->win_gravity = NorthWestGravity;
3298 /* Actually set that position, and convert to absolute. */
3299 x_set_offset (f, leftpos, toppos, -1);
3301 #ifdef HAVE_X_WINDOWS
3302 if ((!NILP (icon_left) || !NILP (icon_top))
3303 && ! (icon_left_no_change && icon_top_no_change))
3304 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3305 #endif /* HAVE_X_WINDOWS */
3308 SAFE_FREE ();
3312 /* Insert a description of internally-recorded parameters of frame X
3313 into the parameter alist *ALISTPTR that is to be given to the user.
3314 Only parameters that are specific to the X window system
3315 and whose values are not correctly recorded in the frame's
3316 param_alist need to be considered here. */
3318 void
3319 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
3321 Lisp_Object tem;
3322 uprintmax_t w;
3323 char buf[INT_BUFSIZE_BOUND (w)];
3325 /* Represent negative positions (off the top or left screen edge)
3326 in a way that Fmodify_frame_parameters will understand correctly. */
3327 XSETINT (tem, f->left_pos);
3328 if (f->left_pos >= 0)
3329 store_in_alist (alistptr, Qleft, tem);
3330 else
3331 store_in_alist (alistptr, Qleft, list2 (Qplus, tem));
3333 XSETINT (tem, f->top_pos);
3334 if (f->top_pos >= 0)
3335 store_in_alist (alistptr, Qtop, tem);
3336 else
3337 store_in_alist (alistptr, Qtop, list2 (Qplus, tem));
3339 store_in_alist (alistptr, Qborder_width,
3340 make_number (f->border_width));
3341 store_in_alist (alistptr, Qinternal_border_width,
3342 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
3343 store_in_alist (alistptr, Qright_divider_width,
3344 make_number (FRAME_RIGHT_DIVIDER_WIDTH (f)));
3345 store_in_alist (alistptr, Qbottom_divider_width,
3346 make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f)));
3347 store_in_alist (alistptr, Qleft_fringe,
3348 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
3349 store_in_alist (alistptr, Qright_fringe,
3350 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
3351 store_in_alist (alistptr, Qscroll_bar_width,
3352 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3353 ? make_number (0)
3354 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3355 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3356 /* nil means "use default width"
3357 for non-toolkit scroll bar.
3358 ruler-mode.el depends on this. */
3359 : Qnil));
3360 store_in_alist (alistptr, Qscroll_bar_height,
3361 (! FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)
3362 ? make_number (0)
3363 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0
3364 ? make_number (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f))
3365 /* nil means "use default height"
3366 for non-toolkit scroll bar. */
3367 : Qnil));
3368 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
3369 MS-Windows it returns a value whose type is HANDLE, which is
3370 actually a pointer. Explicit casting avoids compiler
3371 warnings. */
3372 w = (uintptr_t) FRAME_X_WINDOW (f);
3373 store_in_alist (alistptr, Qwindow_id,
3374 make_formatted_string (buf, "%"pMu, w));
3375 #ifdef HAVE_X_WINDOWS
3376 #ifdef USE_X_TOOLKIT
3377 /* Tooltip frame may not have this widget. */
3378 if (FRAME_X_OUTPUT (f)->widget)
3379 #endif
3380 w = (uintptr_t) FRAME_OUTER_WINDOW (f);
3381 store_in_alist (alistptr, Qouter_window_id,
3382 make_formatted_string (buf, "%"pMu, w));
3383 #endif
3384 store_in_alist (alistptr, Qicon_name, f->icon_name);
3385 store_in_alist (alistptr, Qvisibility,
3386 (FRAME_VISIBLE_P (f) ? Qt
3387 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3388 store_in_alist (alistptr, Qdisplay,
3389 XCAR (FRAME_DISPLAY_INFO (f)->name_list_element));
3391 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_DISPLAY_INFO (f)->root_window)
3392 tem = Qnil;
3393 else
3394 tem = make_natnum ((uintptr_t) FRAME_X_OUTPUT (f)->parent_desc);
3395 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
3396 store_in_alist (alistptr, Qparent_id, tem);
3397 store_in_alist (alistptr, Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f));
3401 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3402 the previous value of that parameter, NEW_VALUE is the new value. */
3404 void
3405 x_set_fullscreen (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3407 if (NILP (new_value))
3408 f->want_fullscreen = FULLSCREEN_NONE;
3409 else if (EQ (new_value, Qfullboth) || EQ (new_value, Qfullscreen))
3410 f->want_fullscreen = FULLSCREEN_BOTH;
3411 else if (EQ (new_value, Qfullwidth))
3412 f->want_fullscreen = FULLSCREEN_WIDTH;
3413 else if (EQ (new_value, Qfullheight))
3414 f->want_fullscreen = FULLSCREEN_HEIGHT;
3415 else if (EQ (new_value, Qmaximized))
3416 f->want_fullscreen = FULLSCREEN_MAXIMIZED;
3418 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
3419 FRAME_TERMINAL (f)->fullscreen_hook (f);
3423 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3424 the previous value of that parameter, NEW_VALUE is the new value. */
3426 void
3427 x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3429 if (NILP (new_value))
3430 f->extra_line_spacing = 0;
3431 else if (RANGED_INTEGERP (0, new_value, INT_MAX))
3432 f->extra_line_spacing = XFASTINT (new_value);
3433 else if (FLOATP (new_value))
3435 int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f) + 0.5;
3437 if (new_spacing >= 0)
3438 f->extra_line_spacing = new_spacing;
3439 else
3440 signal_error ("Invalid line-spacing", new_value);
3442 else
3443 signal_error ("Invalid line-spacing", new_value);
3444 if (FRAME_VISIBLE_P (f))
3445 redraw_frame (f);
3449 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3450 the previous value of that parameter, NEW_VALUE is the new value. */
3452 void
3453 x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3455 Lisp_Object bgcolor;
3457 if (NILP (new_value))
3458 f->gamma = 0;
3459 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3460 /* The value 0.4545 is the normal viewing gamma. */
3461 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3462 else
3463 signal_error ("Invalid screen-gamma", new_value);
3465 /* Apply the new gamma value to the frame background. */
3466 bgcolor = Fassq (Qbackground_color, f->param_alist);
3467 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3469 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
3470 if (NATNUMP (parm_index)
3471 && XFASTINT (parm_index) < ARRAYELTS (frame_parms)
3472 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3473 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3474 (f, bgcolor, Qnil);
3477 Fclear_face_cache (Qnil);
3481 void
3482 x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3484 Lisp_Object font_object;
3485 int fontset = -1;
3486 #ifdef HAVE_X_WINDOWS
3487 Lisp_Object font_param = arg;
3488 #endif
3490 /* Set the frame parameter back to the old value because we may
3491 fail to use ARG as the new parameter value. */
3492 store_frame_param (f, Qfont, oldval);
3494 /* ARG is a fontset name, a font name, a cons of fontset name and a
3495 font object, or a font object. In the last case, this function
3496 never fail. */
3497 if (STRINGP (arg))
3499 fontset = fs_query_fontset (arg, 0);
3500 if (fontset < 0)
3502 font_object = font_open_by_name (f, arg);
3503 if (NILP (font_object))
3504 error ("Font `%s' is not defined", SSDATA (arg));
3505 arg = AREF (font_object, FONT_NAME_INDEX);
3507 else if (fontset > 0)
3509 font_object = font_open_by_name (f, fontset_ascii (fontset));
3510 if (NILP (font_object))
3511 error ("Font `%s' is not defined", SDATA (arg));
3512 arg = AREF (font_object, FONT_NAME_INDEX);
3514 else
3515 error ("The default fontset can't be used for a frame font");
3517 else if (CONSP (arg) && STRINGP (XCAR (arg)) && FONT_OBJECT_P (XCDR (arg)))
3519 /* This is the case that the ASCII font of F's fontset XCAR
3520 (arg) is changed to the font XCDR (arg) by
3521 `set-fontset-font'. */
3522 fontset = fs_query_fontset (XCAR (arg), 0);
3523 if (fontset < 0)
3524 error ("Unknown fontset: %s", SDATA (XCAR (arg)));
3525 font_object = XCDR (arg);
3526 arg = AREF (font_object, FONT_NAME_INDEX);
3527 #ifdef HAVE_X_WINDOWS
3528 font_param = Ffont_get (font_object, QCname);
3529 #endif
3531 else if (FONT_OBJECT_P (arg))
3533 font_object = arg;
3534 #ifdef HAVE_X_WINDOWS
3535 font_param = Ffont_get (font_object, QCname);
3536 #endif
3537 /* This is to store the XLFD font name in the frame parameter for
3538 backward compatibility. We should store the font-object
3539 itself in the future. */
3540 arg = AREF (font_object, FONT_NAME_INDEX);
3541 fontset = FRAME_FONTSET (f);
3542 /* Check if we can use the current fontset. If not, set FONTSET
3543 to -1 to generate a new fontset from FONT-OBJECT. */
3544 if (fontset >= 0)
3546 Lisp_Object ascii_font = fontset_ascii (fontset);
3547 Lisp_Object spec = font_spec_from_name (ascii_font);
3549 if (NILP (spec))
3550 signal_error ("Invalid font name", ascii_font);
3552 if (! font_match_p (spec, font_object))
3553 fontset = -1;
3556 else
3557 signal_error ("Invalid font", arg);
3559 if (! NILP (Fequal (font_object, oldval)))
3560 return;
3562 x_new_font (f, font_object, fontset);
3563 store_frame_param (f, Qfont, arg);
3564 #ifdef HAVE_X_WINDOWS
3565 store_frame_param (f, Qfont_param, font_param);
3566 #endif
3567 /* Recalculate toolbar height. */
3568 f->n_tool_bar_rows = 0;
3570 /* Ensure we redraw it. */
3571 clear_current_matrices (f);
3573 /* Attempt to hunt down bug#16028. */
3574 SET_FRAME_GARBAGED (f);
3576 recompute_basic_faces (f);
3578 do_pending_window_change (0);
3580 /* We used to call face-set-after-frame-default here, but it leads to
3581 recursive calls (since that function can set the `default' face's
3582 font which in turns changes the frame's `font' parameter).
3583 Also I don't know what this call is meant to do, but it seems the
3584 wrong way to do it anyway (it does a lot more work than what seems
3585 reasonable in response to a change to `font'). */
3589 void
3590 x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3592 if (! NILP (new_value)
3593 && !CONSP (new_value))
3595 char *p0, *p1;
3597 CHECK_STRING (new_value);
3598 p0 = p1 = SSDATA (new_value);
3599 new_value = Qnil;
3600 while (*p0)
3602 while (*p1 && ! c_isspace (*p1) && *p1 != ',') p1++;
3603 if (p0 < p1)
3604 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3605 new_value);
3606 if (*p1)
3608 int c;
3610 while ((c = *++p1) && c_isspace (c));
3612 p0 = p1;
3614 new_value = Fnreverse (new_value);
3617 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3618 return;
3620 if (FRAME_FONT (f))
3621 free_all_realized_faces (Qnil);
3623 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
3624 if (NILP (new_value))
3626 if (NILP (old_value))
3627 error ("No font backend available");
3628 font_update_drivers (f, old_value);
3629 error ("None of specified font backends are available");
3631 store_frame_param (f, Qfont_backend, new_value);
3633 if (FRAME_FONT (f))
3635 Lisp_Object frame;
3637 XSETFRAME (frame, f);
3638 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3639 face_change = true;
3640 windows_or_buffers_changed = 18;
3644 void
3645 x_set_left_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3647 int unit = FRAME_COLUMN_WIDTH (f);
3648 int old_width = FRAME_LEFT_FRINGE_WIDTH (f);
3649 int new_width;
3651 new_width = (RANGED_INTEGERP (-INT_MAX, new_value, INT_MAX)
3652 ? eabs (XINT (new_value)) : 8);
3654 if (new_width != old_width)
3656 FRAME_LEFT_FRINGE_WIDTH (f) = new_width;
3657 FRAME_FRINGE_COLS (f) /* Round up. */
3658 = (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit;
3660 if (FRAME_X_WINDOW (f) != 0)
3661 adjust_frame_size (f, -1, -1, 3, 0, Qleft_fringe);
3663 SET_FRAME_GARBAGED (f);
3668 void
3669 x_set_right_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3671 int unit = FRAME_COLUMN_WIDTH (f);
3672 int old_width = FRAME_RIGHT_FRINGE_WIDTH (f);
3673 int new_width;
3675 new_width = (RANGED_INTEGERP (-INT_MAX, new_value, INT_MAX)
3676 ? eabs (XINT (new_value)) : 8);
3678 if (new_width != old_width)
3680 FRAME_RIGHT_FRINGE_WIDTH (f) = new_width;
3681 FRAME_FRINGE_COLS (f) /* Round up. */
3682 = (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit;
3684 if (FRAME_X_WINDOW (f) != 0)
3685 adjust_frame_size (f, -1, -1, 3, 0, Qright_fringe);
3687 SET_FRAME_GARBAGED (f);
3692 void
3693 x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3695 CHECK_TYPE_RANGED_INTEGER (int, arg);
3697 if (XINT (arg) == f->border_width)
3698 return;
3700 if (FRAME_X_WINDOW (f) != 0)
3701 error ("Cannot change the border width of a frame");
3703 f->border_width = XINT (arg);
3706 void
3707 x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3709 int old = FRAME_RIGHT_DIVIDER_WIDTH (f);
3711 CHECK_TYPE_RANGED_INTEGER (int, arg);
3712 FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg);
3713 if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0)
3714 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
3715 if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old)
3717 adjust_frame_size (f, -1, -1, 4, 0, Qright_divider_width);
3718 adjust_frame_glyphs (f);
3719 SET_FRAME_GARBAGED (f);
3724 void
3725 x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3727 int old = FRAME_BOTTOM_DIVIDER_WIDTH (f);
3729 CHECK_TYPE_RANGED_INTEGER (int, arg);
3730 FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg);
3731 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0)
3732 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
3733 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old)
3735 adjust_frame_size (f, -1, -1, 4, 0, Qbottom_divider_width);
3736 adjust_frame_glyphs (f);
3737 SET_FRAME_GARBAGED (f);
3741 void
3742 x_set_visibility (struct frame *f, Lisp_Object value, Lisp_Object oldval)
3744 Lisp_Object frame;
3745 XSETFRAME (frame, f);
3747 if (NILP (value))
3748 Fmake_frame_invisible (frame, Qt);
3749 else if (EQ (value, Qicon))
3750 Ficonify_frame (frame);
3751 else
3752 Fmake_frame_visible (frame);
3755 void
3756 x_set_autoraise (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3758 f->auto_raise = !EQ (Qnil, arg);
3761 void
3762 x_set_autolower (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3764 f->auto_lower = !EQ (Qnil, arg);
3767 void
3768 x_set_unsplittable (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3770 f->no_split = !NILP (arg);
3773 void
3774 x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3776 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3777 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3778 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3779 || (!NILP (arg) && !FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3781 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3782 = (NILP (arg)
3783 ? vertical_scroll_bar_none
3784 : EQ (Qleft, arg)
3785 ? vertical_scroll_bar_left
3786 : EQ (Qright, arg)
3787 ? vertical_scroll_bar_right
3788 : EQ (Qleft, Vdefault_frame_scroll_bars)
3789 ? vertical_scroll_bar_left
3790 : EQ (Qright, Vdefault_frame_scroll_bars)
3791 ? vertical_scroll_bar_right
3792 : vertical_scroll_bar_none);
3794 /* We set this parameter before creating the X window for the
3795 frame, so we can get the geometry right from the start.
3796 However, if the window hasn't been created yet, we shouldn't
3797 call x_set_window_size. */
3798 if (FRAME_X_WINDOW (f))
3799 adjust_frame_size (f, -1, -1, 3, 0, Qvertical_scroll_bars);
3801 SET_FRAME_GARBAGED (f);
3805 void
3806 x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3808 #if USE_HORIZONTAL_SCROLL_BARS
3809 if ((NILP (arg) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))
3810 || (!NILP (arg) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)))
3812 f->horizontal_scroll_bars = NILP (arg) ? false : true;
3814 /* We set this parameter before creating the X window for the
3815 frame, so we can get the geometry right from the start.
3816 However, if the window hasn't been created yet, we shouldn't
3817 call x_set_window_size. */
3818 if (FRAME_X_WINDOW (f))
3819 adjust_frame_size (f, -1, -1, 3, 0, Qhorizontal_scroll_bars);
3821 SET_FRAME_GARBAGED (f);
3823 #endif
3826 void
3827 x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3829 int unit = FRAME_COLUMN_WIDTH (f);
3831 if (NILP (arg))
3833 x_set_scroll_bar_default_width (f);
3835 if (FRAME_X_WINDOW (f))
3836 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width);
3838 SET_FRAME_GARBAGED (f);
3840 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3841 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3843 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3844 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
3845 if (FRAME_X_WINDOW (f))
3846 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width);
3848 SET_FRAME_GARBAGED (f);
3851 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3852 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3855 void
3856 x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3858 #if USE_HORIZONTAL_SCROLL_BARS
3859 int unit = FRAME_LINE_HEIGHT (f);
3861 if (NILP (arg))
3863 x_set_scroll_bar_default_height (f);
3865 if (FRAME_X_WINDOW (f))
3866 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height);
3868 SET_FRAME_GARBAGED (f);
3870 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3871 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_HEIGHT (f))
3873 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg);
3874 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit;
3875 if (FRAME_X_WINDOW (f))
3876 adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height);
3878 SET_FRAME_GARBAGED (f);
3881 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.vpos = 0;
3882 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.y = 0;
3883 #endif
3886 void
3887 x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3889 double alpha = 1.0;
3890 double newval[2];
3891 int i;
3892 Lisp_Object item;
3894 for (i = 0; i < 2; i++)
3896 newval[i] = 1.0;
3897 if (CONSP (arg))
3899 item = CAR (arg);
3900 arg = CDR (arg);
3902 else
3903 item = arg;
3905 if (NILP (item))
3906 alpha = - 1.0;
3907 else if (FLOATP (item))
3909 alpha = XFLOAT_DATA (item);
3910 if (! (0 <= alpha && alpha <= 1.0))
3911 args_out_of_range (make_float (0.0), make_float (1.0));
3913 else if (INTEGERP (item))
3915 EMACS_INT ialpha = XINT (item);
3916 if (! (0 <= ialpha && alpha <= 100))
3917 args_out_of_range (make_number (0), make_number (100));
3918 alpha = ialpha / 100.0;
3920 else
3921 wrong_type_argument (Qnumberp, item);
3922 newval[i] = alpha;
3925 for (i = 0; i < 2; i++)
3926 f->alpha[i] = newval[i];
3928 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3929 block_input ();
3930 x_set_frame_alpha (f);
3931 unblock_input ();
3932 #endif
3934 return;
3937 #ifndef HAVE_NS
3939 /* Non-zero if mouse is grabbed on DPYINFO
3940 and we know the frame where it is. */
3942 bool x_mouse_grabbed (Display_Info *dpyinfo)
3944 return (dpyinfo->grabbed
3945 && dpyinfo->last_mouse_frame
3946 && FRAME_LIVE_P (dpyinfo->last_mouse_frame));
3949 /* Re-highlight something with mouse-face properties
3950 on DPYINFO using saved frame and mouse position. */
3952 void
3953 x_redo_mouse_highlight (Display_Info *dpyinfo)
3955 if (dpyinfo->last_mouse_motion_frame
3956 && FRAME_LIVE_P (dpyinfo->last_mouse_motion_frame))
3957 note_mouse_highlight (dpyinfo->last_mouse_motion_frame,
3958 dpyinfo->last_mouse_motion_x,
3959 dpyinfo->last_mouse_motion_y);
3962 #endif /* HAVE_NS */
3964 /* Subroutines of creating an X frame. */
3966 /* Make sure that Vx_resource_name is set to a reasonable value.
3967 Fix it up, or set it to `emacs' if it is too hopeless. */
3969 void
3970 validate_x_resource_name (void)
3972 ptrdiff_t len = 0;
3973 /* Number of valid characters in the resource name. */
3974 ptrdiff_t good_count = 0;
3975 /* Number of invalid characters in the resource name. */
3976 ptrdiff_t bad_count = 0;
3977 Lisp_Object new;
3978 ptrdiff_t i;
3980 if (!STRINGP (Vx_resource_class))
3981 Vx_resource_class = build_string (EMACS_CLASS);
3983 if (STRINGP (Vx_resource_name))
3985 unsigned char *p = SDATA (Vx_resource_name);
3987 len = SBYTES (Vx_resource_name);
3989 /* Only letters, digits, - and _ are valid in resource names.
3990 Count the valid characters and count the invalid ones. */
3991 for (i = 0; i < len; i++)
3993 int c = p[i];
3994 if (! ((c >= 'a' && c <= 'z')
3995 || (c >= 'A' && c <= 'Z')
3996 || (c >= '0' && c <= '9')
3997 || c == '-' || c == '_'))
3998 bad_count++;
3999 else
4000 good_count++;
4003 else
4004 /* Not a string => completely invalid. */
4005 bad_count = 5, good_count = 0;
4007 /* If name is valid already, return. */
4008 if (bad_count == 0)
4009 return;
4011 /* If name is entirely invalid, or nearly so, or is so implausibly
4012 large that alloca might not work, use `emacs'. */
4013 if (good_count < 2 || MAX_ALLOCA - sizeof ".customization" < len)
4015 Vx_resource_name = build_string ("emacs");
4016 return;
4019 /* Name is partly valid. Copy it and replace the invalid characters
4020 with underscores. */
4022 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
4024 for (i = 0; i < len; i++)
4026 int c = SREF (new, i);
4027 if (! ((c >= 'a' && c <= 'z')
4028 || (c >= 'A' && c <= 'Z')
4029 || (c >= '0' && c <= '9')
4030 || c == '-' || c == '_'))
4031 SSET (new, i, '_');
4035 /* Get specified attribute from resource database RDB.
4036 See Fx_get_resource below for other parameters. */
4038 static Lisp_Object
4039 xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
4041 CHECK_STRING (attribute);
4042 CHECK_STRING (class);
4044 if (!NILP (component))
4045 CHECK_STRING (component);
4046 if (!NILP (subclass))
4047 CHECK_STRING (subclass);
4048 if (NILP (component) != NILP (subclass))
4049 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
4051 validate_x_resource_name ();
4053 /* Allocate space for the components, the dots which separate them,
4054 and the final '\0'. Make them big enough for the worst case. */
4055 ptrdiff_t name_keysize = (SBYTES (Vx_resource_name)
4056 + (STRINGP (component)
4057 ? SBYTES (component) : 0)
4058 + SBYTES (attribute)
4059 + 3);
4061 ptrdiff_t class_keysize = (SBYTES (Vx_resource_class)
4062 + SBYTES (class)
4063 + (STRINGP (subclass)
4064 ? SBYTES (subclass) : 0)
4065 + 3);
4066 USE_SAFE_ALLOCA;
4067 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
4068 char *class_key = name_key + name_keysize;
4070 /* Start with emacs.FRAMENAME for the name (the specific one)
4071 and with `Emacs' for the class key (the general one). */
4072 char *nz = lispstpcpy (name_key, Vx_resource_name);
4073 char *cz = lispstpcpy (class_key, Vx_resource_class);
4075 *cz++ = '.';
4076 cz = lispstpcpy (cz, class);
4078 if (!NILP (component))
4080 *cz++ = '.';
4081 lispstpcpy (cz, subclass);
4083 *nz++ = '.';
4084 nz = lispstpcpy (nz, component);
4087 *nz++ = '.';
4088 lispstpcpy (nz, attribute);
4090 char *value = x_get_string_resource (rdb, name_key, class_key);
4091 SAFE_FREE();
4093 if (value && *value)
4094 return build_string (value);
4095 else
4096 return Qnil;
4100 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
4101 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
4102 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
4103 class, where INSTANCE is the name under which Emacs was invoked, or
4104 the name specified by the `-name' or `-rn' command-line arguments.
4106 The optional arguments COMPONENT and SUBCLASS add to the key and the
4107 class, respectively. You must specify both of them or neither.
4108 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
4109 and the class is `Emacs.CLASS.SUBCLASS'. */)
4110 (Lisp_Object attribute, Lisp_Object class, Lisp_Object component,
4111 Lisp_Object subclass)
4113 check_window_system (NULL);
4115 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
4116 attribute, class, component, subclass);
4119 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
4121 Lisp_Object
4122 display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
4123 Lisp_Object class, Lisp_Object component,
4124 Lisp_Object subclass)
4126 return xrdb_get_resource (dpyinfo->xrdb,
4127 attribute, class, component, subclass);
4130 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
4131 /* Used when C code wants a resource value. */
4132 /* Called from oldXMenu/Create.c. */
4133 char *
4134 x_get_resource_string (const char *attribute, const char *class)
4136 char *result;
4137 struct frame *sf = SELECTED_FRAME ();
4138 ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
4139 USE_SAFE_ALLOCA;
4141 /* Allocate space for the components, the dots which separate them,
4142 and the final '\0'. */
4143 ptrdiff_t name_keysize = invocation_namelen + strlen (attribute) + 2;
4144 ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2;
4145 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
4146 char *class_key = name_key + name_keysize;
4148 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
4149 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
4151 result = x_get_string_resource (FRAME_DISPLAY_INFO (sf)->xrdb,
4152 name_key, class_key);
4153 SAFE_FREE ();
4154 return result;
4156 #endif
4158 /* Return the value of parameter PARAM.
4160 First search ALIST, then Vdefault_frame_alist, then the X defaults
4161 database, using ATTRIBUTE as the attribute name and CLASS as its class.
4163 Convert the resource to the type specified by desired_type.
4165 If no default is specified, return Qunbound. If you call
4166 x_get_arg, make sure you deal with Qunbound in a reasonable way,
4167 and don't let it get stored in any Lisp-visible variables! */
4169 Lisp_Object
4170 x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
4171 const char *attribute, const char *class, enum resource_types type)
4173 Lisp_Object tem;
4175 tem = Fassq (param, alist);
4177 if (!NILP (tem))
4179 /* If we find this parm in ALIST, clear it out
4180 so that it won't be "left over" at the end. */
4181 Lisp_Object tail;
4182 XSETCAR (tem, Qnil);
4183 /* In case the parameter appears more than once in the alist,
4184 clear it out. */
4185 for (tail = alist; CONSP (tail); tail = XCDR (tail))
4186 if (CONSP (XCAR (tail))
4187 && EQ (XCAR (XCAR (tail)), param))
4188 XSETCAR (XCAR (tail), Qnil);
4190 else
4191 tem = Fassq (param, Vdefault_frame_alist);
4193 /* If it wasn't specified in ALIST or the Lisp-level defaults,
4194 look in the X resources. */
4195 if (EQ (tem, Qnil))
4197 if (attribute && dpyinfo)
4199 AUTO_STRING (at, attribute);
4200 AUTO_STRING (cl, class);
4201 tem = display_x_get_resource (dpyinfo, at, cl, Qnil, Qnil);
4203 if (NILP (tem))
4204 return Qunbound;
4206 switch (type)
4208 case RES_TYPE_NUMBER:
4209 return make_number (atoi (SSDATA (tem)));
4211 case RES_TYPE_BOOLEAN_NUMBER:
4212 if (!strcmp (SSDATA (tem), "on")
4213 || !strcmp (SSDATA (tem), "true"))
4214 return make_number (1);
4215 return make_number (atoi (SSDATA (tem)));
4216 break;
4218 case RES_TYPE_FLOAT:
4219 return make_float (atof (SSDATA (tem)));
4221 case RES_TYPE_BOOLEAN:
4222 tem = Fdowncase (tem);
4223 if (!strcmp (SSDATA (tem), "on")
4224 #ifdef HAVE_NS
4225 || !strcmp (SSDATA (tem), "yes")
4226 #endif
4227 || !strcmp (SSDATA (tem), "true"))
4228 return Qt;
4229 else
4230 return Qnil;
4232 case RES_TYPE_STRING:
4233 return tem;
4235 case RES_TYPE_SYMBOL:
4236 /* As a special case, we map the values `true' and `on'
4237 to Qt, and `false' and `off' to Qnil. */
4239 Lisp_Object lower;
4240 lower = Fdowncase (tem);
4241 if (!strcmp (SSDATA (lower), "on")
4242 #ifdef HAVE_NS
4243 || !strcmp (SSDATA (lower), "yes")
4244 #endif
4245 || !strcmp (SSDATA (lower), "true"))
4246 return Qt;
4247 else if (!strcmp (SSDATA (lower), "off")
4248 #ifdef HAVE_NS
4249 || !strcmp (SSDATA (lower), "no")
4250 #endif
4251 || !strcmp (SSDATA (lower), "false"))
4252 return Qnil;
4253 else
4254 return Fintern (tem, Qnil);
4257 default:
4258 emacs_abort ();
4261 else
4262 return Qunbound;
4264 return Fcdr (tem);
4267 static Lisp_Object
4268 x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param,
4269 const char *attribute, const char *class,
4270 enum resource_types type)
4272 return x_get_arg (FRAME_DISPLAY_INFO (f),
4273 alist, param, attribute, class, type);
4276 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
4278 Lisp_Object
4279 x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist,
4280 Lisp_Object param,
4281 const char *attribute, const char *class,
4282 enum resource_types type)
4284 Lisp_Object value;
4286 value = x_get_arg (FRAME_DISPLAY_INFO (f), alist, param,
4287 attribute, class, type);
4288 if (! NILP (value) && ! EQ (value, Qunbound))
4289 store_frame_param (f, param, value);
4291 return value;
4295 /* Record in frame F the specified or default value according to ALIST
4296 of the parameter named PROP (a Lisp symbol).
4297 If no value is specified for PROP, look for an X default for XPROP
4298 on the frame named NAME.
4299 If that is not found either, use the value DEFLT. */
4301 Lisp_Object
4302 x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
4303 Lisp_Object deflt, const char *xprop, const char *xclass,
4304 enum resource_types type)
4306 Lisp_Object tem;
4308 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
4309 if (EQ (tem, Qunbound))
4310 tem = deflt;
4311 AUTO_FRAME_ARG (arg, prop, tem);
4312 x_set_frame_parameters (f, arg);
4313 return tem;
4317 #if !defined (HAVE_X_WINDOWS) && defined (NoValue)
4320 * XParseGeometry parses strings of the form
4321 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
4322 * width, height, xoffset, and yoffset are unsigned integers.
4323 * Example: "=80x24+300-49"
4324 * The equal sign is optional.
4325 * It returns a bitmask that indicates which of the four values
4326 * were actually found in the string. For each value found,
4327 * the corresponding argument is updated; for each value
4328 * not found, the corresponding argument is left unchanged.
4331 static int
4332 XParseGeometry (char *string,
4333 int *x, int *y,
4334 unsigned int *width, unsigned int *height)
4336 int mask = NoValue;
4337 char *strind;
4338 unsigned long tempWidth, tempHeight;
4339 long int tempX, tempY;
4340 char *nextCharacter;
4342 if (string == NULL || *string == '\0')
4343 return mask;
4344 if (*string == '=')
4345 string++; /* ignore possible '=' at beg of geometry spec */
4347 strind = string;
4348 if (*strind != '+' && *strind != '-' && *strind != 'x')
4350 tempWidth = strtoul (strind, &nextCharacter, 10);
4351 if (strind == nextCharacter)
4352 return 0;
4353 strind = nextCharacter;
4354 mask |= WidthValue;
4357 if (*strind == 'x' || *strind == 'X')
4359 strind++;
4360 tempHeight = strtoul (strind, &nextCharacter, 10);
4361 if (strind == nextCharacter)
4362 return 0;
4363 strind = nextCharacter;
4364 mask |= HeightValue;
4367 if (*strind == '+' || *strind == '-')
4369 if (*strind == '-')
4370 mask |= XNegative;
4371 tempX = strtol (strind, &nextCharacter, 10);
4372 if (strind == nextCharacter)
4373 return 0;
4374 strind = nextCharacter;
4375 mask |= XValue;
4376 if (*strind == '+' || *strind == '-')
4378 if (*strind == '-')
4379 mask |= YNegative;
4380 tempY = strtol (strind, &nextCharacter, 10);
4381 if (strind == nextCharacter)
4382 return 0;
4383 strind = nextCharacter;
4384 mask |= YValue;
4388 /* If strind isn't at the end of the string then it's an invalid
4389 geometry specification. */
4391 if (*strind != '\0')
4392 return 0;
4394 if (mask & XValue)
4395 *x = clip_to_bounds (INT_MIN, tempX, INT_MAX);
4396 if (mask & YValue)
4397 *y = clip_to_bounds (INT_MIN, tempY, INT_MAX);
4398 if (mask & WidthValue)
4399 *width = min (tempWidth, UINT_MAX);
4400 if (mask & HeightValue)
4401 *height = min (tempHeight, UINT_MAX);
4402 return mask;
4405 #endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
4408 /* NS used to define x-parse-geometry in ns-win.el, but that confused
4409 make-docfile: the documentation string in ns-win.el was used for
4410 x-parse-geometry even in non-NS builds.
4412 With two definitions of x-parse-geometry in this file, various
4413 things still get confused (eg M-x apropos documentation), so that
4414 it is best if the two definitions just share the same doc-string.
4416 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4417 doc: /* Parse a display geometry string STRING.
4418 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4419 The properties returned may include `top', `left', `height', and `width'.
4420 For X, the value of `left' or `top' may be an integer,
4421 or a list (+ N) meaning N pixels relative to top/left corner,
4422 or a list (- N) meaning -N pixels relative to bottom/right corner.
4423 On Nextstep, this just calls `ns-parse-geometry'. */)
4424 (Lisp_Object string)
4426 int geometry, x, y;
4427 unsigned int width, height;
4428 Lisp_Object result;
4430 CHECK_STRING (string);
4432 #ifdef HAVE_NS
4433 if (strchr (SSDATA (string), ' ') != NULL)
4434 return call1 (Qns_parse_geometry, string);
4435 #endif
4436 geometry = XParseGeometry (SSDATA (string),
4437 &x, &y, &width, &height);
4438 result = Qnil;
4439 if (geometry & XValue)
4441 Lisp_Object element;
4443 if (x >= 0 && (geometry & XNegative))
4444 element = list3 (Qleft, Qminus, make_number (-x));
4445 else if (x < 0 && ! (geometry & XNegative))
4446 element = list3 (Qleft, Qplus, make_number (x));
4447 else
4448 element = Fcons (Qleft, make_number (x));
4449 result = Fcons (element, result);
4452 if (geometry & YValue)
4454 Lisp_Object element;
4456 if (y >= 0 && (geometry & YNegative))
4457 element = list3 (Qtop, Qminus, make_number (-y));
4458 else if (y < 0 && ! (geometry & YNegative))
4459 element = list3 (Qtop, Qplus, make_number (y));
4460 else
4461 element = Fcons (Qtop, make_number (y));
4462 result = Fcons (element, result);
4465 if (geometry & WidthValue)
4466 result = Fcons (Fcons (Qwidth, make_number (width)), result);
4467 if (geometry & HeightValue)
4468 result = Fcons (Fcons (Qheight, make_number (height)), result);
4470 return result;
4474 /* Calculate the desired size and position of frame F.
4475 Return the flags saying which aspects were specified.
4477 Also set the win_gravity and size_hint_flags of F.
4479 Adjust height for toolbar if TOOLBAR_P is 1.
4481 This function does not make the coordinates positive. */
4483 #define DEFAULT_ROWS 35
4484 #define DEFAULT_COLS 80
4486 long
4487 x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4489 Lisp_Object height, width, user_size, top, left, user_position;
4490 long window_prompting = 0;
4491 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
4493 /* Default values if we fall through.
4494 Actually, if that happens we should get
4495 window manager prompting. */
4496 SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
4497 SET_FRAME_COLS (f, DEFAULT_COLS);
4498 SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
4499 SET_FRAME_LINES (f, DEFAULT_ROWS);
4501 /* Window managers expect that if program-specified
4502 positions are not (0,0), they're intentional, not defaults. */
4503 f->top_pos = 0;
4504 f->left_pos = 0;
4506 /* Ensure that earlier new_width and new_height settings won't
4507 override what we specify below. */
4508 f->new_width = f->new_height = 0;
4510 height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4511 width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4512 if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
4514 if (!EQ (width, Qunbound))
4516 CHECK_NUMBER (width);
4517 if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
4518 xsignal1 (Qargs_out_of_range, width);
4520 SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
4523 if (!EQ (height, Qunbound))
4525 CHECK_NUMBER (height);
4526 if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
4527 xsignal1 (Qargs_out_of_range, height);
4529 SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
4532 user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4533 if (!NILP (user_size) && !EQ (user_size, Qunbound))
4534 window_prompting |= USSize;
4535 else
4536 window_prompting |= PSize;
4539 /* Add a tool bar height to the initial frame height so that the user
4540 gets a text display area of the size he specified with -g or via
4541 .Xdefaults. Later changes of the tool bar height don't change the
4542 frame size. This is done so that users can create tall Emacs
4543 frames without having to guess how tall the tool bar will get. */
4544 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4546 if (frame_default_tool_bar_height)
4547 FRAME_TOOL_BAR_HEIGHT (f) = frame_default_tool_bar_height;
4548 else
4550 int margin, relief;
4552 relief = (tool_bar_button_relief >= 0
4553 ? tool_bar_button_relief
4554 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4556 if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX))
4557 margin = XFASTINT (Vtool_bar_button_margin);
4558 else if (CONSP (Vtool_bar_button_margin)
4559 && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX))
4560 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4561 else
4562 margin = 0;
4564 FRAME_TOOL_BAR_HEIGHT (f)
4565 = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4569 top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4570 left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4571 user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4572 if (! EQ (top, Qunbound) || ! EQ (left, Qunbound))
4574 if (EQ (top, Qminus))
4576 f->top_pos = 0;
4577 window_prompting |= YNegative;
4579 else if (CONSP (top) && EQ (XCAR (top), Qminus)
4580 && CONSP (XCDR (top))
4581 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
4583 f->top_pos = - XINT (XCAR (XCDR (top)));
4584 window_prompting |= YNegative;
4586 else if (CONSP (top) && EQ (XCAR (top), Qplus)
4587 && CONSP (XCDR (top))
4588 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
4590 f->top_pos = XINT (XCAR (XCDR (top)));
4592 else if (EQ (top, Qunbound))
4593 f->top_pos = 0;
4594 else
4596 CHECK_TYPE_RANGED_INTEGER (int, top);
4597 f->top_pos = XINT (top);
4598 if (f->top_pos < 0)
4599 window_prompting |= YNegative;
4602 if (EQ (left, Qminus))
4604 f->left_pos = 0;
4605 window_prompting |= XNegative;
4607 else if (CONSP (left) && EQ (XCAR (left), Qminus)
4608 && CONSP (XCDR (left))
4609 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
4611 f->left_pos = - XINT (XCAR (XCDR (left)));
4612 window_prompting |= XNegative;
4614 else if (CONSP (left) && EQ (XCAR (left), Qplus)
4615 && CONSP (XCDR (left))
4616 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
4618 f->left_pos = XINT (XCAR (XCDR (left)));
4620 else if (EQ (left, Qunbound))
4621 f->left_pos = 0;
4622 else
4624 CHECK_TYPE_RANGED_INTEGER (int, left);
4625 f->left_pos = XINT (left);
4626 if (f->left_pos < 0)
4627 window_prompting |= XNegative;
4630 if (!NILP (user_position) && ! EQ (user_position, Qunbound))
4631 window_prompting |= USPosition;
4632 else
4633 window_prompting |= PPosition;
4636 if (window_prompting & XNegative)
4638 if (window_prompting & YNegative)
4639 f->win_gravity = SouthEastGravity;
4640 else
4641 f->win_gravity = NorthEastGravity;
4643 else
4645 if (window_prompting & YNegative)
4646 f->win_gravity = SouthWestGravity;
4647 else
4648 f->win_gravity = NorthWestGravity;
4651 f->size_hint_flags = window_prompting;
4653 return window_prompting;
4658 #endif /* HAVE_WINDOW_SYSTEM */
4660 void
4661 frame_make_pointer_invisible (struct frame *f)
4663 if (! NILP (Vmake_pointer_invisible))
4665 if (f && FRAME_LIVE_P (f) && !f->pointer_invisible
4666 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4668 f->mouse_moved = 0;
4669 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 1);
4670 f->pointer_invisible = 1;
4675 void
4676 frame_make_pointer_visible (struct frame *f)
4678 /* We don't check Vmake_pointer_invisible here in case the
4679 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4680 if (f && FRAME_LIVE_P (f) && f->pointer_invisible && f->mouse_moved
4681 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4683 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 0);
4684 f->pointer_invisible = 0;
4688 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p,
4689 Sframe_pointer_visible_p, 0, 1, 0,
4690 doc: /* Return t if the mouse pointer displayed on FRAME is visible.
4691 Otherwise it returns nil. FRAME omitted or nil means the
4692 selected frame. This is useful when `make-pointer-invisible' is set. */)
4693 (Lisp_Object frame)
4695 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
4700 /***********************************************************************
4701 Multimonitor data
4702 ***********************************************************************/
4704 #ifdef HAVE_WINDOW_SYSTEM
4706 # if (defined HAVE_NS \
4707 || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR)))
4708 void
4709 free_monitors (struct MonitorInfo *monitors, int n_monitors)
4711 int i;
4712 for (i = 0; i < n_monitors; ++i)
4713 xfree (monitors[i].name);
4714 xfree (monitors);
4716 # endif
4718 Lisp_Object
4719 make_monitor_attribute_list (struct MonitorInfo *monitors,
4720 int n_monitors,
4721 int primary_monitor,
4722 Lisp_Object monitor_frames,
4723 const char *source)
4725 Lisp_Object attributes_list = Qnil;
4726 Lisp_Object primary_monitor_attributes = Qnil;
4727 int i;
4729 for (i = 0; i < n_monitors; ++i)
4731 Lisp_Object geometry, workarea, attributes = Qnil;
4732 struct MonitorInfo *mi = &monitors[i];
4734 if (mi->geom.width == 0) continue;
4736 workarea = list4i (mi->work.x, mi->work.y,
4737 mi->work.width, mi->work.height);
4738 geometry = list4i (mi->geom.x, mi->geom.y,
4739 mi->geom.width, mi->geom.height);
4740 attributes = Fcons (Fcons (Qsource, build_string (source)),
4741 attributes);
4742 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
4743 attributes);
4744 attributes = Fcons (Fcons (Qmm_size,
4745 list2i (mi->mm_width, mi->mm_height)),
4746 attributes);
4747 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
4748 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
4749 if (mi->name)
4750 attributes = Fcons (Fcons (Qname, make_string (mi->name,
4751 strlen (mi->name))),
4752 attributes);
4754 if (i == primary_monitor)
4755 primary_monitor_attributes = attributes;
4756 else
4757 attributes_list = Fcons (attributes, attributes_list);
4760 if (!NILP (primary_monitor_attributes))
4761 attributes_list = Fcons (primary_monitor_attributes, attributes_list);
4762 return attributes_list;
4765 #endif /* HAVE_WINDOW_SYSTEM */
4768 /***********************************************************************
4769 Initialization
4770 ***********************************************************************/
4772 void
4773 syms_of_frame (void)
4775 DEFSYM (Qframep, "framep");
4776 DEFSYM (Qframe_live_p, "frame-live-p");
4777 DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
4778 DEFSYM (Qexplicit_name, "explicit-name");
4779 DEFSYM (Qheight, "height");
4780 DEFSYM (Qicon, "icon");
4781 DEFSYM (Qminibuffer, "minibuffer");
4782 DEFSYM (Qmodeline, "modeline");
4783 DEFSYM (Qonly, "only");
4784 DEFSYM (Qnone, "none");
4785 DEFSYM (Qwidth, "width");
4786 DEFSYM (Qgeometry, "geometry");
4787 DEFSYM (Qicon_left, "icon-left");
4788 DEFSYM (Qicon_top, "icon-top");
4789 DEFSYM (Qtooltip, "tooltip");
4790 DEFSYM (Quser_position, "user-position");
4791 DEFSYM (Quser_size, "user-size");
4792 DEFSYM (Qwindow_id, "window-id");
4793 #ifdef HAVE_X_WINDOWS
4794 DEFSYM (Qouter_window_id, "outer-window-id");
4795 #endif
4796 DEFSYM (Qparent_id, "parent-id");
4797 DEFSYM (Qx, "x");
4798 DEFSYM (Qw32, "w32");
4799 DEFSYM (Qpc, "pc");
4800 DEFSYM (Qns, "ns");
4801 DEFSYM (Qvisible, "visible");
4802 DEFSYM (Qbuffer_predicate, "buffer-predicate");
4803 DEFSYM (Qbuffer_list, "buffer-list");
4804 DEFSYM (Qburied_buffer_list, "buried-buffer-list");
4805 DEFSYM (Qdisplay_type, "display-type");
4806 DEFSYM (Qbackground_mode, "background-mode");
4807 DEFSYM (Qnoelisp, "noelisp");
4808 DEFSYM (Qtty_color_mode, "tty-color-mode");
4809 DEFSYM (Qtty, "tty");
4810 DEFSYM (Qtty_type, "tty-type");
4812 DEFSYM (Qface_set_after_frame_default, "face-set-after-frame-default");
4814 DEFSYM (Qfullwidth, "fullwidth");
4815 DEFSYM (Qfullheight, "fullheight");
4816 DEFSYM (Qfullboth, "fullboth");
4817 DEFSYM (Qmaximized, "maximized");
4818 DEFSYM (Qx_resource_name, "x-resource-name");
4819 DEFSYM (Qx_frame_parameter, "x-frame-parameter");
4821 DEFSYM (Qterminal, "terminal");
4823 DEFSYM (Qworkarea, "workarea");
4824 DEFSYM (Qmm_size, "mm-size");
4825 DEFSYM (Qframes, "frames");
4826 DEFSYM (Qsource, "source");
4828 DEFSYM (Qframe_position, "frame-position");
4829 DEFSYM (Qframe_outer_size, "frame-outer-size");
4830 DEFSYM (Qexternal_border_size, "external-border-size");
4831 DEFSYM (Qtitle_height, "title-height");
4832 DEFSYM (Qmenu_bar_external, "menu-bar-external");
4833 DEFSYM (Qmenu_bar_size, "menu-bar-size");
4834 DEFSYM (Qtool_bar_external, "tool-bar-external");
4835 DEFSYM (Qtool_bar_size, "tool-bar-size");
4836 DEFSYM (Qframe_inner_size, "frame-inner-size");
4837 DEFSYM (Qchange_frame_size, "change-frame-size");
4838 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
4839 DEFSYM (Qset_window_configuration, "set-window-configuration");
4840 DEFSYM (Qx_create_frame_1, "x-create-frame-1");
4841 DEFSYM (Qx_create_frame_2, "x-create-frame-2");
4843 #ifdef HAVE_NS
4844 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
4845 #endif
4847 DEFSYM (Qalpha, "alpha");
4848 DEFSYM (Qauto_lower, "auto-lower");
4849 DEFSYM (Qauto_raise, "auto-raise");
4850 DEFSYM (Qborder_color, "border-color");
4851 DEFSYM (Qborder_width, "border-width");
4852 DEFSYM (Qbottom_divider_width, "bottom-divider-width");
4853 DEFSYM (Qcursor_color, "cursor-color");
4854 DEFSYM (Qcursor_type, "cursor-type");
4855 DEFSYM (Qfont_backend, "font-backend");
4856 DEFSYM (Qfullscreen, "fullscreen");
4857 DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars");
4858 DEFSYM (Qicon_name, "icon-name");
4859 DEFSYM (Qicon_type, "icon-type");
4860 DEFSYM (Qinternal_border_width, "internal-border-width");
4861 DEFSYM (Qleft_fringe, "left-fringe");
4862 DEFSYM (Qline_spacing, "line-spacing");
4863 DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
4864 DEFSYM (Qmouse_color, "mouse-color");
4865 DEFSYM (Qname, "name");
4866 DEFSYM (Qright_divider_width, "right-divider-width");
4867 DEFSYM (Qright_fringe, "right-fringe");
4868 DEFSYM (Qscreen_gamma, "screen-gamma");
4869 DEFSYM (Qscroll_bar_background, "scroll-bar-background");
4870 DEFSYM (Qscroll_bar_foreground, "scroll-bar-foreground");
4871 DEFSYM (Qscroll_bar_height, "scroll-bar-height");
4872 DEFSYM (Qscroll_bar_width, "scroll-bar-width");
4873 DEFSYM (Qsticky, "sticky");
4874 DEFSYM (Qtitle, "title");
4875 DEFSYM (Qtool_bar_lines, "tool-bar-lines");
4876 DEFSYM (Qtool_bar_position, "tool-bar-position");
4877 DEFSYM (Qunsplittable, "unsplittable");
4878 DEFSYM (Qvertical_scroll_bars, "vertical-scroll-bars");
4879 DEFSYM (Qvisibility, "visibility");
4880 DEFSYM (Qwait_for_wm, "wait-for-wm");
4883 int i;
4885 for (i = 0; i < ARRAYELTS (frame_parms); i++)
4887 Lisp_Object v = (frame_parms[i].sym < 0
4888 ? intern_c_string (frame_parms[i].name)
4889 : builtin_lisp_symbol (frame_parms[i].sym));
4890 Fput (v, Qx_frame_parameter, make_number (i));
4894 #ifdef HAVE_WINDOW_SYSTEM
4895 DEFVAR_LISP ("x-resource-name", Vx_resource_name,
4896 doc: /* The name Emacs uses to look up X resources.
4897 `x-get-resource' uses this as the first component of the instance name
4898 when requesting resource values.
4899 Emacs initially sets `x-resource-name' to the name under which Emacs
4900 was invoked, or to the value specified with the `-name' or `-rn'
4901 switches, if present.
4903 It may be useful to bind this variable locally around a call
4904 to `x-get-resource'. See also the variable `x-resource-class'. */);
4905 Vx_resource_name = Qnil;
4907 DEFVAR_LISP ("x-resource-class", Vx_resource_class,
4908 doc: /* The class Emacs uses to look up X resources.
4909 `x-get-resource' uses this as the first component of the instance class
4910 when requesting resource values.
4912 Emacs initially sets `x-resource-class' to "Emacs".
4914 Setting this variable permanently is not a reasonable thing to do,
4915 but binding this variable locally around a call to `x-get-resource'
4916 is a reasonable practice. See also the variable `x-resource-name'. */);
4917 Vx_resource_class = build_string (EMACS_CLASS);
4919 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit,
4920 doc: /* The lower limit of the frame opacity (alpha transparency).
4921 The value should range from 0 (invisible) to 100 (completely opaque).
4922 You can also use a floating number between 0.0 and 1.0. */);
4923 Vframe_alpha_lower_limit = make_number (20);
4924 #endif
4926 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist,
4927 doc: /* Alist of default values for frame creation.
4928 These may be set in your init file, like this:
4929 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4930 These override values given in window system configuration data,
4931 including X Windows' defaults database.
4932 For values specific to the first Emacs frame, see `initial-frame-alist'.
4933 For window-system specific values, see `window-system-default-frame-alist'.
4934 For values specific to the separate minibuffer frame, see
4935 `minibuffer-frame-alist'.
4936 The `menu-bar-lines' element of the list controls whether new frames
4937 have menu bars; `menu-bar-mode' works by altering this element.
4938 Setting this variable does not affect existing frames, only new ones. */);
4939 Vdefault_frame_alist = Qnil;
4941 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars,
4942 doc: /* Default position of vertical scroll bars on this window-system. */);
4943 #ifdef HAVE_WINDOW_SYSTEM
4944 #if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
4945 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
4946 default. */
4947 Vdefault_frame_scroll_bars = Qright;
4948 #else
4949 Vdefault_frame_scroll_bars = Qleft;
4950 #endif
4951 #else
4952 Vdefault_frame_scroll_bars = Qnil;
4953 #endif
4955 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
4956 scroll_bar_adjust_thumb_portion_p,
4957 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
4958 Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards
4959 even if the end of the buffer is shown (i.e. overscrolling).
4960 Set to nil if you want the thumb to be at the bottom when the end of the buffer
4961 is shown. Also, the thumb fills the whole scroll bar when the entire buffer
4962 is visible. In this case you can not overscroll. */);
4963 scroll_bar_adjust_thumb_portion_p = 1;
4965 DEFVAR_LISP ("terminal-frame", Vterminal_frame,
4966 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4968 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function,
4969 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4970 `mouse-position' and `mouse-pixel-position' call this function, passing their
4971 usual return value as argument, and return whatever this function returns.
4972 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4973 which need to do mouse handling at the Lisp level. */);
4974 Vmouse_position_function = Qnil;
4976 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight,
4977 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4978 If the value is an integer, highlighting is only shown after moving the
4979 mouse, while keyboard input turns off the highlight even when the mouse
4980 is over the clickable text. However, the mouse shape still indicates
4981 when the mouse is over clickable text. */);
4982 Vmouse_highlight = Qt;
4984 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible,
4985 doc: /* If non-nil, make pointer invisible while typing.
4986 The pointer becomes visible again when the mouse is moved. */);
4987 Vmake_pointer_invisible = Qt;
4989 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
4990 doc: /* Normal hook run when a frame gains input focus. */);
4991 Vfocus_in_hook = Qnil;
4992 DEFSYM (Qfocus_in_hook, "focus-in-hook");
4994 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
4995 doc: /* Normal hook run when a frame loses input focus. */);
4996 Vfocus_out_hook = Qnil;
4997 DEFSYM (Qfocus_out_hook, "focus-out-hook");
4999 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
5000 doc: /* Functions run before deleting a frame.
5001 The functions are run with one arg, the frame to be deleted.
5002 See `delete-frame'.
5004 Note that functions in this list may be called just before the frame is
5005 actually deleted, or some time later (or even both when an earlier function
5006 in `delete-frame-functions' (indirectly) calls `delete-frame'
5007 recursively). */);
5008 Vdelete_frame_functions = Qnil;
5009 DEFSYM (Qdelete_frame_functions, "delete-frame-functions");
5011 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode,
5012 doc: /* Non-nil if Menu-Bar mode is enabled.
5013 See the command `menu-bar-mode' for a description of this minor mode.
5014 Setting this variable directly does not take effect;
5015 either customize it (see the info node `Easy Customization')
5016 or call the function `menu-bar-mode'. */);
5017 Vmenu_bar_mode = Qt;
5019 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode,
5020 doc: /* Non-nil if Tool-Bar mode is enabled.
5021 See the command `tool-bar-mode' for a description of this minor mode.
5022 Setting this variable directly does not take effect;
5023 either customize it (see the info node `Easy Customization')
5024 or call the function `tool-bar-mode'. */);
5025 #ifdef HAVE_WINDOW_SYSTEM
5026 Vtool_bar_mode = Qt;
5027 #else
5028 Vtool_bar_mode = Qnil;
5029 #endif
5031 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
5032 doc: /* Minibufferless frames use this frame's minibuffer.
5033 Emacs cannot create minibufferless frames unless this is set to an
5034 appropriate surrogate.
5036 Emacs consults this variable only when creating minibufferless
5037 frames; once the frame is created, it sticks with its assigned
5038 minibuffer, no matter what this variable is set to. This means that
5039 this variable doesn't necessarily say anything meaningful about the
5040 current set of frames, or where the minibuffer is currently being
5041 displayed.
5043 This variable is local to the current terminal and cannot be buffer-local. */);
5045 DEFVAR_BOOL ("focus-follows-mouse", focus_follows_mouse,
5046 doc: /* Non-nil if window system changes focus when you move the mouse.
5047 You should set this variable to tell Emacs how your window manager
5048 handles focus, since there is no way in general for Emacs to find out
5049 automatically. See also `mouse-autoselect-window'. */);
5050 focus_follows_mouse = 0;
5052 DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise,
5053 doc: /* Non-nil means resize frames pixelwise.
5054 If this option is nil, resizing a frame rounds its sizes to the frame's
5055 current values of `frame-char-height' and `frame-char-width'. If this
5056 is non-nil, no rounding occurs, hence frame sizes can increase/decrease
5057 by one pixel.
5059 With some window managers you may have to set this to non-nil in order
5060 to set the size of a frame in pixels, to maximize frames or to make them
5061 fullscreen. To resize your initial frame pixelwise, set this option to
5062 a non-nil value in your init file. */);
5063 frame_resize_pixelwise = 0;
5065 DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize,
5066 doc: /* Whether frames should be resized implicitly.
5067 If this option is nil, setting font, menu bar, tool bar, internal
5068 borders, fringes or scroll bars of a specific frame may resize the frame
5069 in order to preserve the number of columns or lines it displays. If
5070 this option is `t', no such resizing is done. Note that the size of
5071 fullscreen and maximized frames, the height of fullheight frames and the
5072 width of fullwidth frames never change implicitly.
5074 The value of this option can be also be a list of frame parameters. In
5075 this case, resizing is inhibited when changing a parameter that appears
5076 in that list. The parameters currently handled by this option include
5077 `font', `font-backend', `internal-border-width', `menu-bar-lines' and
5078 `tool-bar-lines'.
5080 Changing any of the parameters `scroll-bar-width', `scroll-bar-height',
5081 `vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and
5082 `right-fringe' is handled as if the frame contained just one live
5083 window. This means, for example, that removing vertical scroll bars on
5084 a frame containing several side by side windows will shrink the frame
5085 width by the width of one scroll bar provided this option is nil and
5086 keep it unchanged if this option is either `t' or a list containing
5087 `vertical-scroll-bars'.
5089 The default value is '(tool-bar-lines) on Lucid, Motif and Windows
5090 \(which means that adding/removing a tool bar does not change the frame
5091 height), nil on all other window systems including GTK+ (which means
5092 that changing any of the parameters listed above may change the size of
5093 the frame), and `t' otherwise (which means the frame size never changes
5094 implicitly when there's no window system support).
5096 Note that when a frame is not large enough to accommodate a change of
5097 any of the parameters listed above, Emacs may try to enlarge the frame
5098 even if this option is non-nil. */);
5099 #if defined (HAVE_WINDOW_SYSTEM)
5100 #if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI)
5101 frame_inhibit_implied_resize = list1 (Qtool_bar_lines);
5102 #else
5103 frame_inhibit_implied_resize = Qnil;
5104 #endif
5105 #else
5106 frame_inhibit_implied_resize = Qt;
5107 #endif
5109 DEFVAR_LISP ("frame-adjust-size-history", Vframe_adjust_size_history,
5110 doc: /* History of frame size adjustments. */);
5111 Vframe_adjust_size_history = Qnil;
5113 staticpro (&Vframe_list);
5115 defsubr (&Sframep);
5116 defsubr (&Sframe_live_p);
5117 defsubr (&Swindow_system);
5118 defsubr (&Sframe_windows_min_size);
5119 defsubr (&Smake_terminal_frame);
5120 defsubr (&Shandle_switch_frame);
5121 defsubr (&Sselect_frame);
5122 defsubr (&Sselected_frame);
5123 defsubr (&Sframe_list);
5124 defsubr (&Snext_frame);
5125 defsubr (&Sprevious_frame);
5126 defsubr (&Slast_nonminibuf_frame);
5127 defsubr (&Sdelete_frame);
5128 defsubr (&Smouse_position);
5129 defsubr (&Smouse_pixel_position);
5130 defsubr (&Sset_mouse_position);
5131 defsubr (&Sset_mouse_pixel_position);
5132 #if 0
5133 defsubr (&Sframe_configuration);
5134 defsubr (&Srestore_frame_configuration);
5135 #endif
5136 defsubr (&Smake_frame_visible);
5137 defsubr (&Smake_frame_invisible);
5138 defsubr (&Siconify_frame);
5139 defsubr (&Sframe_visible_p);
5140 defsubr (&Svisible_frame_list);
5141 defsubr (&Sraise_frame);
5142 defsubr (&Slower_frame);
5143 defsubr (&Sx_focus_frame);
5144 defsubr (&Scan_run_window_configuration_change_hook);
5145 defsubr (&Sredirect_frame_focus);
5146 defsubr (&Sframe_focus);
5147 defsubr (&Sframe_parameters);
5148 defsubr (&Sframe_parameter);
5149 defsubr (&Smodify_frame_parameters);
5150 defsubr (&Sframe_char_height);
5151 defsubr (&Sframe_char_width);
5152 defsubr (&Sframe_pixel_height);
5153 defsubr (&Sframe_pixel_width);
5154 defsubr (&Sframe_text_cols);
5155 defsubr (&Sframe_text_lines);
5156 defsubr (&Sframe_total_cols);
5157 defsubr (&Sframe_total_lines);
5158 defsubr (&Sframe_text_width);
5159 defsubr (&Sframe_text_height);
5160 defsubr (&Sscroll_bar_width);
5161 defsubr (&Sscroll_bar_height);
5162 defsubr (&Sfringe_width);
5163 defsubr (&Sborder_width);
5164 defsubr (&Sright_divider_width);
5165 defsubr (&Sbottom_divider_width);
5166 defsubr (&Stool_bar_pixel_width);
5167 defsubr (&Sset_frame_height);
5168 defsubr (&Sset_frame_width);
5169 defsubr (&Sset_frame_size);
5170 defsubr (&Sset_frame_position);
5171 defsubr (&Sframe_pointer_visible_p);
5173 #ifdef HAVE_WINDOW_SYSTEM
5174 defsubr (&Sx_get_resource);
5175 defsubr (&Sx_parse_geometry);
5176 #endif