1 /* Generic frame functions.
3 Copyright (C) 1993-1995, 1997, 1999-2018 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 (at
10 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 <https://www.gnu.org/licenses/>. */
31 #ifdef HAVE_WINDOW_SYSTEM
33 #endif /* HAVE_WINDOW_SYSTEM */
36 /* These help us bind and responding to switch-frame events. */
38 #include "ptr-bounds.h"
40 #include "blockinput.h"
42 #include "termhooks.h"
43 #include "dispextern.h"
45 #ifdef HAVE_WINDOW_SYSTEM
57 /* The currently selected frame. */
59 Lisp_Object selected_frame
;
61 /* A frame which is not just a mini-buffer, or NULL if there are no such
62 frames. This is usually the most recent such frame that was selected. */
64 static struct frame
*last_nonminibuf_frame
;
66 /* False means there are no visible garbaged frames. */
69 /* The default tool bar height for future frames. */
70 #if defined USE_GTK || defined HAVE_NS
71 enum { frame_default_tool_bar_height
= 0 };
73 int frame_default_tool_bar_height
;
76 #ifdef HAVE_WINDOW_SYSTEM
77 static void x_report_frame_params (struct frame
*, Lisp_Object
*);
80 /* These setters are used only in this file, so they can be private. */
82 fset_buffer_predicate (struct frame
*f
, Lisp_Object val
)
84 f
->buffer_predicate
= val
;
87 fset_minibuffer_window (struct frame
*f
, Lisp_Object val
)
89 f
->minibuffer_window
= val
;
93 decode_live_frame (register Lisp_Object frame
)
96 frame
= selected_frame
;
97 CHECK_LIVE_FRAME (frame
);
98 return XFRAME (frame
);
102 decode_any_frame (register Lisp_Object frame
)
105 frame
= selected_frame
;
107 return XFRAME (frame
);
110 #ifdef HAVE_WINDOW_SYSTEM
112 display_available (void)
114 return x_display_list
!= NULL
;
119 decode_window_system_frame (Lisp_Object frame
)
121 struct frame
*f
= decode_live_frame (frame
);
122 check_window_system (f
);
123 #ifdef HAVE_WINDOW_SYSTEM
129 check_window_system (struct frame
*f
)
131 #ifdef HAVE_WINDOW_SYSTEM
132 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. */
142 get_frame_param (struct frame
*frame
, Lisp_Object prop
)
144 return Fcdr (Fassq (prop
, frame
->param_alist
));
149 frame_size_history_add (struct frame
*f
, Lisp_Object fun_symbol
,
150 int width
, int height
, Lisp_Object rest
)
154 XSETFRAME (frame
, f
);
155 if (CONSP (frame_size_history
)
156 && INTEGERP (XCAR (frame_size_history
))
157 && 0 < XINT (XCAR (frame_size_history
)))
159 Fcons (make_number (XINT (XCAR (frame_size_history
)) - 1),
163 ? list4 (make_number (FRAME_TEXT_WIDTH (f
)),
164 make_number (FRAME_TEXT_HEIGHT (f
)),
166 make_number (height
))
169 XCDR (frame_size_history
)));
173 /* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
174 state of frame F would be affected by a vertical (horizontal if
175 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
176 parameter that is changed. */
178 frame_inhibit_resize (struct frame
*f
, bool horizontal
, Lisp_Object parameter
)
180 Lisp_Object fullscreen
= get_frame_param (f
, Qfullscreen
);
182 = (f
->after_make_frame
183 ? (EQ (frame_inhibit_implied_resize
, Qt
)
184 || (CONSP (frame_inhibit_implied_resize
)
185 && !NILP (Fmemq (parameter
, frame_inhibit_implied_resize
)))
187 && !NILP (fullscreen
) && !EQ (fullscreen
, Qfullheight
))
189 && !NILP (fullscreen
) && !EQ (fullscreen
, Qfullwidth
))
190 || FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
191 : ((horizontal
&& f
->inhibit_horizontal_resize
)
192 || (!horizontal
&& f
->inhibit_vertical_resize
)));
193 if (inhibit
&& !FRAME_TERMCAP_P (f
) && !FRAME_MSDOS_P (f
))
194 frame_size_history_add
195 (f
, Qframe_inhibit_resize
, 0, 0,
196 list5 (horizontal
? Qt
: Qnil
, parameter
,
197 f
->after_make_frame
? Qt
: Qnil
,
198 frame_inhibit_implied_resize
,
205 set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
208 int olines
= FRAME_MENU_BAR_LINES (f
);
210 /* Right now, menu bars don't work properly in minibuf-only frames;
211 most of the commands try to apply themselves to the minibuffer
212 frame itself, and get an error because you can't switch buffers
213 in or split the minibuffer window. */
214 if (FRAME_MINIBUF_ONLY_P (f
))
217 if (TYPE_RANGED_INTEGERP (int, value
))
218 nlines
= XINT (value
);
222 if (nlines
!= olines
)
224 windows_or_buffers_changed
= 14;
225 FRAME_MENU_BAR_LINES (f
) = nlines
;
226 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
227 change_frame_size (f
, FRAME_COLS (f
),
228 FRAME_LINES (f
) + olines
- nlines
,
233 Lisp_Object Vframe_list
;
236 DEFUN ("framep", Fframep
, Sframep
, 1, 1, 0,
237 doc
: /* Return non-nil if OBJECT is a frame.
239 t for a termcap frame (a character-only terminal),
240 `x' for an Emacs frame that is really an X window,
241 `w32' for an Emacs frame that is a window on MS-Windows display,
242 `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
243 `pc' for a direct-write MS-DOS frame.
244 See also `frame-live-p'. */)
247 if (!FRAMEP (object
))
249 switch (XFRAME (object
)->output_method
)
251 case output_initial
: /* The initial frame is like a termcap frame. */
254 case output_x_window
:
258 case output_msdos_raw
:
267 DEFUN ("frame-live-p", Fframe_live_p
, Sframe_live_p
, 1, 1, 0,
268 doc
: /* Return non-nil if OBJECT is a frame which has not been deleted.
269 Value is nil if OBJECT is not a live frame. If object is a live
270 frame, the return value indicates what sort of terminal device it is
271 displayed on. See the documentation of `framep' for possible
275 return ((FRAMEP (object
)
276 && FRAME_LIVE_P (XFRAME (object
)))
281 DEFUN ("window-system", Fwindow_system
, Swindow_system
, 0, 1, 0,
282 doc
: /* The name of the window system that FRAME is displaying through.
283 The value is a symbol:
284 nil for a termcap frame (a character-only terminal),
285 `x' for an Emacs frame that is really an X window,
286 `w32' for an Emacs frame that is a window on MS-Windows display,
287 `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
288 `pc' for a direct-write MS-DOS frame.
290 FRAME defaults to the currently selected frame.
292 Use of this function as a predicate is deprecated. Instead,
293 use `display-graphic-p' or any of the other `display-*-p'
294 predicates which report frame's specific UI-related capabilities. */)
299 frame
= selected_frame
;
301 type
= Fframep (frame
);
304 wrong_type_argument (Qframep
, frame
);
312 /* Placeholder used by temacs -nw before window.el is loaded. */
313 DEFUN ("frame-windows-min-size", Fframe_windows_min_size
,
314 Sframe_windows_min_size
, 4, 4, 0,
315 doc
: /* SKIP: real doc in window.el. */
317 (Lisp_Object frame
, Lisp_Object horizontal
,
318 Lisp_Object ignore
, Lisp_Object pixelwise
)
320 return make_number (0);
324 * frame_windows_min_size:
326 * Return the minimum number of lines (columns if HORIZONTAL is non-nil)
327 * of FRAME. If PIXELWISE is non-nil, return the minimum inner height
328 * (width) of FRAME in pixels.
330 * This value is calculated by the function `frame-windows-min-size' in
331 * window.el unless the `min-height' (`min-width' if HORIZONTAL is
332 * non-nil) parameter of FRAME is non-nil thus explicitly specifying the
333 * value to be returned. In that latter case IGNORE is ignored.
335 * If `frame-windows-min-size' is called, it will make sure that the
336 * return value accommodates all windows of FRAME respecting the values
337 * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil).
338 * With IGNORE non-nil the values of these variables are ignored.
340 * In either case, never return a value less than 1. For TTY frames,
341 * additionally limit the minimum frame height to a value large enough
342 * to support the menu bar, the mode line, and the echo area.
345 frame_windows_min_size (Lisp_Object frame
, Lisp_Object horizontal
,
346 Lisp_Object ignore
, Lisp_Object pixelwise
)
348 struct frame
*f
= XFRAME (frame
);
349 Lisp_Object par_size
;
352 if ((!NILP (horizontal
)
353 && NUMBERP (par_size
= get_frame_param (f
, Qmin_width
)))
354 || (NILP (horizontal
)
355 && NUMBERP (par_size
= get_frame_param (f
, Qmin_height
))))
357 int min_size
= XINT (par_size
);
359 /* Don't allow phantom frames. */
363 retval
= (NILP (pixelwise
)
365 : min_size
* (NILP (horizontal
)
366 ? FRAME_LINE_HEIGHT (f
)
367 : FRAME_COLUMN_WIDTH (f
)));
370 retval
= XINT (call4 (Qframe_windows_min_size
, frame
, horizontal
,
372 /* Don't allow too small height of text-mode frames, or else cm.c
373 might abort in cmcheckmagic. */
374 if ((FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
)) && NILP (horizontal
))
376 int min_height
= (FRAME_MENU_BAR_LINES (f
)
377 + FRAME_WANTS_MODELINE_P (f
)
378 + 2); /* one text line and one echo-area line */
379 if (retval
< min_height
)
387 #ifdef HAVE_WINDOW_SYSTEM
391 * Preserve ratios of frame F which usually happens after its parent
392 * frame P got resized. OLD_WIDTH, OLD_HEIGHT specifies the old native
393 * size of F's parent, NEW_WIDTH and NEW_HEIGHT its new size.
395 * Adjust F's width if F's 'keep_ratio' parameter is non-nil and, if
396 * it is a cons, its car is not 'height-only'. Adjust F's height if F's
397 * 'keep_ratio' parameter is non-nil and, if it is a cons, its car
398 * is not 'width-only'.
400 * Adjust F's left position if F's 'keep_ratio' parameter is non-nil
401 * and, if its is a cons, its cdr is non-nil and not 'top-only'. Adjust
402 * F's top position if F's 'keep_ratio' parameter is non-nil and, if
403 * its is a cons, its cdr is non-nil and not 'left-only'.
405 * Note that when positional adjustment is requested but the size of F
406 * should remain unaltered in the corresponding direction, this routine
407 * tries to constrain F to its parent frame - something which usually
408 * happens when the parent frame shrinks. This means, however, that
409 * when the parent frame is re-enlarged later, the child's original
410 * position will not get restored to its pre-shrinking value.
412 * This routine is currently useful for child frames only. It might be
413 * eventually useful when moving non-child frames between monitors with
414 * different resolutions.
417 keep_ratio (struct frame
*f
, struct frame
*p
, int old_width
, int old_height
,
418 int new_width
, int new_height
)
420 Lisp_Object keep_ratio
= get_frame_param (f
, Qkeep_ratio
);
423 if (!NILP (keep_ratio
))
425 double width_factor
= (double)new_width
/ (double)old_width
;
426 double height_factor
= (double)new_height
/ (double)old_height
;
427 int pixel_width
, pixel_height
, pos_x
, pos_y
;
429 if (!CONSP (keep_ratio
) || !NILP (Fcdr (keep_ratio
)))
431 if (CONSP (keep_ratio
) && EQ (Fcdr (keep_ratio
), Qtop_only
))
435 pos_x
= (int)(f
->left_pos
* width_factor
+ 0.5);
437 if (CONSP (keep_ratio
)
438 && (NILP (Fcar (keep_ratio
))
439 || EQ (Fcar (keep_ratio
), Qheight_only
))
440 && p
->pixel_width
- f
->pixel_width
< pos_x
)
442 int p_f_width
= p
->pixel_width
- f
->pixel_width
;
447 pos_x
= (int)(p_f_width
* width_factor
* 0.5 + 0.5);
453 if (CONSP (keep_ratio
) && EQ (Fcdr (keep_ratio
), Qleft_only
))
457 pos_y
= (int)(f
->top_pos
* height_factor
+ 0.5);
459 if (CONSP (keep_ratio
)
460 && (NILP (Fcar (keep_ratio
))
461 || EQ (Fcar (keep_ratio
), Qwidth_only
))
462 && p
->pixel_height
- f
->pixel_height
< pos_y
)
463 /* When positional adjustment was requested and the
464 width of F should remain unaltered, try to constrain
465 F to its parent. This means that when the parent
466 frame is enlarged later the child's original position
467 won't get restored. */
469 int p_f_height
= p
->pixel_height
- f
->pixel_height
;
474 pos_y
= (int)(p_f_height
* height_factor
* 0.5 + 0.5);
480 x_set_offset (f
, pos_x
, pos_y
, -1);
483 if (!CONSP (keep_ratio
) || !NILP (Fcar (keep_ratio
)))
485 if (CONSP (keep_ratio
) && EQ (Fcar (keep_ratio
), Qheight_only
))
489 pixel_width
= (int)(f
->pixel_width
* width_factor
+ 0.5);
490 pixel_width
= FRAME_PIXEL_TO_TEXT_WIDTH (f
, pixel_width
);
493 if (CONSP (keep_ratio
) && EQ (Fcar (keep_ratio
), Qwidth_only
))
497 pixel_height
= (int)(f
->pixel_height
* height_factor
+ 0.5);
498 pixel_height
= FRAME_PIXEL_TO_TEXT_HEIGHT (f
, pixel_height
);
501 adjust_frame_size (f
, pixel_width
, pixel_height
, 1, 0,
512 * Adjust size of frame F. NEW_WIDTH and NEW_HEIGHT specify the new
513 * text size of F in pixels. A value of -1 means no change is requested
514 * for that direction (but the frame may still have to be resized to
515 * accommodate windows with their minimum sizes). This can either issue
516 * a request to resize the frame externally (via x_set_window_size), to
517 * resize the frame internally (via resize_frame_windows) or do nothing
520 * The argument INHIBIT can assume the following values:
522 * 0 means to unconditionally call x_set_window_size even if sizes
523 * apparently do not change. Fx_create_frame uses this to pass the
524 * initial size to the window manager.
526 * 1 means to call x_set_window_size if the native frame size really
527 * changes. Fset_frame_size, Fset_frame_height, ... use this.
529 * 2 means to call x_set_window_size provided frame_inhibit_resize
530 * allows it. The menu and tool bar code use this ("3" won't work
531 * here in general because menu and tool bar are often not counted in
532 * the frame's text height).
534 * 3 means call x_set_window_size if window minimum sizes must be
535 * preserved or frame_inhibit_resize allows it. x_set_left_fringe,
536 * x_set_scroll_bar_width, x_new_font ... use (or should use) this.
538 * 4 means call x_set_window_size only if window minimum sizes must be
539 * preserved. x_set_right_divider_width, x_set_border_width and the
540 * code responsible for wrapping the tool bar use this.
542 * 5 means to never call x_set_window_size. change_frame_size uses
545 * Note that even when x_set_window_size is not called, individual
546 * windows may have to be resized (via `window--sanitize-window-sizes')
547 * in order to support minimum size constraints.
549 * PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
550 * symbol of the parameter changed (like `menu-bar-lines', `font', ...).
551 * This is passed on to frame_inhibit_resize to let the latter decide on
552 * a case-by-case basis whether the frame may be resized externally.
555 adjust_frame_size (struct frame
*f
, int new_width
, int new_height
, int inhibit
,
556 bool pretend
, Lisp_Object parameter
)
558 int unit_width
= FRAME_COLUMN_WIDTH (f
);
559 int unit_height
= FRAME_LINE_HEIGHT (f
);
560 int old_pixel_width
= FRAME_PIXEL_WIDTH (f
);
561 int old_pixel_height
= FRAME_PIXEL_HEIGHT (f
);
562 int old_cols
= FRAME_COLS (f
);
563 int old_lines
= FRAME_LINES (f
);
564 int new_pixel_width
, new_pixel_height
;
565 /* The following two values are calculated from the old frame pixel
566 sizes and any "new" settings for tool bar, menu bar and internal
567 borders. We do it this way to detect whether we have to call
568 x_set_window_size as consequence of the new settings. */
569 int windows_width
= FRAME_WINDOWS_WIDTH (f
);
570 int windows_height
= FRAME_WINDOWS_HEIGHT (f
);
571 int min_windows_width
, min_windows_height
;
572 /* These are a bit tedious, maybe we should use a macro. */
573 struct window
*r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
574 int old_windows_width
= WINDOW_PIXEL_WIDTH (r
);
575 int old_windows_height
576 = (WINDOW_PIXEL_HEIGHT (r
)
577 + ((FRAME_HAS_MINIBUF_P (f
) && !FRAME_MINIBUF_ONLY_P (f
))
578 ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f
)))
580 int new_windows_width
, new_windows_height
;
581 int old_text_width
= FRAME_TEXT_WIDTH (f
);
582 int old_text_height
= FRAME_TEXT_HEIGHT (f
);
583 /* If a size is < 0 use the old value. */
584 int new_text_width
= (new_width
>= 0) ? new_width
: old_text_width
;
585 int new_text_height
= (new_height
>= 0) ? new_height
: old_text_height
;
586 int new_cols
, new_lines
;
587 bool inhibit_horizontal
, inhibit_vertical
;
590 XSETFRAME (frame
, f
);
592 frame_size_history_add
593 (f
, Qadjust_frame_size_1
, new_text_width
, new_text_height
,
594 list2 (parameter
, make_number (inhibit
)));
596 /* The following two values are calculated from the old window body
597 sizes and any "new" settings for scroll bars, dividers, fringes and
598 margins (though the latter should have been processed already). */
600 = frame_windows_min_size (frame
, Qt
, (inhibit
== 5) ? Qt
: Qnil
, Qt
);
602 = frame_windows_min_size (frame
, Qnil
, (inhibit
== 5) ? Qt
: Qnil
, Qt
);
604 if (inhibit
>= 2 && inhibit
<= 4)
605 /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
606 within the limits and either resizing is inhibited or INHIBIT
609 inhibit_horizontal
= (windows_width
>= min_windows_width
611 || frame_inhibit_resize (f
, true, parameter
)));
612 inhibit_vertical
= (windows_height
>= min_windows_height
614 || frame_inhibit_resize (f
, false, parameter
)));
617 /* Otherwise inhibit if INHIBIT equals 5. */
618 inhibit_horizontal
= inhibit_vertical
= inhibit
== 5;
620 new_pixel_width
= ((inhibit_horizontal
&& (inhibit
< 5))
622 : max (FRAME_TEXT_TO_PIXEL_WIDTH (f
, new_text_width
),
624 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)));
625 new_windows_width
= new_pixel_width
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
626 new_text_width
= FRAME_PIXEL_TO_TEXT_WIDTH (f
, new_pixel_width
);
627 new_cols
= new_text_width
/ unit_width
;
629 new_pixel_height
= ((inhibit_vertical
&& (inhibit
< 5))
631 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f
, new_text_height
),
633 + FRAME_TOP_MARGIN_HEIGHT (f
)
634 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)));
635 new_windows_height
= (new_pixel_height
636 - FRAME_TOP_MARGIN_HEIGHT (f
)
637 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
638 new_text_height
= FRAME_PIXEL_TO_TEXT_HEIGHT (f
, new_pixel_height
);
639 new_lines
= new_text_height
/ unit_height
;
641 #ifdef HAVE_WINDOW_SYSTEM
642 if (FRAME_WINDOW_P (f
)
643 && f
->can_x_set_window_size
644 && ((!inhibit_horizontal
645 && (new_pixel_width
!= old_pixel_width
646 || inhibit
== 0 || inhibit
== 2))
647 || (!inhibit_vertical
648 && (new_pixel_height
!= old_pixel_height
649 || inhibit
== 0 || inhibit
== 2))))
650 /* We are either allowed to change the frame size or the minimum
651 sizes request such a change. Do not care for fixing minimum
652 sizes here, we do that eventually when we're called from
653 change_frame_size. */
655 /* Make sure we respect fullheight and fullwidth. */
656 if (inhibit_horizontal
)
657 new_text_width
= old_text_width
;
658 else if (inhibit_vertical
)
659 new_text_height
= old_text_height
;
661 frame_size_history_add
662 (f
, Qadjust_frame_size_2
, new_text_width
, new_text_height
,
663 list2 (inhibit_horizontal
? Qt
: Qnil
,
664 inhibit_vertical
? Qt
: Qnil
));
666 x_set_window_size (f
, 0, new_text_width
, new_text_height
, 1);
673 if (new_text_width
== old_text_width
674 && new_text_height
== old_text_height
675 && new_windows_width
== old_windows_width
676 && new_windows_height
== old_windows_height
677 && new_pixel_width
== old_pixel_width
678 && new_pixel_height
== old_pixel_height
679 && new_cols
== old_cols
680 && new_lines
== old_lines
)
681 /* No change. Sanitize window sizes and return. */
683 sanitize_window_sizes (Qt
);
684 sanitize_window_sizes (Qnil
);
692 /* We only can set screen dimensions to certain values supported by
693 our video hardware. Try to find the smallest size greater or
694 equal to the requested dimensions, while accounting for the fact
695 that the menu-bar lines are not counted in the frame height. */
696 int dos_new_lines
= new_lines
+ FRAME_TOP_MARGIN (f
);
697 dos_set_window_size (&dos_new_lines
, &new_cols
);
698 new_lines
= dos_new_lines
- FRAME_TOP_MARGIN (f
);
701 if (new_windows_width
!= old_windows_width
)
703 resize_frame_windows (f
, new_windows_width
, 1, 1);
705 /* MSDOS frames cannot PRETEND, as they change frame size by
706 manipulating video hardware. */
707 if ((FRAME_TERMCAP_P (f
) && !pretend
) || FRAME_MSDOS_P (f
))
708 FrameCols (FRAME_TTY (f
)) = new_cols
;
710 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
711 if (WINDOWP (f
->tool_bar_window
))
713 XWINDOW (f
->tool_bar_window
)->pixel_width
= new_windows_width
;
714 XWINDOW (f
->tool_bar_window
)->total_cols
715 = new_windows_width
/ unit_width
;
719 else if (new_cols
!= old_cols
)
720 call2 (Qwindow__pixel_to_total
, frame
, Qt
);
722 if (new_windows_height
!= old_windows_height
723 /* When the top margin has changed we have to recalculate the top
724 edges of all windows. No such calculation is necessary for the
726 || WINDOW_TOP_PIXEL_EDGE (r
) != FRAME_TOP_MARGIN_HEIGHT (f
))
728 resize_frame_windows (f
, new_windows_height
, 0, 1);
730 /* MSDOS frames cannot PRETEND, as they change frame size by
731 manipulating video hardware. */
732 if ((FRAME_TERMCAP_P (f
) && !pretend
) || FRAME_MSDOS_P (f
))
733 FrameRows (FRAME_TTY (f
)) = new_lines
+ FRAME_TOP_MARGIN (f
);
735 else if (new_lines
!= old_lines
)
736 call2 (Qwindow__pixel_to_total
, frame
, Qnil
);
738 frame_size_history_add
739 (f
, Qadjust_frame_size_3
, new_text_width
, new_text_height
,
740 list4 (make_number (old_pixel_width
), make_number (old_pixel_height
),
741 make_number (new_pixel_width
), make_number (new_pixel_height
)));
743 /* Assign new sizes. */
744 FRAME_TEXT_WIDTH (f
) = new_text_width
;
745 FRAME_TEXT_HEIGHT (f
) = new_text_height
;
746 FRAME_PIXEL_WIDTH (f
) = new_pixel_width
;
747 FRAME_PIXEL_HEIGHT (f
) = new_pixel_height
;
748 SET_FRAME_COLS (f
, new_cols
);
749 SET_FRAME_LINES (f
, new_lines
);
752 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
753 int text_area_x
, text_area_y
, text_area_width
, text_area_height
;
755 window_box (w
, TEXT_AREA
, &text_area_x
, &text_area_y
, &text_area_width
,
757 if (w
->cursor
.x
>= text_area_x
+ text_area_width
)
758 w
->cursor
.hpos
= w
->cursor
.x
= 0;
759 if (w
->cursor
.y
>= text_area_y
+ text_area_height
)
760 w
->cursor
.vpos
= w
->cursor
.y
= 0;
763 /* Sanitize window sizes. */
764 sanitize_window_sizes (Qt
);
765 sanitize_window_sizes (Qnil
);
767 adjust_frame_glyphs (f
);
769 SET_FRAME_GARBAGED (f
);
771 /* A frame was "resized" if one of its pixelsizes changed, even if its
772 X window wasn't resized at all. */
773 f
->resized_p
= (new_pixel_width
!= old_pixel_width
774 || new_pixel_height
!= old_pixel_height
);
778 #ifdef HAVE_WINDOW_SYSTEM
780 /* Adjust size of F's child frames. */
781 Lisp_Object frames
, frame1
;
783 FOR_EACH_FRAME (frames
, frame1
)
784 if (FRAME_PARENT_FRAME (XFRAME (frame1
)) == f
)
785 keep_ratio (XFRAME (frame1
), f
, old_pixel_width
, old_pixel_height
,
786 new_pixel_width
, new_pixel_height
);
791 /* Allocate basically initialized frame. */
793 static struct frame
*
794 allocate_frame (void)
796 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct frame
, face_cache
, PVEC_FRAME
);
800 make_frame (bool mini_p
)
804 struct window
*rw
, *mw UNINIT
;
805 Lisp_Object root_window
;
806 Lisp_Object mini_window
;
808 f
= allocate_frame ();
809 XSETFRAME (frame
, f
);
812 /* Initialize Lisp data. Note that allocate_frame initializes all
813 Lisp data to nil, so do it only for slots which should not be nil. */
814 fset_tool_bar_position (f
, Qtop
);
817 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
818 non-Lisp data, so do it only for slots which should not be zero.
819 To avoid subtle bugs and for the sake of readability, it's better to
820 initialize enum members explicitly even if their values are zero. */
821 f
->wants_modeline
= true;
824 f
->can_x_set_window_size
= false;
825 f
->after_make_frame
= false;
826 f
->inhibit_horizontal_resize
= false;
827 f
->inhibit_vertical_resize
= false;
828 f
->tool_bar_redisplayed
= false;
829 f
->tool_bar_resized
= false;
830 f
->column_width
= 1; /* !FRAME_WINDOW_P value. */
831 f
->line_height
= 1; /* !FRAME_WINDOW_P value. */
832 #ifdef HAVE_WINDOW_SYSTEM
833 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
834 f
->horizontal_scroll_bars
= false;
835 f
->want_fullscreen
= FULLSCREEN_NONE
;
836 f
->undecorated
= false;
837 f
->no_special_glyphs
= false;
839 f
->override_redirect
= false;
841 f
->skip_taskbar
= false;
842 f
->no_focus_on_map
= false;
843 f
->no_accept_focus
= false;
844 f
->z_group
= z_group_none
;
846 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
847 f
->last_tool_bar_item
= -1;
850 f
->ns_appearance
= ns_appearance_aqua
;
851 f
->ns_transparent_titlebar
= false;
855 root_window
= make_window ();
856 rw
= XWINDOW (root_window
);
859 mini_window
= make_window ();
860 mw
= XWINDOW (mini_window
);
861 wset_next (rw
, mini_window
);
862 wset_prev (mw
, root_window
);
864 wset_frame (mw
, frame
);
865 fset_minibuffer_window (f
, mini_window
);
866 store_frame_param (f
, Qminibuffer
, Qt
);
871 wset_next (rw
, Qnil
);
872 fset_minibuffer_window (f
, Qnil
);
875 wset_frame (rw
, frame
);
878 just so that there is "something there."
879 Correct size will be set up later with adjust_frame_size. */
881 SET_FRAME_COLS (f
, 10);
882 SET_FRAME_LINES (f
, 10);
883 SET_FRAME_WIDTH (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
));
884 SET_FRAME_HEIGHT (f
, FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
));
887 rw
->pixel_width
= rw
->total_cols
* FRAME_COLUMN_WIDTH (f
);
888 rw
->total_lines
= mini_p
? 9 : 10;
889 rw
->pixel_height
= rw
->total_lines
* FRAME_LINE_HEIGHT (f
);
893 mw
->top_line
= rw
->total_lines
;
894 mw
->pixel_top
= rw
->pixel_height
;
895 mw
->total_cols
= rw
->total_cols
;
896 mw
->pixel_width
= rw
->pixel_width
;
898 mw
->pixel_height
= FRAME_LINE_HEIGHT (f
);
901 /* Choose a buffer for the frame's root window. */
903 Lisp_Object buf
= Fcurrent_buffer ();
905 /* If current buffer is hidden, try to find another one. */
906 if (BUFFER_HIDDEN_P (XBUFFER (buf
)))
907 buf
= other_buffer_safely (buf
);
909 /* Use set_window_buffer, not Fset_window_buffer, and don't let
910 hooks be run by it. The reason is that the whole frame/window
911 arrangement is not yet fully initialized at this point. Windows
912 don't have the right size, glyph matrices aren't initialized
913 etc. Running Lisp functions at this point surely ends in a
915 set_window_buffer (root_window
, buf
, 0, 0);
916 fset_buffer_list (f
, list1 (buf
));
921 set_window_buffer (mini_window
,
922 (NILP (Vminibuffer_list
)
924 : Fcar (Vminibuffer_list
)),
926 /* No horizontal scroll bars in minibuffers. */
927 wset_horizontal_scroll_bar (mw
, Qnil
);
930 fset_root_window (f
, root_window
);
931 fset_selected_window (f
, root_window
);
932 /* Make sure this window seems more recently used than
933 a newly-created, never-selected window. */
934 XWINDOW (f
->selected_window
)->use_time
= ++window_select_count
;
939 #ifdef HAVE_WINDOW_SYSTEM
940 /* Make a frame using a separate minibuffer window on another frame.
941 MINI_WINDOW is the minibuffer window to use. nil means use the
942 default (the global minibuffer). */
945 make_frame_without_minibuffer (Lisp_Object mini_window
, KBOARD
*kb
,
950 if (!NILP (mini_window
))
951 CHECK_LIVE_WINDOW (mini_window
);
953 if (!NILP (mini_window
)
954 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window
)->frame
)) != kb
)
955 error ("Frame and minibuffer must be on the same terminal");
957 /* Make a frame containing just a root window. */
960 if (NILP (mini_window
))
962 /* Use default-minibuffer-frame if possible. */
963 if (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
964 || ! FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
))))
966 Lisp_Object frame_dummy
;
968 XSETFRAME (frame_dummy
, f
);
969 /* If there's no minibuffer frame to use, create one. */
970 kset_default_minibuffer_frame
971 (kb
, call1 (intern ("make-initial-minibuffer-frame"), display
));
975 = XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
))->minibuffer_window
;
978 fset_minibuffer_window (f
, mini_window
);
979 store_frame_param (f
, Qminibuffer
, mini_window
);
981 /* Make the chosen minibuffer window display the proper minibuffer,
982 unless it is already showing a minibuffer. */
983 if (NILP (Fmemq (XWINDOW (mini_window
)->contents
, Vminibuffer_list
)))
984 /* Use set_window_buffer instead of Fset_window_buffer (see
985 discussion of bug#11984, bug#12025, bug#12026). */
986 set_window_buffer (mini_window
,
987 (NILP (Vminibuffer_list
)
989 : Fcar (Vminibuffer_list
)), 0, 0);
993 /* Make a frame containing only a minibuffer window. */
996 make_minibuffer_frame (void)
998 /* First make a frame containing just a root window, no minibuffer. */
1000 register struct frame
*f
= make_frame (0);
1001 register Lisp_Object mini_window
;
1002 register Lisp_Object frame
;
1004 XSETFRAME (frame
, f
);
1009 f
->wants_modeline
= 0;
1011 /* Now label the root window as also being the minibuffer.
1012 Avoid infinite looping on the window chain by marking next pointer
1015 mini_window
= f
->root_window
;
1016 fset_minibuffer_window (f
, mini_window
);
1017 store_frame_param (f
, Qminibuffer
, Qonly
);
1018 XWINDOW (mini_window
)->mini
= 1;
1019 wset_next (XWINDOW (mini_window
), Qnil
);
1020 wset_prev (XWINDOW (mini_window
), Qnil
);
1021 wset_frame (XWINDOW (mini_window
), frame
);
1023 /* Put the proper buffer in that window. */
1025 /* Use set_window_buffer instead of Fset_window_buffer (see
1026 discussion of bug#11984, bug#12025, bug#12026). */
1027 set_window_buffer (mini_window
,
1028 (NILP (Vminibuffer_list
)
1029 ? get_minibuffer (0)
1030 : Fcar (Vminibuffer_list
)), 0, 0);
1033 #endif /* HAVE_WINDOW_SYSTEM */
1035 /* Construct a frame that refers to a terminal. */
1037 static printmax_t tty_frame_count
;
1040 make_initial_frame (void)
1043 struct terminal
*terminal
;
1046 eassert (initial_kboard
);
1048 /* The first call must initialize Vframe_list. */
1049 if (! (NILP (Vframe_list
) || CONSP (Vframe_list
)))
1052 terminal
= init_initial_terminal ();
1055 XSETFRAME (frame
, f
);
1057 Vframe_list
= Fcons (frame
, Vframe_list
);
1059 tty_frame_count
= 1;
1060 fset_name (f
, build_pure_c_string ("F1"));
1062 SET_FRAME_VISIBLE (f
, 1);
1064 f
->output_method
= terminal
->type
;
1065 f
->terminal
= terminal
;
1066 f
->terminal
->reference_count
++;
1067 f
->output_data
.nothing
= 0;
1069 FRAME_FOREGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_FG_COLOR
;
1070 FRAME_BACKGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_BG_COLOR
;
1072 #ifdef HAVE_WINDOW_SYSTEM
1073 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
1074 f
->horizontal_scroll_bars
= false;
1077 /* The default value of menu-bar-mode is t. */
1078 set_menu_bar_lines (f
, make_number (1), Qnil
);
1080 /* Allocate glyph matrices. */
1081 adjust_frame_glyphs (f
);
1083 if (!noninteractive
)
1084 init_frame_faces (f
);
1086 last_nonminibuf_frame
= f
;
1088 f
->can_x_set_window_size
= true;
1089 f
->after_make_frame
= true;
1095 static struct frame
*
1096 make_terminal_frame (struct terminal
*terminal
)
1098 register struct frame
*f
;
1100 char name
[sizeof "F" + INT_STRLEN_BOUND (printmax_t
)];
1102 if (!terminal
->name
)
1103 error ("Terminal is not live, can't create new frames on it");
1107 XSETFRAME (frame
, f
);
1108 Vframe_list
= Fcons (frame
, Vframe_list
);
1110 fset_name (f
, make_formatted_string (name
, "F%"pMd
, ++tty_frame_count
));
1112 SET_FRAME_VISIBLE (f
, 1);
1114 f
->terminal
= terminal
;
1115 f
->terminal
->reference_count
++;
1117 f
->output_data
.tty
->display_info
= &the_only_display_info
;
1118 if (!inhibit_window_system
1119 && (!FRAMEP (selected_frame
) || !FRAME_LIVE_P (XFRAME (selected_frame
))
1120 || XFRAME (selected_frame
)->output_method
== output_msdos_raw
))
1121 f
->output_method
= output_msdos_raw
;
1123 f
->output_method
= output_termcap
;
1124 #else /* not MSDOS */
1125 f
->output_method
= output_termcap
;
1126 create_tty_output (f
);
1127 FRAME_FOREGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_FG_COLOR
;
1128 FRAME_BACKGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_BG_COLOR
;
1129 #endif /* not MSDOS */
1131 #ifdef HAVE_WINDOW_SYSTEM
1132 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
1133 f
->horizontal_scroll_bars
= false;
1136 FRAME_MENU_BAR_LINES (f
) = NILP (Vmenu_bar_mode
) ? 0 : 1;
1137 FRAME_LINES (f
) = FRAME_LINES (f
) - FRAME_MENU_BAR_LINES (f
);
1138 FRAME_MENU_BAR_HEIGHT (f
) = FRAME_MENU_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
);
1139 FRAME_TEXT_HEIGHT (f
) = FRAME_TEXT_HEIGHT (f
) - FRAME_MENU_BAR_HEIGHT (f
);
1141 /* Set the top frame to the newly created frame. */
1142 if (FRAMEP (FRAME_TTY (f
)->top_frame
)
1143 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f
)->top_frame
)))
1144 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f
)->top_frame
), 2); /* obscured */
1146 FRAME_TTY (f
)->top_frame
= frame
;
1148 if (!noninteractive
)
1149 init_frame_faces (f
);
1154 /* Get a suitable value for frame parameter PARAMETER for a newly
1155 created frame, based on (1) the user-supplied frame parameter
1156 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
1159 get_future_frame_param (Lisp_Object parameter
,
1160 Lisp_Object supplied_parms
,
1161 char *current_value
)
1165 result
= Fassq (parameter
, supplied_parms
);
1167 result
= Fassq (parameter
, XFRAME (selected_frame
)->param_alist
);
1168 if (NILP (result
) && current_value
!= NULL
)
1169 result
= build_string (current_value
);
1170 if (!NILP (result
) && !STRINGP (result
))
1171 result
= XCDR (result
);
1172 if (NILP (result
) || !STRINGP (result
))
1178 DEFUN ("make-terminal-frame", Fmake_terminal_frame
, Smake_terminal_frame
,
1180 doc
: /* Create an additional terminal frame, possibly on another terminal.
1181 This function takes one argument, an alist specifying frame parameters.
1183 You can create multiple frames on a single text terminal, but only one
1184 of them (the selected terminal frame) is actually displayed.
1186 In practice, generally you don't need to specify any parameters,
1187 except when you want to create a new frame on another terminal.
1188 In that case, the `tty' parameter specifies the device file to open,
1189 and the `tty-type' parameter specifies the terminal type. Example:
1191 (make-terminal-frame \\='((tty . "/dev/pts/5") (tty-type . "xterm")))
1193 Note that changing the size of one terminal frame automatically
1194 affects all frames on the same terminal device. */)
1198 struct terminal
*t
= NULL
;
1199 Lisp_Object frame
, tem
;
1200 struct frame
*sf
= SELECTED_FRAME ();
1203 if (sf
->output_method
!= output_msdos_raw
1204 && sf
->output_method
!= output_termcap
)
1206 #else /* not MSDOS */
1208 #ifdef WINDOWSNT /* This should work now! */
1209 if (sf
->output_method
!= output_termcap
)
1210 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
1212 #endif /* not MSDOS */
1215 Lisp_Object terminal
;
1217 terminal
= Fassq (Qterminal
, parms
);
1218 if (CONSP (terminal
))
1220 terminal
= XCDR (terminal
);
1221 t
= decode_live_terminal (terminal
);
1224 if (t
&& t
!= the_only_display_info
.terminal
)
1225 /* msdos.c assumes a single tty_display_info object. */
1226 error ("Multiple terminals are not supported on this platform");
1228 t
= the_only_display_info
.terminal
;
1234 char *name
= 0, *type
= 0;
1235 Lisp_Object tty
, tty_type
;
1238 tty
= get_future_frame_param
1239 (Qtty
, parms
, (FRAME_TERMCAP_P (XFRAME (selected_frame
))
1240 ? FRAME_TTY (XFRAME (selected_frame
))->name
1243 SAFE_ALLOCA_STRING (name
, tty
);
1245 tty_type
= get_future_frame_param
1246 (Qtty_type
, parms
, (FRAME_TERMCAP_P (XFRAME (selected_frame
))
1247 ? FRAME_TTY (XFRAME (selected_frame
))->type
1249 if (!NILP (tty_type
))
1250 SAFE_ALLOCA_STRING (type
, tty_type
);
1252 t
= init_tty (name
, type
, 0); /* Errors are not fatal. */
1256 f
= make_terminal_frame (t
);
1260 get_tty_size (fileno (FRAME_TTY (f
)->input
), &width
, &height
);
1261 adjust_frame_size (f
, width
, height
- FRAME_MENU_BAR_LINES (f
),
1262 5, 0, Qterminal_frame
);
1265 adjust_frame_glyphs (f
);
1266 calculate_costs (f
);
1267 XSETFRAME (frame
, f
);
1269 store_in_alist (&parms
, Qtty_type
, build_string (t
->display_info
.tty
->type
));
1270 store_in_alist (&parms
, Qtty
,
1271 (t
->display_info
.tty
->name
1272 ? build_string (t
->display_info
.tty
->name
)
1274 /* On terminal frames the `minibuffer' frame parameter is always
1275 virtually t. Avoid that a different value in parms causes
1276 complaints, see Bug#24758. */
1277 store_in_alist (&parms
, Qminibuffer
, Qt
);
1278 Fmodify_frame_parameters (frame
, parms
);
1280 /* Make the frame face alist be frame-specific, so that each
1281 frame could change its face definitions independently. */
1282 fset_face_alist (f
, Fcopy_alist (sf
->face_alist
));
1283 /* Simple Fcopy_alist isn't enough, because we need the contents of
1284 the vectors which are the CDRs of associations in face_alist to
1285 be copied as well. */
1286 for (tem
= f
->face_alist
; CONSP (tem
); tem
= XCDR (tem
))
1287 XSETCDR (XCAR (tem
), Fcopy_sequence (XCDR (XCAR (tem
))));
1289 f
->can_x_set_window_size
= true;
1290 f
->after_make_frame
= true;
1296 /* Perform the switch to frame FRAME.
1298 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
1301 If TRACK is non-zero and the frame that currently has the focus
1302 redirects its focus to the selected frame, redirect that focused
1303 frame's focus to FRAME instead.
1305 FOR_DELETION non-zero means that the selected frame is being
1306 deleted, which includes the possibility that the frame's terminal
1309 The value of NORECORD is passed as argument to Fselect_window. */
1312 do_switch_frame (Lisp_Object frame
, int track
, int for_deletion
, Lisp_Object norecord
)
1314 struct frame
*sf
= SELECTED_FRAME (), *f
;
1316 /* If FRAME is a switch-frame event, extract the frame we should
1319 && EQ (XCAR (frame
), Qswitch_frame
)
1320 && CONSP (XCDR (frame
)))
1321 frame
= XCAR (XCDR (frame
));
1323 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
1324 a switch-frame event to arrive after a frame is no longer live,
1325 especially when deleting the initial frame during startup. */
1326 CHECK_FRAME (frame
);
1328 if (!FRAME_LIVE_P (f
))
1333 /* If a frame's focus has been redirected toward the currently
1334 selected frame, we should change the redirection to point to the
1335 newly selected frame. This means that if the focus is redirected
1336 from a minibufferless frame to a surrogate minibuffer frame, we
1337 can use `other-window' to switch between all the frames using
1338 that minibuffer frame, and the focus redirection will follow us
1341 /* This is too greedy; it causes inappropriate focus redirection
1342 that's hard to get rid of. */
1347 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1351 if (!FRAMEP (XCAR (tail
)))
1354 focus
= FRAME_FOCUS_FRAME (XFRAME (XCAR (tail
)));
1356 if (FRAMEP (focus
) && XFRAME (focus
) == SELECTED_FRAME ())
1357 Fredirect_frame_focus (XCAR (tail
), frame
);
1361 /* Instead, apply it only to the frame we're pointing to. */
1362 #ifdef HAVE_WINDOW_SYSTEM
1363 if (track
&& FRAME_WINDOW_P (f
))
1365 Lisp_Object focus
, xfocus
;
1367 xfocus
= x_get_focus_frame (f
);
1368 if (FRAMEP (xfocus
))
1370 focus
= FRAME_FOCUS_FRAME (XFRAME (xfocus
));
1371 if ((FRAMEP (focus
) && XFRAME (focus
) == SELECTED_FRAME ())
1372 /* Redirect frame focus also when FRAME has its minibuffer
1373 window on the selected frame (see Bug#24500). */
1375 && EQ (FRAME_MINIBUF_WINDOW (f
), sf
->selected_window
)))
1376 Fredirect_frame_focus (xfocus
, frame
);
1379 #endif /* HAVE_X_WINDOWS */
1382 if (!for_deletion
&& FRAME_HAS_MINIBUF_P (sf
))
1383 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf
)), 1);
1385 if (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
1387 struct tty_display_info
*tty
= FRAME_TTY (f
);
1388 Lisp_Object top_frame
= tty
->top_frame
;
1390 /* Don't mark the frame garbaged and/or obscured if we are
1391 switching to the frame that is already the top frame of that
1393 if (!EQ (frame
, top_frame
))
1395 if (FRAMEP (top_frame
))
1396 /* Mark previously displayed frame as now obscured. */
1397 SET_FRAME_VISIBLE (XFRAME (top_frame
), 2);
1398 SET_FRAME_VISIBLE (f
, 1);
1399 /* If the new TTY frame changed dimensions, we need to
1400 resync term.c's idea of the frame size with the new
1402 if (FRAME_COLS (f
) != FrameCols (tty
))
1403 FrameCols (tty
) = FRAME_COLS (f
);
1404 if (FRAME_TOTAL_LINES (f
) != FrameRows (tty
))
1405 FrameRows (tty
) = FRAME_TOTAL_LINES (f
);
1407 tty
->top_frame
= frame
;
1410 selected_frame
= frame
;
1411 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame
)))
1412 last_nonminibuf_frame
= XFRAME (selected_frame
);
1414 Fselect_window (f
->selected_window
, norecord
);
1416 /* We want to make sure that the next event generates a frame-switch
1417 event to the appropriate frame. This seems kludgy to me, but
1418 before you take it out, make sure that evaluating something like
1419 (select-window (frame-root-window (make-frame))) doesn't end up
1420 with your typing being interpreted in the new frame instead of
1421 the one you're actually typing in. */
1422 #ifdef HAVE_WINDOW_SYSTEM
1423 if (!frame_ancestor_p (f
, sf
))
1425 internal_last_event_frame
= Qnil
;
1430 DEFUN ("select-frame", Fselect_frame
, Sselect_frame
, 1, 2, "e",
1431 doc
: /* Select FRAME.
1432 Subsequent editing commands apply to its selected window.
1433 Optional argument NORECORD means to neither change the order of
1434 recently selected windows nor the buffer list.
1436 The selection of FRAME lasts until the next time the user does
1437 something to select a different frame, or until the next time
1438 this function is called. If you are using a window system, the
1439 previously selected frame may be restored as the selected frame
1440 when returning to the command loop, because it still may have
1441 the window system's input focus. On a text terminal, the next
1442 redisplay will display FRAME.
1444 This function returns FRAME, or nil if FRAME has been deleted. */)
1445 (Lisp_Object frame
, Lisp_Object norecord
)
1447 return do_switch_frame (frame
, 1, 0, norecord
);
1450 DEFUN ("handle-switch-frame", Fhandle_switch_frame
, Shandle_switch_frame
, 1, 1, "^e",
1451 doc
: /* Handle a switch-frame event EVENT.
1452 Switch-frame events are usually bound to this function.
1453 A switch-frame event is an event Emacs sends itself to
1454 indicate that input is arriving in a new frame. It does not
1455 necessarily represent user-visible input focus. */)
1458 /* Preserve prefix arg that the command loop just cleared. */
1459 kset_prefix_arg (current_kboard
, Vcurrent_prefix_arg
);
1460 run_hook (Qmouse_leave_buffer_hook
);
1461 return do_switch_frame (event
, 0, 0, Qnil
);
1464 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
1465 doc
: /* Return the frame that is now selected. */)
1468 return selected_frame
;
1471 DEFUN ("frame-list", Fframe_list
, Sframe_list
,
1473 doc
: /* Return a list of all live frames.
1474 The return value does not include any tooltip frame. */)
1477 #ifdef HAVE_WINDOW_SYSTEM
1478 Lisp_Object list
= Qnil
, tail
, frame
;
1480 FOR_EACH_FRAME (tail
, frame
)
1481 if (!FRAME_TOOLTIP_P (XFRAME (frame
)))
1482 list
= Fcons (frame
, list
);
1483 /* Reverse list for consistency with the !HAVE_WINDOW_SYSTEM case. */
1484 return Fnreverse (list
);
1485 #else /* !HAVE_WINDOW_SYSTEM */
1486 return Fcopy_sequence (Vframe_list
);
1487 #endif /* HAVE_WINDOW_SYSTEM */
1490 DEFUN ("frame-parent", Fframe_parent
, Sframe_parent
,
1492 doc
: /* Return the parent frame of FRAME.
1493 The parent frame of FRAME is the Emacs frame whose window-system window
1494 is the parent window of FRAME's window-system window. When such a frame
1495 exists, FRAME is considered a child frame of that frame.
1497 Return nil if FRAME has no parent frame. This means that FRAME's
1498 window-system window is either a "top-level" window (a window whose
1499 parent window is the window-system's root window) or an embedded window
1500 \(a window whose parent window is owned by some other application). */)
1503 struct frame
*f
= decode_live_frame (frame
);
1504 struct frame
*p
= FRAME_PARENT_FRAME (f
);
1507 /* Can't return f->parent_frame directly since it might not be defined
1508 for this platform. */
1511 XSETFRAME (parent
, p
);
1519 #ifdef HAVE_WINDOW_SYSTEM
1521 frame_ancestor_p (struct frame
*af
, struct frame
*df
)
1523 struct frame
*pf
= FRAME_PARENT_FRAME (df
);
1530 pf
= FRAME_PARENT_FRAME (pf
);
1537 DEFUN ("frame-ancestor-p", Fframe_ancestor_p
, Sframe_ancestor_p
,
1539 doc
: /* Return non-nil if ANCESTOR is an ancestor of DESCENDANT.
1540 ANCESTOR is an ancestor of DESCENDANT when it is either DESCENDANT's
1541 parent frame or it is an ancestor of DESCENDANT's parent frame. Both,
1542 ANCESTOR and DESCENDANT must be live frames and default to the selected
1544 (Lisp_Object ancestor
, Lisp_Object descendant
)
1546 #ifdef HAVE_WINDOW_SYSTEM
1547 struct frame
*af
= decode_live_frame (ancestor
);
1548 struct frame
*df
= decode_live_frame (descendant
);
1550 return frame_ancestor_p (af
, df
) ? Qt
: Qnil
;
1556 /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1557 same tty (for tty frames) or among frames which uses FRAME's keyboard.
1558 If MINIBUF is nil, do not consider minibuffer-only candidate.
1559 If MINIBUF is `visible', do not consider an invisible candidate.
1560 If MINIBUF is a window, consider only its own frame and candidate now
1561 using that window as the minibuffer.
1562 If MINIBUF is 0, consider candidate if it is visible or iconified.
1563 Otherwise consider any candidate and return nil if CANDIDATE is not
1567 candidate_frame (Lisp_Object candidate
, Lisp_Object frame
, Lisp_Object minibuf
)
1569 struct frame
*c
= XFRAME (candidate
), *f
= XFRAME (frame
);
1571 if ((!FRAME_TERMCAP_P (c
) && !FRAME_TERMCAP_P (f
)
1572 && FRAME_KBOARD (c
) == FRAME_KBOARD (f
))
1573 || (FRAME_TERMCAP_P (c
) && FRAME_TERMCAP_P (f
)
1574 && FRAME_TTY (c
) == FRAME_TTY (f
)))
1576 if (!NILP (get_frame_param (c
, Qno_other_frame
)))
1578 else if (NILP (minibuf
))
1580 if (!FRAME_MINIBUF_ONLY_P (c
))
1583 else if (EQ (minibuf
, Qvisible
))
1585 if (FRAME_VISIBLE_P (c
))
1588 else if (WINDOWP (minibuf
))
1590 if (EQ (FRAME_MINIBUF_WINDOW (c
), minibuf
)
1591 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)), candidate
)
1592 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
1593 FRAME_FOCUS_FRAME (c
)))
1596 else if (INTEGERP (minibuf
) && XINT (minibuf
) == 0)
1598 if (FRAME_VISIBLE_P (c
) || FRAME_ICONIFIED_P (c
))
1607 /* Return the next frame in the frame list after FRAME. */
1610 next_frame (Lisp_Object frame
, Lisp_Object minibuf
)
1612 Lisp_Object f
, tail
;
1615 eassume (CONSP (Vframe_list
));
1618 FOR_EACH_FRAME (tail
, f
)
1622 f
= candidate_frame (f
, frame
, minibuf
);
1632 /* Return the previous frame in the frame list before FRAME. */
1635 prev_frame (Lisp_Object frame
, Lisp_Object minibuf
)
1637 Lisp_Object f
, tail
, prev
= Qnil
;
1639 eassume (CONSP (Vframe_list
));
1641 FOR_EACH_FRAME (tail
, f
)
1643 if (EQ (frame
, f
) && !NILP (prev
))
1645 f
= candidate_frame (f
, frame
, minibuf
);
1650 /* We've scanned the entire list. */
1652 /* We went through the whole frame list without finding a single
1653 acceptable frame. Return the original frame. */
1656 /* There were no acceptable frames in the list before FRAME; otherwise,
1657 we would have returned directly from the loop. Since PREV is the last
1658 acceptable frame in the list, return it. */
1663 DEFUN ("next-frame", Fnext_frame
, Snext_frame
, 0, 2, 0,
1664 doc
: /* Return the next frame in the frame list after FRAME.
1665 It considers only frames on the same terminal as FRAME.
1666 By default, skip minibuffer-only frames.
1667 If omitted, FRAME defaults to the selected frame.
1668 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1669 If MINIFRAME is a window, include only its own frame
1670 and any frame now using that window as the minibuffer.
1671 If MINIFRAME is `visible', include all visible frames.
1672 If MINIFRAME is 0, include all visible and iconified frames.
1673 Otherwise, include all frames. */)
1674 (Lisp_Object frame
, Lisp_Object miniframe
)
1677 frame
= selected_frame
;
1678 CHECK_LIVE_FRAME (frame
);
1679 return next_frame (frame
, miniframe
);
1682 DEFUN ("previous-frame", Fprevious_frame
, Sprevious_frame
, 0, 2, 0,
1683 doc
: /* Return the previous frame in the frame list before FRAME.
1684 It considers only frames on the same terminal as FRAME.
1685 By default, skip minibuffer-only frames.
1686 If omitted, FRAME defaults to the selected frame.
1687 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1688 If MINIFRAME is a window, include only its own frame
1689 and any frame now using that window as the minibuffer.
1690 If MINIFRAME is `visible', include all visible frames.
1691 If MINIFRAME is 0, include all visible and iconified frames.
1692 Otherwise, include all frames. */)
1693 (Lisp_Object frame
, Lisp_Object miniframe
)
1696 frame
= selected_frame
;
1697 CHECK_LIVE_FRAME (frame
);
1698 return prev_frame (frame
, miniframe
);
1701 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame
,
1702 Slast_nonminibuf_frame
, 0, 0, 0,
1703 doc
: /* Return last non-minibuffer frame selected. */)
1706 Lisp_Object frame
= Qnil
;
1708 if (last_nonminibuf_frame
)
1709 XSETFRAME (frame
, last_nonminibuf_frame
);
1717 * Return true if there exists at least one visible or iconified frame
1718 * but F. Tooltip frames do not qualify as candidates. Return false
1719 * if no such frame exists.
1721 * INVISIBLE true means we are called from make_frame_invisible where
1722 * such a frame must be visible or iconified. INVISIBLE nil means we
1723 * are called from delete_frame. In that case FORCE true means that the
1724 * visibility status of such a frame can be ignored.
1726 * If F is the terminal frame and we are using X, return true if at
1727 * least one X frame exists.
1730 other_frames (struct frame
*f
, bool invisible
, bool force
)
1732 Lisp_Object frames
, frame
, frame1
;
1733 Lisp_Object minibuffer_window
= FRAME_MINIBUF_WINDOW (f
);
1735 XSETFRAME (frame
, f
);
1736 if (WINDOWP (minibuffer_window
)
1737 && !EQ (frame
, WINDOW_FRAME (XWINDOW (minibuffer_window
))))
1738 minibuffer_window
= Qnil
;
1740 FOR_EACH_FRAME (frames
, frame1
)
1742 struct frame
*f1
= XFRAME (frame1
);
1746 /* Verify that we can still talk to the frame's X window, and
1747 note any recent change in visibility. */
1748 #ifdef HAVE_X_WINDOWS
1749 if (FRAME_WINDOW_P (f1
))
1752 if (!FRAME_TOOLTIP_P (f1
)
1753 /* Tooltips and child frames count neither for
1754 invisibility nor for deletions. */
1755 && !FRAME_PARENT_FRAME (f1
)
1756 /* Frames with a non-nil `delete-before' parameter don't
1757 count for deletions. */
1758 && (invisible
|| NILP (get_frame_param (f1
, Qdelete_before
)))
1759 /* For invisibility and normal deletions, at least one
1760 visible or iconified frame must remain (Bug#26682). */
1761 && (FRAME_VISIBLE_P (f1
) || FRAME_ICONIFIED_P (f1
)
1764 /* Allow deleting the terminal frame when at
1765 least one X frame exists. */
1766 || (FRAME_WINDOW_P (f1
) && !FRAME_WINDOW_P (f
))))))
1774 /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1775 window. Preferably use the selected frame's minibuffer window
1776 instead. If the selected frame doesn't have one, get some other
1777 frame's minibuffer window. SELECT non-zero means select the new
1778 minibuffer window. */
1780 check_minibuf_window (Lisp_Object frame
, int select
)
1782 struct frame
*f
= decode_live_frame (frame
);
1784 XSETFRAME (frame
, f
);
1786 if (WINDOWP (minibuf_window
) && EQ (f
->minibuffer_window
, minibuf_window
))
1788 Lisp_Object frames
, this, window
= make_number (0);
1790 if (!EQ (frame
, selected_frame
)
1791 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame
)))
1792 window
= FRAME_MINIBUF_WINDOW (XFRAME (selected_frame
));
1794 FOR_EACH_FRAME (frames
, this)
1796 if (!EQ (this, frame
) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1798 window
= FRAME_MINIBUF_WINDOW (XFRAME (this));
1803 /* Don't abort if no window was found (Bug#15247). */
1804 if (WINDOWP (window
))
1806 /* Use set_window_buffer instead of Fset_window_buffer (see
1807 discussion of bug#11984, bug#12025, bug#12026). */
1808 set_window_buffer (window
, XWINDOW (minibuf_window
)->contents
, 0, 0);
1809 minibuf_window
= window
;
1811 /* SELECT non-zero usually means that FRAME's minibuffer
1812 window was selected; select the new one. */
1814 Fselect_window (minibuf_window
, Qnil
);
1823 * Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1824 * unconditionally. x_connection_closed and delete_terminal use this.
1825 * Any other value of FORCE implements the semantics described for
1828 delete_frame (Lisp_Object frame
, Lisp_Object force
)
1830 struct frame
*f
= decode_any_frame (frame
);
1833 Lisp_Object frames
, frame1
;
1834 int minibuffer_selected
, is_tooltip_frame
;
1835 bool nochild
= !FRAME_PARENT_FRAME (f
);
1837 if (!FRAME_LIVE_P (f
))
1839 else if (!EQ (force
, Qnoelisp
) && !other_frames (f
, false, !NILP (force
)))
1842 error ("Attempt to delete the sole visible or iconified frame");
1844 error ("Attempt to delete the only frame");
1847 XSETFRAME (frame
, f
);
1849 /* Softly delete all frames with this frame as their parent frame or
1850 as their `delete-before' frame parameter value. */
1851 FOR_EACH_FRAME (frames
, frame1
)
1852 if (FRAME_PARENT_FRAME (XFRAME (frame1
)) == f
1853 /* Process `delete-before' parameter iff FRAME is not a child
1854 frame. This avoids that we enter an infinite chain of mixed
1857 && EQ (get_frame_param (XFRAME (frame1
), Qdelete_before
), frame
)))
1858 delete_frame (frame1
, Qnil
);
1860 /* Does this frame have a minibuffer, and is it the surrogate
1861 minibuffer for any other frame? */
1862 if (FRAME_HAS_MINIBUF_P (f
))
1864 FOR_EACH_FRAME (frames
, frame1
)
1868 if (EQ (frame1
, frame
))
1871 fminiw
= FRAME_MINIBUF_WINDOW (XFRAME (frame1
));
1873 if (WINDOWP (fminiw
) && EQ (frame
, WINDOW_FRAME (XWINDOW (fminiw
))))
1875 /* If we MUST delete this frame, delete the other first.
1876 But do this only if FORCE equals `noelisp'. */
1877 if (EQ (force
, Qnoelisp
))
1878 delete_frame (frame1
, Qnoelisp
);
1880 error ("Attempt to delete a surrogate minibuffer frame");
1885 is_tooltip_frame
= FRAME_TOOLTIP_P (f
);
1887 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1888 frame is a tooltip. FORCE is set to `noelisp' when handling
1889 a disconnect from the terminal, so we don't dare call Lisp
1891 if (NILP (Vrun_hooks
) || is_tooltip_frame
)
1893 else if (EQ (force
, Qnoelisp
))
1895 = Fcons (list3 (Qrun_hook_with_args
, Qdelete_frame_functions
, frame
),
1899 #ifdef HAVE_X_WINDOWS
1900 /* Also, save clipboard to the clipboard manager. */
1901 x_clipboard_manager_save_frame (frame
);
1904 safe_call2 (Qrun_hook_with_args
, Qdelete_frame_functions
, frame
);
1907 /* delete_frame_functions may have deleted any frame, including this
1909 if (!FRAME_LIVE_P (f
))
1911 else if (!EQ (force
, Qnoelisp
) && !other_frames (f
, false, !NILP (force
)))
1914 error ("Attempt to delete the sole visible or iconified frame");
1916 error ("Attempt to delete the only frame");
1919 /* At this point, we are committed to deleting the frame.
1920 There is no more chance for errors to prevent it. */
1921 minibuffer_selected
= EQ (minibuf_window
, selected_window
);
1922 sf
= SELECTED_FRAME ();
1923 /* Don't let the frame remain selected. */
1927 Lisp_Object frame1 UNINIT
; /* This line works around GCC bug 85563. */
1928 eassume (CONSP (Vframe_list
));
1930 /* Look for another visible frame on the same terminal.
1931 Do not call next_frame here because it may loop forever.
1932 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1933 FOR_EACH_FRAME (tail
, frame1
)
1935 struct frame
*f1
= XFRAME (frame1
);
1937 if (!EQ (frame
, frame1
)
1938 && !FRAME_TOOLTIP_P (f1
)
1939 && FRAME_TERMINAL (f
) == FRAME_TERMINAL (f1
)
1940 && FRAME_VISIBLE_P (f1
))
1944 /* If there is none, find *some* other frame. */
1945 if (NILP (frame1
) || EQ (frame1
, frame
))
1947 FOR_EACH_FRAME (tail
, frame1
)
1949 struct frame
*f1
= XFRAME (frame1
);
1951 if (!EQ (frame
, frame1
)
1952 && FRAME_LIVE_P (f1
)
1953 && !FRAME_TOOLTIP_P (f1
))
1955 if (FRAME_TERMCAP_P (f1
) || FRAME_MSDOS_P (f1
))
1957 Lisp_Object top_frame
= FRAME_TTY (f1
)->top_frame
;
1959 if (!EQ (top_frame
, frame
))
1966 #ifdef NS_IMPL_COCOA
1968 /* Under NS, there is no system mechanism for choosing a new
1969 window to get focus -- it is left to application code.
1970 So the portion of THIS application interfacing with NS
1971 needs to know about it. We call Fraise_frame, but the
1972 purpose is really to transfer focus. */
1973 Fraise_frame (frame1
);
1976 do_switch_frame (frame1
, 0, 1, Qnil
);
1977 sf
= SELECTED_FRAME ();
1980 /* Don't allow minibuf_window to remain on a deleted frame. */
1981 check_minibuf_window (frame
, minibuffer_selected
);
1983 /* Don't let echo_area_window to remain on a deleted frame. */
1984 if (EQ (f
->minibuffer_window
, echo_area_window
))
1985 echo_area_window
= sf
->minibuffer_window
;
1987 /* Clear any X selections for this frame. */
1988 #ifdef HAVE_X_WINDOWS
1990 x_clear_frame_selections (f
);
1994 This function must be called before the window tree of the
1995 frame is deleted because windows contain dynamically allocated
1999 #ifdef HAVE_WINDOW_SYSTEM
2000 /* Give chance to each font driver to free a frame specific data. */
2001 font_update_drivers (f
, Qnil
);
2004 /* Mark all the windows that used to be on FRAME as deleted, and then
2005 remove the reference to them. */
2006 delete_all_child_windows (f
->root_window
);
2007 fset_root_window (f
, Qnil
);
2009 Vframe_list
= Fdelq (frame
, Vframe_list
);
2010 SET_FRAME_VISIBLE (f
, 0);
2012 /* Allow the vector of menu bar contents to be freed in the next
2013 garbage collection. The frame object itself may not be garbage
2014 collected until much later, because recent_keys and other data
2015 structures can still refer to it. */
2016 fset_menu_bar_vector (f
, Qnil
);
2018 /* If FRAME's buffer lists contains killed
2019 buffers, this helps GC to reclaim them. */
2020 fset_buffer_list (f
, Qnil
);
2021 fset_buried_buffer_list (f
, Qnil
);
2023 free_font_driver_list (f
);
2024 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
2027 xfree (f
->decode_mode_spec_buffer
);
2028 xfree (FRAME_INSERT_COST (f
));
2029 xfree (FRAME_DELETEN_COST (f
));
2030 xfree (FRAME_INSERTN_COST (f
));
2031 xfree (FRAME_DELETE_COST (f
));
2033 /* Since some events are handled at the interrupt level, we may get
2034 an event for f at any time; if we zero out the frame's terminal
2035 now, then we may trip up the event-handling code. Instead, we'll
2036 promise that the terminal of the frame must be valid until we
2037 have called the window-system-dependent frame destruction
2040 struct terminal
*terminal
;
2042 if (FRAME_TERMINAL (f
)->delete_frame_hook
)
2043 (*FRAME_TERMINAL (f
)->delete_frame_hook
) (f
);
2044 terminal
= FRAME_TERMINAL (f
);
2045 f
->output_data
.nothing
= 0;
2046 f
->terminal
= 0; /* Now the frame is dead. */
2049 /* If needed, delete the terminal that this frame was on.
2050 (This must be done after the frame is killed.) */
2051 terminal
->reference_count
--;
2052 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
2053 /* FIXME: Deleting the terminal crashes emacs because of a GTK
2055 https://lists.gnu.org/r/emacs-devel/2011-10/msg00363.html */
2057 /* Since a similar behavior was observed on the Lucid and Motif
2058 builds (see Bug#5802, Bug#21509, Bug#23499, Bug#27816), we now
2059 don't delete the terminal for these builds either. */
2060 if (terminal
->reference_count
== 0 && terminal
->type
== output_x_window
)
2061 terminal
->reference_count
= 1;
2062 #endif /* USE_X_TOOLKIT || USE_GTK */
2063 if (terminal
->reference_count
== 0)
2066 XSETTERMINAL (tmp
, terminal
);
2069 Fdelete_terminal (tmp
, NILP (force
) ? Qt
: force
);
2072 kb
= terminal
->kboard
;
2075 /* If we've deleted the last_nonminibuf_frame, then try to find
2077 if (f
== last_nonminibuf_frame
)
2079 last_nonminibuf_frame
= 0;
2081 FOR_EACH_FRAME (frames
, frame1
)
2083 struct frame
*f1
= XFRAME (frame1
);
2085 if (!FRAME_MINIBUF_ONLY_P (f1
))
2087 last_nonminibuf_frame
= f1
;
2093 /* If there's no other frame on the same kboard, get out of
2094 single-kboard state if we're in it for this kboard. */
2097 /* Some frame we found on the same kboard, or nil if there are none. */
2098 Lisp_Object frame_on_same_kboard
= Qnil
;
2100 FOR_EACH_FRAME (frames
, frame1
)
2101 if (kb
== FRAME_KBOARD (XFRAME (frame1
)))
2102 frame_on_same_kboard
= frame1
;
2104 if (NILP (frame_on_same_kboard
))
2105 not_single_kboard_state (kb
);
2109 /* If we've deleted this keyboard's default_minibuffer_frame, try to
2110 find another one. Prefer minibuffer-only frames, but also notice
2111 frames with other windows. */
2112 if (kb
!= NULL
&& EQ (frame
, KVAR (kb
, Vdefault_minibuffer_frame
)))
2114 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
2115 Lisp_Object frame_with_minibuf
= Qnil
;
2116 /* Some frame we found on the same kboard, or nil if there are none. */
2117 Lisp_Object frame_on_same_kboard
= Qnil
;
2119 FOR_EACH_FRAME (frames
, frame1
)
2121 struct frame
*f1
= XFRAME (frame1
);
2123 /* Consider only frames on the same kboard
2124 and only those with minibuffers. */
2125 if (kb
== FRAME_KBOARD (f1
)
2126 && FRAME_HAS_MINIBUF_P (f1
))
2128 frame_with_minibuf
= frame1
;
2129 if (FRAME_MINIBUF_ONLY_P (f1
))
2133 if (kb
== FRAME_KBOARD (f1
))
2134 frame_on_same_kboard
= frame1
;
2137 if (!NILP (frame_on_same_kboard
))
2139 /* We know that there must be some frame with a minibuffer out
2140 there. If this were not true, all of the frames present
2141 would have to be minibufferless, which implies that at some
2142 point their minibuffer frames must have been deleted, but
2143 that is prohibited at the top; you can't delete surrogate
2144 minibuffer frames. */
2145 if (NILP (frame_with_minibuf
))
2148 kset_default_minibuffer_frame (kb
, frame_with_minibuf
);
2151 /* No frames left on this kboard--say no minibuffer either. */
2152 kset_default_minibuffer_frame (kb
, Qnil
);
2155 /* Cause frame titles to update--necessary if we now have just one frame. */
2156 if (!is_tooltip_frame
)
2157 update_mode_lines
= 15;
2159 /* Now run the post-deletion hooks. */
2160 if (NILP (Vrun_hooks
) || is_tooltip_frame
)
2162 else if (EQ (force
, Qnoelisp
))
2164 = Fcons (list3 (Qrun_hook_with_args
, Qafter_delete_frame_functions
, frame
),
2167 safe_call2 (Qrun_hook_with_args
, Qafter_delete_frame_functions
, frame
);
2172 DEFUN ("delete-frame", Fdelete_frame
, Sdelete_frame
, 0, 2, "",
2173 doc
: /* Delete FRAME, permanently eliminating it from use.
2174 FRAME must be a live frame and defaults to the selected one.
2176 A frame may not be deleted if its minibuffer serves as surrogate
2177 minibuffer for another frame. Normally, you may not delete a frame if
2178 all other frames are invisible, but if the second optional argument
2179 FORCE is non-nil, you may do so.
2181 This function runs `delete-frame-functions' before actually
2182 deleting the frame, unless the frame is a tooltip.
2183 The functions are run with one argument, the frame to be deleted. */)
2184 (Lisp_Object frame
, Lisp_Object force
)
2186 return delete_frame (frame
, !NILP (force
) ? Qt
: Qnil
);
2189 #ifdef HAVE_WINDOW_SYSTEM
2191 * frame_internal_border_part:
2193 * Return part of internal border the coordinates X and Y relative to
2194 * frame F are on. Return nil if the coordinates are not on the
2195 * internal border of F.
2197 * Return one of INTERNAL_BORDER_LEFT_EDGE, INTERNAL_BORDER_TOP_EDGE,
2198 * INTERNAL_BORDER_RIGHT_EDGE or INTERNAL_BORDER_BOTTOM_EDGE when the
2199 * mouse cursor is on the corresponding border with an offset of at
2200 * least one canonical character height from that border's edges.
2202 * If no border part could be found this way, return one of
2203 * INTERNAL_BORDER_TOP_LEFT_CORNER, INTERNAL_BORDER_TOP_RIGHT_CORNER,
2204 * INTERNAL_BORDER_BOTTOM_LEFT_CORNER or
2205 * INTERNAL_BORDER_BOTTOM_RIGHT_CORNER to indicate that the mouse is in
2206 * one of the corresponding corners. This means that for very small
2207 * frames an `edge' return value is preferred.
2209 enum internal_border_part
2210 frame_internal_border_part (struct frame
*f
, int x
, int y
)
2212 int border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
2213 int offset
= FRAME_LINE_HEIGHT (f
);
2214 int width
= FRAME_PIXEL_WIDTH (f
);
2215 int height
= FRAME_PIXEL_HEIGHT (f
);
2216 enum internal_border_part part
= INTERNAL_BORDER_NONE
;
2218 if (offset
< border
)
2219 /* For very wide borders make offset at least as large as
2223 if (offset
< x
&& x
< width
- offset
)
2224 /* Top or bottom border. */
2226 if (0 <= y
&& y
<= border
)
2227 part
= INTERNAL_BORDER_TOP_EDGE
;
2228 else if (height
- border
<= y
&& y
<= height
)
2229 part
= INTERNAL_BORDER_BOTTOM_EDGE
;
2231 else if (offset
< y
&& y
< height
- offset
)
2232 /* Left or right border. */
2234 if (0 <= x
&& x
<= border
)
2235 part
= INTERNAL_BORDER_LEFT_EDGE
;
2236 else if (width
- border
<= x
&& x
<= width
)
2237 part
= INTERNAL_BORDER_RIGHT_EDGE
;
2242 int half_width
= width
/ 2;
2243 int half_height
= height
/ 2;
2245 if (0 <= x
&& x
<= border
)
2248 if (0 <= y
&& y
<= half_height
)
2249 part
= INTERNAL_BORDER_TOP_LEFT_CORNER
;
2250 else if (half_height
< y
&& y
<= height
)
2251 part
= INTERNAL_BORDER_BOTTOM_LEFT_CORNER
;
2253 else if (width
- border
<= x
&& x
<= width
)
2256 if (0 <= y
&& y
<= half_height
)
2257 part
= INTERNAL_BORDER_TOP_RIGHT_CORNER
;
2258 else if (half_height
< y
&& y
<= height
)
2259 part
= INTERNAL_BORDER_BOTTOM_RIGHT_CORNER
;
2261 else if (0 <= y
&& y
<= border
)
2264 if (0 <= x
&& x
<= half_width
)
2265 part
= INTERNAL_BORDER_TOP_LEFT_CORNER
;
2266 else if (half_width
< x
&& x
<= width
)
2267 part
= INTERNAL_BORDER_TOP_RIGHT_CORNER
;
2269 else if (height
- border
<= y
&& y
<= height
)
2271 /* A bottom edge. */
2272 if (0 <= x
&& x
<= half_width
)
2273 part
= INTERNAL_BORDER_BOTTOM_LEFT_CORNER
;
2274 else if (half_width
< x
&& x
<= width
)
2275 part
= INTERNAL_BORDER_BOTTOM_RIGHT_CORNER
;
2283 /* Return mouse position in character cell units. */
2285 DEFUN ("mouse-position", Fmouse_position
, Smouse_position
, 0, 0, 0,
2286 doc
: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
2287 The position is given in canonical character cells, where (0, 0) is the
2288 upper-left corner of the frame, X is the horizontal offset, and Y is the
2289 vertical offset, measured in units of the frame's default character size.
2290 If Emacs is running on a mouseless terminal or hasn't been programmed
2291 to read the mouse position, it returns the selected frame for FRAME
2292 and nil for X and Y.
2293 If `mouse-position-function' is non-nil, `mouse-position' calls it,
2294 passing the normal return value to that function as an argument,
2295 and returns whatever that function returns. */)
2299 Lisp_Object lispy_dummy
;
2300 Lisp_Object x
, y
, retval
;
2302 f
= SELECTED_FRAME ();
2305 /* It's okay for the hook to refrain from storing anything. */
2306 if (FRAME_TERMINAL (f
)->mouse_position_hook
)
2308 enum scroll_bar_part party_dummy
;
2310 (*FRAME_TERMINAL (f
)->mouse_position_hook
) (&f
, -1,
2311 &lispy_dummy
, &party_dummy
,
2320 pixel_to_glyph_coords (f
, col
, row
, &col
, &row
, NULL
, 1);
2324 XSETFRAME (lispy_dummy
, f
);
2325 retval
= Fcons (lispy_dummy
, Fcons (x
, y
));
2326 if (!NILP (Vmouse_position_function
))
2327 retval
= call1 (Vmouse_position_function
, retval
);
2331 DEFUN ("mouse-pixel-position", Fmouse_pixel_position
,
2332 Smouse_pixel_position
, 0, 0, 0,
2333 doc
: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
2334 The position is given in pixel units, where (0, 0) is the
2335 upper-left corner of the frame, X is the horizontal offset, and Y is
2336 the vertical offset.
2337 If Emacs is running on a mouseless terminal or hasn't been programmed
2338 to read the mouse position, it returns the selected frame for FRAME
2339 and nil for X and Y. */)
2343 Lisp_Object lispy_dummy
;
2344 Lisp_Object x
, y
, retval
;
2346 f
= SELECTED_FRAME ();
2349 /* It's okay for the hook to refrain from storing anything. */
2350 if (FRAME_TERMINAL (f
)->mouse_position_hook
)
2352 enum scroll_bar_part party_dummy
;
2354 (*FRAME_TERMINAL (f
)->mouse_position_hook
) (&f
, -1,
2355 &lispy_dummy
, &party_dummy
,
2360 XSETFRAME (lispy_dummy
, f
);
2361 retval
= Fcons (lispy_dummy
, Fcons (x
, y
));
2362 if (!NILP (Vmouse_position_function
))
2363 retval
= call1 (Vmouse_position_function
, retval
);
2367 #ifdef HAVE_WINDOW_SYSTEM
2369 /* On frame F, convert character coordinates X and Y to pixel
2370 coordinates *PIX_X and *PIX_Y. */
2373 frame_char_to_pixel_position (struct frame
*f
, int x
, int y
,
2374 int *pix_x
, int *pix_y
)
2376 *pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
2377 *pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
2381 if (*pix_x
> FRAME_PIXEL_WIDTH (f
))
2382 *pix_x
= FRAME_PIXEL_WIDTH (f
);
2386 if (*pix_y
> FRAME_PIXEL_HEIGHT (f
))
2387 *pix_y
= FRAME_PIXEL_HEIGHT (f
);
2390 /* On frame F, reposition mouse pointer to character coordinates X and Y. */
2393 frame_set_mouse_position (struct frame
*f
, int x
, int y
)
2397 frame_char_to_pixel_position (f
, x
, y
, &pix_x
, &pix_y
);
2398 frame_set_mouse_pixel_position (f
, pix_x
, pix_y
);
2401 #endif /* HAVE_WINDOW_SYSTEM */
2403 DEFUN ("set-mouse-position", Fset_mouse_position
, Sset_mouse_position
, 3, 3, 0,
2404 doc
: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
2405 Coordinates are relative to the frame, not a window,
2406 so the coordinates of the top left character in the frame
2407 may be nonzero due to left-hand scroll bars or the menu bar.
2409 The position is given in canonical character cells, where (0, 0) is
2410 the upper-left corner of the frame, X is the horizontal offset, and
2411 Y is the vertical offset, measured in units of the frame's default
2414 This function is a no-op for an X frame that is not visible.
2415 If you have just created a frame, you must wait for it to become visible
2416 before calling this function on it, like this.
2417 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
2418 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
2420 CHECK_LIVE_FRAME (frame
);
2421 CHECK_TYPE_RANGED_INTEGER (int, x
);
2422 CHECK_TYPE_RANGED_INTEGER (int, y
);
2424 /* I think this should be done with a hook. */
2425 #ifdef HAVE_WINDOW_SYSTEM
2426 if (FRAME_WINDOW_P (XFRAME (frame
)))
2427 /* Warping the mouse will cause enternotify and focus events. */
2428 frame_set_mouse_position (XFRAME (frame
), XINT (x
), XINT (y
));
2431 if (FRAME_MSDOS_P (XFRAME (frame
)))
2433 Fselect_frame (frame
, Qnil
);
2434 mouse_moveto (XINT (x
), XINT (y
));
2439 Fselect_frame (frame
, Qnil
);
2440 term_mouse_moveto (XINT (x
), XINT (y
));
2449 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position
,
2450 Sset_mouse_pixel_position
, 3, 3, 0,
2451 doc
: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
2452 The position is given in pixels, where (0, 0) is the upper-left corner
2453 of the frame, X is the horizontal offset, and Y is the vertical offset.
2455 Note, this is a no-op for an X frame that is not visible.
2456 If you have just created a frame, you must wait for it to become visible
2457 before calling this function on it, like this.
2458 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
2459 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
2461 CHECK_LIVE_FRAME (frame
);
2462 CHECK_TYPE_RANGED_INTEGER (int, x
);
2463 CHECK_TYPE_RANGED_INTEGER (int, y
);
2465 /* I think this should be done with a hook. */
2466 #ifdef HAVE_WINDOW_SYSTEM
2467 if (FRAME_WINDOW_P (XFRAME (frame
)))
2468 /* Warping the mouse will cause enternotify and focus events. */
2469 frame_set_mouse_pixel_position (XFRAME (frame
), XINT (x
), XINT (y
));
2472 if (FRAME_MSDOS_P (XFRAME (frame
)))
2474 Fselect_frame (frame
, Qnil
);
2475 mouse_moveto (XINT (x
), XINT (y
));
2480 Fselect_frame (frame
, Qnil
);
2481 term_mouse_moveto (XINT (x
), XINT (y
));
2490 static void make_frame_visible_1 (Lisp_Object
);
2492 DEFUN ("make-frame-visible", Fmake_frame_visible
, Smake_frame_visible
,
2494 doc
: /* Make the frame FRAME visible (assuming it is an X window).
2495 If omitted, FRAME defaults to the currently selected frame. */)
2498 struct frame
*f
= decode_live_frame (frame
);
2500 /* I think this should be done with a hook. */
2501 #ifdef HAVE_WINDOW_SYSTEM
2502 if (FRAME_WINDOW_P (f
))
2503 x_make_frame_visible (f
);
2506 make_frame_visible_1 (f
->root_window
);
2508 /* Make menu bar update for the Buffers and Frames menus. */
2509 /* windows_or_buffers_changed = 15; FIXME: Why? */
2511 XSETFRAME (frame
, f
);
2515 /* Update the display_time slot of the buffers shown in WINDOW
2516 and all its descendants. */
2519 make_frame_visible_1 (Lisp_Object window
)
2523 for (; !NILP (window
); window
= w
->next
)
2525 w
= XWINDOW (window
);
2526 if (WINDOWP (w
->contents
))
2527 make_frame_visible_1 (w
->contents
);
2529 bset_display_time (XBUFFER (w
->contents
), Fcurrent_time ());
2533 DEFUN ("make-frame-invisible", Fmake_frame_invisible
, Smake_frame_invisible
,
2535 doc
: /* Make the frame FRAME invisible.
2536 If omitted, FRAME defaults to the currently selected frame.
2537 On graphical displays, invisible frames are not updated and are
2538 usually not displayed at all, even in a window system's \"taskbar\".
2540 Normally you may not make FRAME invisible if all other frames are invisible,
2541 but if the second optional argument FORCE is non-nil, you may do so.
2543 This function has no effect on text terminal frames. Such frames are
2544 always considered visible, whether or not they are currently being
2545 displayed in the terminal. */)
2546 (Lisp_Object frame
, Lisp_Object force
)
2548 struct frame
*f
= decode_live_frame (frame
);
2550 if (NILP (force
) && !other_frames (f
, true, false))
2551 error ("Attempt to make invisible the sole visible or iconified frame");
2553 /* Don't allow minibuf_window to remain on an invisible frame. */
2554 check_minibuf_window (frame
, EQ (minibuf_window
, selected_window
));
2556 /* I think this should be done with a hook. */
2557 #ifdef HAVE_WINDOW_SYSTEM
2558 if (FRAME_WINDOW_P (f
))
2559 x_make_frame_invisible (f
);
2562 /* Make menu bar update for the Buffers and Frames menus. */
2563 windows_or_buffers_changed
= 16;
2568 DEFUN ("iconify-frame", Ficonify_frame
, Siconify_frame
,
2570 doc
: /* Make the frame FRAME into an icon.
2571 If omitted, FRAME defaults to the currently selected frame.
2573 If FRAME is a child frame, consult the variable `iconify-child-frame'
2574 for how to proceed. */)
2577 struct frame
*f
= decode_live_frame (frame
);
2578 #ifdef HAVE_WINDOW_SYSTEM
2579 Lisp_Object parent
= f
->parent_frame
;
2583 if (NILP (iconify_child_frame
))
2586 else if (EQ (iconify_child_frame
, Qiconify_top_level
))
2588 /* Iconify top level frame instead (the default). */
2589 Ficonify_frame (parent
);
2592 else if (EQ (iconify_child_frame
, Qmake_invisible
))
2594 /* Make frame invisible instead. */
2595 Fmake_frame_invisible (frame
, Qnil
);
2599 #endif /* HAVE_WINDOW_SYSTEM */
2601 /* Don't allow minibuf_window to remain on an iconified frame. */
2602 check_minibuf_window (frame
, EQ (minibuf_window
, selected_window
));
2604 /* I think this should be done with a hook. */
2605 if (FRAME_WINDOW_P (f
))
2607 #ifdef HAVE_WINDOW_SYSTEM
2608 x_iconify_frame (f
);
2615 DEFUN ("frame-visible-p", Fframe_visible_p
, Sframe_visible_p
,
2617 doc
: /* Return t if FRAME is \"visible\" (actually in use for display).
2618 Return the symbol `icon' if FRAME is iconified or \"minimized\".
2619 Return nil if FRAME was made invisible, via `make-frame-invisible'.
2620 On graphical displays, invisible frames are not updated and are
2621 usually not displayed at all, even in a window system's \"taskbar\".
2623 If FRAME is a text terminal frame, this always returns t.
2624 Such frames are always considered visible, whether or not they are
2625 currently being displayed on the terminal. */)
2628 CHECK_LIVE_FRAME (frame
);
2630 if (FRAME_VISIBLE_P (XFRAME (frame
)))
2632 if (FRAME_ICONIFIED_P (XFRAME (frame
)))
2637 DEFUN ("visible-frame-list", Fvisible_frame_list
, Svisible_frame_list
,
2639 doc
: /* Return a list of all frames now \"visible\" (being updated). */)
2642 Lisp_Object tail
, frame
, value
= Qnil
;
2644 FOR_EACH_FRAME (tail
, frame
)
2645 if (FRAME_VISIBLE_P (XFRAME (frame
)))
2646 value
= Fcons (frame
, value
);
2652 DEFUN ("raise-frame", Fraise_frame
, Sraise_frame
, 0, 1, "",
2653 doc
: /* Bring FRAME to the front, so it occludes any frames it overlaps.
2654 If FRAME is invisible or iconified, make it visible.
2655 If you don't specify a frame, the selected frame is used.
2656 If Emacs is displaying on an ordinary terminal or some other device which
2657 doesn't support multiple overlapping frames, this function selects FRAME. */)
2660 struct frame
*f
= decode_live_frame (frame
);
2662 XSETFRAME (frame
, f
);
2664 if (FRAME_TERMCAP_P (f
))
2665 /* On a text terminal select FRAME. */
2666 Fselect_frame (frame
, Qnil
);
2668 /* Do like the documentation says. */
2669 Fmake_frame_visible (frame
);
2671 if (FRAME_TERMINAL (f
)->frame_raise_lower_hook
)
2672 (*FRAME_TERMINAL (f
)->frame_raise_lower_hook
) (f
, 1);
2677 /* Should we have a corresponding function called Flower_Power? */
2678 DEFUN ("lower-frame", Flower_frame
, Slower_frame
, 0, 1, "",
2679 doc
: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2680 If you don't specify a frame, the selected frame is used.
2681 If Emacs is displaying on an ordinary terminal or some other device which
2682 doesn't support multiple overlapping frames, this function does nothing. */)
2685 struct frame
*f
= decode_live_frame (frame
);
2687 if (FRAME_TERMINAL (f
)->frame_raise_lower_hook
)
2688 (*FRAME_TERMINAL (f
)->frame_raise_lower_hook
) (f
, 0);
2694 DEFUN ("redirect-frame-focus", Fredirect_frame_focus
, Sredirect_frame_focus
,
2696 doc
: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2697 In other words, switch-frame events caused by events in FRAME will
2698 request a switch to FOCUS-FRAME, and `last-event-frame' will be
2699 FOCUS-FRAME after reading an event typed at FRAME.
2701 If FOCUS-FRAME is nil, any existing redirection is canceled, and the
2702 frame again receives its own keystrokes.
2704 Focus redirection is useful for temporarily redirecting keystrokes to
2705 a surrogate minibuffer frame when a frame doesn't have its own
2708 A frame's focus redirection can be changed by `select-frame'. If frame
2709 FOO is selected, and then a different frame BAR is selected, any
2710 frames redirecting their focus to FOO are shifted to redirect their
2711 focus to BAR. This allows focus redirection to work properly when the
2712 user switches from one frame to another using `select-window'.
2714 This means that a frame whose focus is redirected to itself is treated
2715 differently from a frame whose focus is redirected to nil; the former
2716 is affected by `select-frame', while the latter is not.
2718 The redirection lasts until `redirect-frame-focus' is called to change it. */)
2719 (Lisp_Object frame
, Lisp_Object focus_frame
)
2721 /* Note that we don't check for a live frame here. It's reasonable
2722 to redirect the focus of a frame you're about to delete, if you
2723 know what other frame should receive those keystrokes. */
2724 struct frame
*f
= decode_any_frame (frame
);
2726 if (! NILP (focus_frame
))
2727 CHECK_LIVE_FRAME (focus_frame
);
2729 fset_focus_frame (f
, focus_frame
);
2731 if (FRAME_TERMINAL (f
)->frame_rehighlight_hook
)
2732 (*FRAME_TERMINAL (f
)->frame_rehighlight_hook
) (f
);
2738 DEFUN ("frame-focus", Fframe_focus
, Sframe_focus
, 0, 1, 0,
2739 doc
: /* Return the frame to which FRAME's keystrokes are currently being sent.
2740 If FRAME is omitted or nil, the selected frame is used.
2741 Return nil if FRAME's focus is not redirected.
2742 See `redirect-frame-focus'. */)
2745 return FRAME_FOCUS_FRAME (decode_live_frame (frame
));
2748 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 2, 0,
2749 doc
: /* Set the input focus to FRAME.
2750 FRAME nil means use the selected frame. Optional argument NOACTIVATE
2751 means do not activate FRAME.
2753 If there is no window system support, this function does nothing. */)
2754 (Lisp_Object frame
, Lisp_Object noactivate
)
2756 #ifdef HAVE_WINDOW_SYSTEM
2757 x_focus_frame (decode_window_system_frame (frame
), !NILP (noactivate
));
2762 DEFUN ("frame-after-make-frame",
2763 Fframe_after_make_frame
,
2764 Sframe_after_make_frame
, 2, 2, 0,
2765 doc
: /* Mark FRAME as made.
2766 FRAME nil means use the selected frame. Second argument MADE non-nil
2767 means functions on `window-configuration-change-hook' are called
2768 whenever the window configuration of FRAME changes. MADE nil means
2769 these functions are not called.
2771 This function is currently called by `make-frame' only and should be
2772 otherwise used with utter care to avoid that running functions on
2773 `window-configuration-change-hook' is impeded forever. */)
2774 (Lisp_Object frame
, Lisp_Object made
)
2776 struct frame
*f
= decode_live_frame (frame
);
2777 f
->after_make_frame
= !NILP (made
);
2778 f
->inhibit_horizontal_resize
= false;
2779 f
->inhibit_vertical_resize
= false;
2784 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2787 frames_discard_buffer (Lisp_Object buffer
)
2789 Lisp_Object frame
, tail
;
2791 FOR_EACH_FRAME (tail
, frame
)
2794 (XFRAME (frame
), Fdelq (buffer
, XFRAME (frame
)->buffer_list
));
2795 fset_buried_buffer_list
2796 (XFRAME (frame
), Fdelq (buffer
, XFRAME (frame
)->buried_buffer_list
));
2800 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2801 If the alist already has an element for PROP, we change it. */
2804 store_in_alist (Lisp_Object
*alistptr
, Lisp_Object prop
, Lisp_Object val
)
2806 Lisp_Object tem
= Fassq (prop
, *alistptr
);
2808 *alistptr
= Fcons (Fcons (prop
, val
), *alistptr
);
2814 frame_name_fnn_p (char *str
, ptrdiff_t len
)
2816 if (len
> 1 && str
[0] == 'F' && '0' <= str
[1] && str
[1] <= '9')
2819 while ('0' <= *p
&& *p
<= '9')
2827 /* Set the name of the terminal frame. Also used by MSDOS frames.
2828 Modeled after x_set_name which is used for WINDOW frames. */
2831 set_term_frame_name (struct frame
*f
, Lisp_Object name
)
2833 f
->explicit_name
= ! NILP (name
);
2835 /* If NAME is nil, set the name to F<num>. */
2838 char namebuf
[sizeof "F" + INT_STRLEN_BOUND (printmax_t
)];
2840 /* Check for no change needed in this very common case
2841 before we do any consing. */
2842 if (frame_name_fnn_p (SSDATA (f
->name
), SBYTES (f
->name
)))
2845 name
= make_formatted_string (namebuf
, "F%"pMd
, ++tty_frame_count
);
2849 CHECK_STRING (name
);
2851 /* Don't change the name if it's already NAME. */
2852 if (! NILP (Fstring_equal (name
, f
->name
)))
2855 /* Don't allow the user to set the frame name to F<num>, so it
2856 doesn't clash with the names we generate for terminal frames. */
2857 if (frame_name_fnn_p (SSDATA (name
), SBYTES (name
)))
2858 error ("Frame names of the form F<num> are usurped by Emacs");
2861 fset_name (f
, name
);
2862 update_mode_lines
= 16;
2866 store_frame_param (struct frame
*f
, Lisp_Object prop
, Lisp_Object val
)
2868 register Lisp_Object old_alist_elt
;
2870 if (EQ (prop
, Qminibuffer
))
2874 if (!MINI_WINDOW_P (XWINDOW (val
)))
2875 error ("The `minibuffer' parameter does not specify a valid minibuffer window");
2876 else if (FRAME_MINIBUF_ONLY_P (f
))
2878 if (EQ (val
, FRAME_MINIBUF_WINDOW (f
)))
2881 error ("Can't change the minibuffer window of a minibuffer-only frame");
2883 else if (FRAME_HAS_MINIBUF_P (f
))
2885 if (EQ (val
, FRAME_MINIBUF_WINDOW (f
)))
2888 error ("Can't change the minibuffer window of a frame with its own minibuffer");
2891 /* Store the chosen minibuffer window. */
2892 fset_minibuffer_window (f
, val
);
2896 Lisp_Object old_val
= Fcdr (Fassq (Qminibuffer
, f
->param_alist
));
2898 if (!NILP (old_val
))
2900 if (WINDOWP (old_val
) && NILP (val
))
2901 /* Don't change the value for a minibuffer-less frame if
2902 only nil was specified as new value. */
2904 else if (!EQ (old_val
, val
))
2905 error ("Can't change the `minibuffer' parameter of this frame");
2910 /* Check each parent-frame and delete-before parameter for a
2911 circular dependency. Do not check between parameters, so you can
2912 still create circular dependencies with different properties, for
2913 example a chain of frames F1->F2->...Fn such that F1 is an ancestor
2914 frame of Fn and thus cannot be deleted before Fn and a second chain
2915 Fn->Fn-1->...F1 such that Fn cannot be deleted before F1. */
2916 else if (EQ (prop
, Qparent_frame
) || EQ (prop
, Qdelete_before
))
2918 Lisp_Object oldval
= Fcdr (Fassq (prop
, f
->param_alist
));
2920 if (!EQ (oldval
, val
) && !NILP (val
))
2923 Lisp_Object frame1
= val
;
2925 if (!FRAMEP (frame1
) || !FRAME_LIVE_P (XFRAME (frame1
)))
2926 error ("Invalid `%s' frame parameter",
2927 SSDATA (SYMBOL_NAME (prop
)));
2929 XSETFRAME (frame
, f
);
2931 while (FRAMEP (frame1
) && FRAME_LIVE_P (XFRAME (frame1
)))
2932 if (EQ (frame1
, frame
))
2933 error ("Circular specification of `%s' frame parameter",
2934 SSDATA (SYMBOL_NAME (prop
)));
2936 frame1
= get_frame_param (XFRAME (frame1
), prop
);
2940 /* The buffer-list parameters are stored in a special place and not
2941 in the alist. All buffers must be live. */
2942 else if (EQ (prop
, Qbuffer_list
))
2944 Lisp_Object list
= Qnil
;
2945 for (; CONSP (val
); val
= XCDR (val
))
2946 if (!NILP (Fbuffer_live_p (XCAR (val
))))
2947 list
= Fcons (XCAR (val
), list
);
2948 fset_buffer_list (f
, Fnreverse (list
));
2951 else if (EQ (prop
, Qburied_buffer_list
))
2953 Lisp_Object list
= Qnil
;
2954 for (; CONSP (val
); val
= XCDR (val
))
2955 if (!NILP (Fbuffer_live_p (XCAR (val
))))
2956 list
= Fcons (XCAR (val
), list
);
2957 fset_buried_buffer_list (f
, Fnreverse (list
));
2961 /* The tty color needed to be set before the frame's parameter
2962 alist was updated with the new value. This is not true any more,
2963 but we still do this test early on. */
2964 if (FRAME_TERMCAP_P (f
) && EQ (prop
, Qtty_color_mode
)
2965 && f
== FRAME_TTY (f
)->previous_frame
)
2966 /* Force redisplay of this tty. */
2967 FRAME_TTY (f
)->previous_frame
= NULL
;
2969 /* Update the frame parameter alist. */
2970 old_alist_elt
= Fassq (prop
, f
->param_alist
);
2971 if (NILP (old_alist_elt
))
2972 fset_param_alist (f
, Fcons (Fcons (prop
, val
), f
->param_alist
));
2974 Fsetcdr (old_alist_elt
, val
);
2976 /* Update some other special parameters in their special places
2977 in addition to the alist. */
2979 if (EQ (prop
, Qbuffer_predicate
))
2980 fset_buffer_predicate (f
, val
);
2982 if (! FRAME_WINDOW_P (f
))
2984 if (EQ (prop
, Qmenu_bar_lines
))
2985 set_menu_bar_lines (f
, val
, make_number (FRAME_MENU_BAR_LINES (f
)));
2986 else if (EQ (prop
, Qname
))
2987 set_term_frame_name (f
, val
);
2991 /* Return color matches UNSPEC on frame F or nil if UNSPEC
2992 is not an unspecified foreground or background color. */
2995 frame_unspecified_color (struct frame
*f
, Lisp_Object unspec
)
2997 return (!strncmp (SSDATA (unspec
), unspecified_bg
, SBYTES (unspec
))
2998 ? tty_color_name (f
, FRAME_BACKGROUND_PIXEL (f
))
2999 : (!strncmp (SSDATA (unspec
), unspecified_fg
, SBYTES (unspec
))
3000 ? tty_color_name (f
, FRAME_FOREGROUND_PIXEL (f
)) : Qnil
));
3003 DEFUN ("frame-parameters", Fframe_parameters
, Sframe_parameters
, 0, 1, 0,
3004 doc
: /* Return the parameters-alist of frame FRAME.
3005 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
3006 The meaningful PARMs depend on the kind of frame.
3007 If FRAME is omitted or nil, return information on the currently selected frame. */)
3011 struct frame
*f
= decode_any_frame (frame
);
3014 if (!FRAME_LIVE_P (f
))
3017 alist
= Fcopy_alist (f
->param_alist
);
3019 if (!FRAME_WINDOW_P (f
))
3023 /* If the frame's parameter alist says the colors are
3024 unspecified and reversed, take the frame's background pixel
3025 for foreground and vice versa. */
3026 elt
= Fassq (Qforeground_color
, alist
);
3027 if (CONSP (elt
) && STRINGP (XCDR (elt
)))
3029 elt
= frame_unspecified_color (f
, XCDR (elt
));
3031 store_in_alist (&alist
, Qforeground_color
, elt
);
3034 store_in_alist (&alist
, Qforeground_color
,
3035 tty_color_name (f
, FRAME_FOREGROUND_PIXEL (f
)));
3036 elt
= Fassq (Qbackground_color
, alist
);
3037 if (CONSP (elt
) && STRINGP (XCDR (elt
)))
3039 elt
= frame_unspecified_color (f
, XCDR (elt
));
3041 store_in_alist (&alist
, Qbackground_color
, elt
);
3044 store_in_alist (&alist
, Qbackground_color
,
3045 tty_color_name (f
, FRAME_BACKGROUND_PIXEL (f
)));
3046 store_in_alist (&alist
, Qfont
,
3047 build_string (FRAME_MSDOS_P (f
)
3049 : FRAME_W32_P (f
) ? "w32term"
3052 store_in_alist (&alist
, Qname
, f
->name
);
3053 height
= (f
->new_height
3055 ? (f
->new_height
/ FRAME_LINE_HEIGHT (f
))
3058 store_in_alist (&alist
, Qheight
, make_number (height
));
3059 width
= (f
->new_width
3061 ? (f
->new_width
/ FRAME_COLUMN_WIDTH (f
))
3064 store_in_alist (&alist
, Qwidth
, make_number (width
));
3065 store_in_alist (&alist
, Qmodeline
, (FRAME_WANTS_MODELINE_P (f
) ? Qt
: Qnil
));
3066 store_in_alist (&alist
, Qunsplittable
, (FRAME_NO_SPLIT_P (f
) ? Qt
: Qnil
));
3067 store_in_alist (&alist
, Qbuffer_list
, f
->buffer_list
);
3068 store_in_alist (&alist
, Qburied_buffer_list
, f
->buried_buffer_list
);
3070 /* I think this should be done with a hook. */
3071 #ifdef HAVE_WINDOW_SYSTEM
3072 if (FRAME_WINDOW_P (f
))
3073 x_report_frame_params (f
, &alist
);
3077 /* This ought to be correct in f->param_alist for an X frame. */
3079 XSETFASTINT (lines
, FRAME_MENU_BAR_LINES (f
));
3080 store_in_alist (&alist
, Qmenu_bar_lines
, lines
);
3087 DEFUN ("frame-parameter", Fframe_parameter
, Sframe_parameter
, 2, 2, 0,
3088 doc
: /* Return FRAME's value for parameter PARAMETER.
3089 If FRAME is nil, describe the currently selected frame. */)
3090 (Lisp_Object frame
, Lisp_Object parameter
)
3092 struct frame
*f
= decode_any_frame (frame
);
3093 Lisp_Object value
= Qnil
;
3095 CHECK_SYMBOL (parameter
);
3097 XSETFRAME (frame
, f
);
3099 if (FRAME_LIVE_P (f
))
3101 /* Avoid consing in frequent cases. */
3102 if (EQ (parameter
, Qname
))
3104 #ifdef HAVE_WINDOW_SYSTEM
3105 /* These are used by vertical motion commands. */
3106 else if (EQ (parameter
, Qvertical_scroll_bars
))
3107 value
= (f
->vertical_scroll_bar_type
== vertical_scroll_bar_none
3109 : (f
->vertical_scroll_bar_type
== vertical_scroll_bar_left
3111 else if (EQ (parameter
, Qhorizontal_scroll_bars
))
3112 value
= f
->horizontal_scroll_bars
? Qt
: Qnil
;
3113 else if (EQ (parameter
, Qline_spacing
) && f
->extra_line_spacing
== 0)
3114 /* If this is non-zero, we can't determine whether the user specified
3115 an integer or float value without looking through 'param_alist'. */
3116 value
= make_number (0);
3117 else if (EQ (parameter
, Qfont
) && FRAME_X_P (f
))
3118 value
= FRAME_FONT (f
)->props
[FONT_NAME_INDEX
];
3119 #endif /* HAVE_WINDOW_SYSTEM */
3120 #ifdef HAVE_X_WINDOWS
3121 else if (EQ (parameter
, Qdisplay
) && FRAME_X_P (f
))
3122 value
= XCAR (FRAME_DISPLAY_INFO (f
)->name_list_element
);
3123 #endif /* HAVE_X_WINDOWS */
3124 else if (EQ (parameter
, Qbackground_color
)
3125 || EQ (parameter
, Qforeground_color
))
3127 value
= Fassq (parameter
, f
->param_alist
);
3130 value
= XCDR (value
);
3131 /* Fframe_parameters puts the actual fg/bg color names,
3132 even if f->param_alist says otherwise. This is
3133 important when param_alist's notion of colors is
3134 "unspecified". We need to do the same here. */
3135 if (STRINGP (value
) && !FRAME_WINDOW_P (f
))
3137 Lisp_Object tem
= frame_unspecified_color (f
, value
);
3144 value
= Fcdr (Fassq (parameter
, Fframe_parameters (frame
)));
3146 else if (EQ (parameter
, Qdisplay_type
)
3147 || EQ (parameter
, Qbackground_mode
))
3148 value
= Fcdr (Fassq (parameter
, f
->param_alist
));
3150 /* FIXME: Avoid this code path at all (as well as code duplication)
3151 by sharing more code with Fframe_parameters. */
3152 value
= Fcdr (Fassq (parameter
, Fframe_parameters (frame
)));
3159 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters
,
3160 Smodify_frame_parameters
, 2, 2, 0,
3161 doc
: /* Modify FRAME according to new values of its parameters in ALIST.
3162 If FRAME is nil, it defaults to the selected frame.
3163 ALIST is an alist of parameters to change and their new values.
3164 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
3165 Which PARMs are meaningful depends on the kind of frame.
3166 The meaningful parameters are acted upon, i.e. the frame is changed
3167 according to their new values, and are also stored in the frame's
3168 parameter list so that `frame-parameters' will return them.
3169 PARMs that are not meaningful are still stored in the frame's parameter
3170 list, but are otherwise ignored. */)
3171 (Lisp_Object frame
, Lisp_Object alist
)
3173 struct frame
*f
= decode_live_frame (frame
);
3174 Lisp_Object prop
, val
;
3176 /* I think this should be done with a hook. */
3177 #ifdef HAVE_WINDOW_SYSTEM
3178 if (FRAME_WINDOW_P (f
))
3179 x_set_frame_parameters (f
, alist
);
3183 if (FRAME_MSDOS_P (f
))
3184 IT_set_frame_parameters (f
, alist
);
3189 EMACS_INT length
= XFASTINT (Flength (alist
));
3192 Lisp_Object
*values
;
3194 SAFE_ALLOCA_LISP (parms
, 2 * length
);
3195 values
= parms
+ length
;
3197 /* Extract parm names and values into those vectors. */
3199 for (i
= 0; CONSP (alist
); alist
= XCDR (alist
))
3204 parms
[i
] = Fcar (elt
);
3205 values
[i
] = Fcdr (elt
);
3209 /* Now process them in reverse of specified order. */
3214 store_frame_param (f
, prop
, val
);
3216 if (EQ (prop
, Qforeground_color
)
3217 || EQ (prop
, Qbackground_color
))
3218 update_face_from_frame_parameter (f
, prop
, val
);
3226 DEFUN ("frame-char-height", Fframe_char_height
, Sframe_char_height
,
3228 doc
: /* Height in pixels of a line in the font in frame FRAME.
3229 If FRAME is omitted or nil, the selected frame is used.
3230 For a terminal frame, the value is always 1. */)
3233 #ifdef HAVE_WINDOW_SYSTEM
3234 struct frame
*f
= decode_any_frame (frame
);
3236 if (FRAME_WINDOW_P (f
))
3237 return make_number (FRAME_LINE_HEIGHT (f
));
3240 return make_number (1);
3244 DEFUN ("frame-char-width", Fframe_char_width
, Sframe_char_width
,
3246 doc
: /* Width in pixels of characters in the font in frame FRAME.
3247 If FRAME is omitted or nil, the selected frame is used.
3248 On a graphical screen, the width is the standard width of the default font.
3249 For a terminal screen, the value is always 1. */)
3252 #ifdef HAVE_WINDOW_SYSTEM
3253 struct frame
*f
= decode_any_frame (frame
);
3255 if (FRAME_WINDOW_P (f
))
3256 return make_number (FRAME_COLUMN_WIDTH (f
));
3259 return make_number (1);
3262 DEFUN ("frame-native-width", Fframe_native_width
,
3263 Sframe_native_width
, 0, 1, 0,
3264 doc
: /* Return FRAME's native width in pixels.
3265 For a terminal frame, the result really gives the width in characters.
3266 If FRAME is omitted or nil, the selected frame is used. */)
3269 struct frame
*f
= decode_any_frame (frame
);
3271 #ifdef HAVE_WINDOW_SYSTEM
3272 if (FRAME_WINDOW_P (f
))
3273 return make_number (FRAME_PIXEL_WIDTH (f
));
3276 return make_number (FRAME_TOTAL_COLS (f
));
3279 DEFUN ("frame-native-height", Fframe_native_height
,
3280 Sframe_native_height
, 0, 1, 0,
3281 doc
: /* Return FRAME's native height in pixels.
3282 If FRAME is omitted or nil, the selected frame is used. The exact value
3283 of the result depends on the window-system and toolkit in use:
3285 In the Gtk+ and NS versions, it includes only any window (including the
3286 minibuffer or echo area), mode line, and header line. It does not
3287 include the tool bar or menu bar. With other graphical versions, it may
3288 also include the tool bar and the menu bar.
3290 For a text terminal, it includes the menu bar. In this case, the
3291 result is really in characters rather than pixels (i.e., is identical
3292 to `frame-height'). */)
3295 struct frame
*f
= decode_any_frame (frame
);
3297 #ifdef HAVE_WINDOW_SYSTEM
3298 if (FRAME_WINDOW_P (f
))
3299 return make_number (FRAME_PIXEL_HEIGHT (f
));
3302 return make_number (FRAME_TOTAL_LINES (f
));
3305 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width
,
3306 Stool_bar_pixel_width
, 0, 1, 0,
3307 doc
: /* Return width in pixels of FRAME's tool bar.
3308 The result is greater than zero only when the tool bar is on the left
3309 or right side of FRAME. If FRAME is omitted or nil, the selected frame
3313 #ifdef FRAME_TOOLBAR_WIDTH
3314 struct frame
*f
= decode_any_frame (frame
);
3316 if (FRAME_WINDOW_P (f
))
3317 return make_number (FRAME_TOOLBAR_WIDTH (f
));
3319 return make_number (0);
3322 DEFUN ("frame-text-cols", Fframe_text_cols
, Sframe_text_cols
, 0, 1, 0,
3323 doc
: /* Return width in columns of FRAME's text area. */)
3326 return make_number (FRAME_COLS (decode_any_frame (frame
)));
3329 DEFUN ("frame-text-lines", Fframe_text_lines
, Sframe_text_lines
, 0, 1, 0,
3330 doc
: /* Return height in lines of FRAME's text area. */)
3333 return make_number (FRAME_LINES (decode_any_frame (frame
)));
3336 DEFUN ("frame-total-cols", Fframe_total_cols
, Sframe_total_cols
, 0, 1, 0,
3337 doc
: /* Return number of total columns of FRAME. */)
3340 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame
)));
3343 DEFUN ("frame-total-lines", Fframe_total_lines
, Sframe_total_lines
, 0, 1, 0,
3344 doc
: /* Return number of total lines of FRAME. */)
3347 return make_number (FRAME_TOTAL_LINES (decode_any_frame (frame
)));
3350 DEFUN ("frame-text-width", Fframe_text_width
, Sframe_text_width
, 0, 1, 0,
3351 doc
: /* Return text area width of FRAME in pixels. */)
3354 return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame
)));
3357 DEFUN ("frame-text-height", Fframe_text_height
, Sframe_text_height
, 0, 1, 0,
3358 doc
: /* Return text area height of FRAME in pixels. */)
3361 return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame
)));
3364 DEFUN ("frame-scroll-bar-width", Fscroll_bar_width
, Sscroll_bar_width
, 0, 1, 0,
3365 doc
: /* Return scroll bar width of FRAME in pixels. */)
3368 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame
)));
3371 DEFUN ("frame-scroll-bar-height", Fscroll_bar_height
, Sscroll_bar_height
, 0, 1, 0,
3372 doc
: /* Return scroll bar height of FRAME in pixels. */)
3375 return make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (decode_any_frame (frame
)));
3378 DEFUN ("frame-fringe-width", Ffringe_width
, Sfringe_width
, 0, 1, 0,
3379 doc
: /* Return fringe width of FRAME in pixels. */)
3382 return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame
)));
3385 DEFUN ("frame-internal-border-width", Fframe_internal_border_width
, Sframe_internal_border_width
, 0, 1, 0,
3386 doc
: /* Return width of FRAME's internal border in pixels. */)
3389 return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame
)));
3392 DEFUN ("frame-right-divider-width", Fright_divider_width
, Sright_divider_width
, 0, 1, 0,
3393 doc
: /* Return width (in pixels) of vertical window dividers on FRAME. */)
3396 return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame
)));
3399 DEFUN ("frame-bottom-divider-width", Fbottom_divider_width
, Sbottom_divider_width
, 0, 1, 0,
3400 doc
: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
3403 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame
)));
3406 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 4, 0,
3407 doc
: /* Set text height of frame FRAME to HEIGHT lines.
3408 Optional third arg PRETEND non-nil means that redisplay should use
3409 HEIGHT lines but that the idea of the actual height of the frame should
3412 Optional fourth argument PIXELWISE non-nil means that FRAME should be
3413 HEIGHT pixels high. Note: When `frame-resize-pixelwise' is nil, some
3414 window managers may refuse to honor a HEIGHT that is not an integer
3415 multiple of the default frame font height. */)
3416 (Lisp_Object frame
, Lisp_Object height
, Lisp_Object pretend
, Lisp_Object pixelwise
)
3418 struct frame
*f
= decode_live_frame (frame
);
3421 CHECK_TYPE_RANGED_INTEGER (int, height
);
3423 pixel_height
= (!NILP (pixelwise
)
3425 : XINT (height
) * FRAME_LINE_HEIGHT (f
));
3426 adjust_frame_size (f
, -1, pixel_height
, 1, !NILP (pretend
), Qheight
);
3431 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 4, 0,
3432 doc
: /* Set text width of frame FRAME to WIDTH columns.
3433 Optional third arg PRETEND non-nil means that redisplay should use WIDTH
3434 columns but that the idea of the actual width of the frame should not
3437 Optional fourth argument PIXELWISE non-nil means that FRAME should be
3438 WIDTH pixels wide. Note: When `frame-resize-pixelwise' is nil, some
3439 window managers may refuse to honor a WIDTH that is not an integer
3440 multiple of the default frame font width. */)
3441 (Lisp_Object frame
, Lisp_Object width
, Lisp_Object pretend
, Lisp_Object pixelwise
)
3443 struct frame
*f
= decode_live_frame (frame
);
3446 CHECK_TYPE_RANGED_INTEGER (int, width
);
3448 pixel_width
= (!NILP (pixelwise
)
3450 : XINT (width
) * FRAME_COLUMN_WIDTH (f
));
3451 adjust_frame_size (f
, pixel_width
, -1, 1, !NILP (pretend
), Qwidth
);
3456 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 4, 0,
3457 doc
: /* Set text size of FRAME to WIDTH by HEIGHT, measured in characters.
3458 Optional argument PIXELWISE non-nil means to measure in pixels. Note:
3459 When `frame-resize-pixelwise' is nil, some window managers may refuse to
3460 honor a WIDTH that is not an integer multiple of the default frame font
3461 width or a HEIGHT that is not an integer multiple of the default frame
3463 (Lisp_Object frame
, Lisp_Object width
, Lisp_Object height
, Lisp_Object pixelwise
)
3465 struct frame
*f
= decode_live_frame (frame
);
3466 int pixel_width
, pixel_height
;
3468 CHECK_TYPE_RANGED_INTEGER (int, width
);
3469 CHECK_TYPE_RANGED_INTEGER (int, height
);
3471 pixel_width
= (!NILP (pixelwise
)
3473 : XINT (width
) * FRAME_COLUMN_WIDTH (f
));
3474 pixel_height
= (!NILP (pixelwise
)
3476 : XINT (height
) * FRAME_LINE_HEIGHT (f
));
3477 adjust_frame_size (f
, pixel_width
, pixel_height
, 1, 0, Qsize
);
3482 DEFUN ("frame-position", Fframe_position
,
3483 Sframe_position
, 0, 1, 0,
3484 doc
: /* Return top left corner of FRAME in pixels.
3485 FRAME must be a live frame and defaults to the selected one. The return
3486 value is a cons (x, y) of the coordinates of the top left corner of
3487 FRAME's outer frame, in pixels relative to an origin (0, 0) of FRAME's
3491 register struct frame
*f
= decode_live_frame (frame
);
3493 return Fcons (make_number (f
->left_pos
), make_number (f
->top_pos
));
3496 DEFUN ("set-frame-position", Fset_frame_position
,
3497 Sset_frame_position
, 3, 3, 0,
3498 doc
: /* Set position of FRAME to (X, Y).
3499 FRAME must be a live frame and defaults to the selected one. X and Y,
3500 if positive, specify the coordinate of the left and top edge of FRAME's
3501 outer frame in pixels relative to an origin (0, 0) of FRAME's display.
3502 If any of X or Y is negative, it specifies the coordinates of the right
3503 or bottom edge of the outer frame of FRAME relative to the right or
3504 bottom edge of FRAME's display. */)
3505 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
3507 struct frame
*f
= decode_live_frame (frame
);
3509 CHECK_TYPE_RANGED_INTEGER (int, x
);
3510 CHECK_TYPE_RANGED_INTEGER (int, y
);
3512 /* I think this should be done with a hook. */
3513 if (FRAME_WINDOW_P (f
))
3515 #ifdef HAVE_WINDOW_SYSTEM
3516 x_set_offset (f
, XINT (x
), XINT (y
), 1);
3523 /***********************************************************************
3525 ***********************************************************************/
3527 /* Connect the frame-parameter names for X frames
3528 to the ways of passing the parameter values to the window system.
3530 The name of a parameter, as a Lisp symbol,
3531 has an `x-frame-parameter' property which is an integer in Lisp
3532 that is an index in this table. */
3534 struct frame_parm_table
{
3539 static const struct frame_parm_table frame_parms
[] =
3541 {"auto-raise", SYMBOL_INDEX (Qauto_raise
)},
3542 {"auto-lower", SYMBOL_INDEX (Qauto_lower
)},
3543 {"background-color", -1},
3544 {"border-color", SYMBOL_INDEX (Qborder_color
)},
3545 {"border-width", SYMBOL_INDEX (Qborder_width
)},
3546 {"cursor-color", SYMBOL_INDEX (Qcursor_color
)},
3547 {"cursor-type", SYMBOL_INDEX (Qcursor_type
)},
3549 {"foreground-color", -1},
3550 {"icon-name", SYMBOL_INDEX (Qicon_name
)},
3551 {"icon-type", SYMBOL_INDEX (Qicon_type
)},
3552 {"internal-border-width", SYMBOL_INDEX (Qinternal_border_width
)},
3553 {"right-divider-width", SYMBOL_INDEX (Qright_divider_width
)},
3554 {"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width
)},
3555 {"menu-bar-lines", SYMBOL_INDEX (Qmenu_bar_lines
)},
3556 {"mouse-color", SYMBOL_INDEX (Qmouse_color
)},
3557 {"name", SYMBOL_INDEX (Qname
)},
3558 {"scroll-bar-width", SYMBOL_INDEX (Qscroll_bar_width
)},
3559 {"scroll-bar-height", SYMBOL_INDEX (Qscroll_bar_height
)},
3560 {"title", SYMBOL_INDEX (Qtitle
)},
3561 {"unsplittable", SYMBOL_INDEX (Qunsplittable
)},
3562 {"vertical-scroll-bars", SYMBOL_INDEX (Qvertical_scroll_bars
)},
3563 {"horizontal-scroll-bars", SYMBOL_INDEX (Qhorizontal_scroll_bars
)},
3564 {"visibility", SYMBOL_INDEX (Qvisibility
)},
3565 {"tool-bar-lines", SYMBOL_INDEX (Qtool_bar_lines
)},
3566 {"scroll-bar-foreground", SYMBOL_INDEX (Qscroll_bar_foreground
)},
3567 {"scroll-bar-background", SYMBOL_INDEX (Qscroll_bar_background
)},
3568 {"screen-gamma", SYMBOL_INDEX (Qscreen_gamma
)},
3569 {"line-spacing", SYMBOL_INDEX (Qline_spacing
)},
3570 {"left-fringe", SYMBOL_INDEX (Qleft_fringe
)},
3571 {"right-fringe", SYMBOL_INDEX (Qright_fringe
)},
3572 {"wait-for-wm", SYMBOL_INDEX (Qwait_for_wm
)},
3573 {"fullscreen", SYMBOL_INDEX (Qfullscreen
)},
3574 {"font-backend", SYMBOL_INDEX (Qfont_backend
)},
3575 {"alpha", SYMBOL_INDEX (Qalpha
)},
3576 {"sticky", SYMBOL_INDEX (Qsticky
)},
3577 {"tool-bar-position", SYMBOL_INDEX (Qtool_bar_position
)},
3578 {"inhibit-double-buffering", SYMBOL_INDEX (Qinhibit_double_buffering
)},
3579 {"undecorated", SYMBOL_INDEX (Qundecorated
)},
3580 {"parent-frame", SYMBOL_INDEX (Qparent_frame
)},
3581 {"skip-taskbar", SYMBOL_INDEX (Qskip_taskbar
)},
3582 {"no-focus-on-map", SYMBOL_INDEX (Qno_focus_on_map
)},
3583 {"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus
)},
3584 {"z-group", SYMBOL_INDEX (Qz_group
)},
3585 {"override-redirect", SYMBOL_INDEX (Qoverride_redirect
)},
3586 {"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs
)},
3587 #ifdef NS_IMPL_COCOA
3588 {"ns-appearance", SYMBOL_INDEX (Qns_appearance
)},
3589 {"ns-transparent-titlebar", SYMBOL_INDEX (Qns_transparent_titlebar
)},
3593 #ifdef HAVE_WINDOW_SYSTEM
3595 /* Enumeration type for switch in frame_float. */
3596 enum frame_float_type
3607 * Process the value VAL of the float type frame parameter 'width',
3608 * 'height', 'left', or 'top' specified via a frame_float_type
3609 * enumeration type WHAT for frame F. Such parameters relate the outer
3610 * size or position of F to the size of the F's display or parent frame
3611 * which have to be both available in some way.
3613 * The return value is a size or position value in pixels. VAL must be
3614 * in the range 0.0 to 1.0 where a width/height of 0.0 means to return 0
3615 * and 1.0 means to return the full width/height of the display/parent.
3616 * For positions, 0.0 means position in the left/top corner of the
3617 * display/parent while 1.0 means to position at the right/bottom corner
3618 * of the display/parent frame.
3620 * Set PARENT_DONE and OUTER_DONE to avoid recalculation of the outer
3621 * size or parent or display attributes when more float parameters are
3622 * calculated in a row: -1 means not processed yet, 0 means processing
3623 * failed, 1 means processing succeeded.
3625 * Return DEFAULT_VALUE when processing fails for whatever reason with
3626 * one exception: When calculating F's outer edges fails (probably
3627 * because F has not been created yet) return the difference between F's
3628 * native and text size.
3631 frame_float (struct frame
*f
, Lisp_Object val
, enum frame_float_type what
,
3632 int *parent_done
, int *outer_done
, int default_value
)
3634 double d_val
= XFLOAT_DATA (val
);
3636 if (d_val
< 0.0 || d_val
> 1.0)
3638 return default_value
;
3641 static unsigned parent_width
, parent_height
;
3642 static int parent_left
, parent_top
;
3643 static unsigned outer_minus_text_width
, outer_minus_text_height
;
3644 struct frame
*p
= FRAME_PARENT_FRAME (f
);
3646 if (*parent_done
== 1)
3650 parent_width
= FRAME_PIXEL_WIDTH (p
);
3651 parent_height
= FRAME_PIXEL_HEIGHT (p
);
3656 if (*parent_done
== 0)
3657 /* No workarea available. */
3658 return default_value
;
3659 else if (*parent_done
== -1)
3661 Lisp_Object monitor_attributes
;
3662 Lisp_Object workarea
;
3665 XSETFRAME (frame
, f
);
3666 monitor_attributes
= Fcar (call1 (Qdisplay_monitor_attributes_list
, frame
));
3667 if (NILP (monitor_attributes
))
3669 /* No monitor attributes available. */
3672 return default_value
;
3675 workarea
= Fcdr (Fassq (Qworkarea
, monitor_attributes
));
3676 if (NILP (workarea
))
3678 /* No workarea available. */
3681 return default_value
;
3684 /* Workarea available. */
3685 parent_left
= XINT (Fnth (make_number (0), workarea
));
3686 parent_top
= XINT (Fnth (make_number (1), workarea
));
3687 parent_width
= XINT (Fnth (make_number (2), workarea
));
3688 parent_height
= XINT (Fnth (make_number (3), workarea
));
3693 if (*outer_done
== 1)
3695 else if (FRAME_UNDECORATED (f
))
3697 outer_minus_text_width
3698 = FRAME_PIXEL_WIDTH (f
) - FRAME_TEXT_WIDTH (f
);
3699 outer_minus_text_height
3700 = FRAME_PIXEL_HEIGHT (f
) - FRAME_TEXT_HEIGHT (f
);
3703 else if (*outer_done
== 0)
3704 /* No outer size available. */
3705 return default_value
;
3706 else if (*outer_done
== -1)
3708 Lisp_Object frame
, outer_edges
;
3710 XSETFRAME (frame
, f
);
3711 outer_edges
= call2 (Qframe_edges
, frame
, Qouter_edges
);
3713 if (!NILP (outer_edges
))
3715 outer_minus_text_width
3716 = (XINT (Fnth (make_number (2), outer_edges
))
3717 - XINT (Fnth (make_number (0), outer_edges
))
3718 - FRAME_TEXT_WIDTH (f
));
3719 outer_minus_text_height
3720 = (XINT (Fnth (make_number (3), outer_edges
))
3721 - XINT (Fnth (make_number (1), outer_edges
))
3722 - FRAME_TEXT_HEIGHT (f
));
3726 /* If we can't get any outer edges, proceed as if the frame
3727 were undecorated. */
3728 outer_minus_text_width
3729 = FRAME_PIXEL_WIDTH (f
) - FRAME_TEXT_WIDTH (f
);
3730 outer_minus_text_height
3731 = FRAME_PIXEL_HEIGHT (f
) - FRAME_TEXT_HEIGHT (f
);
3739 case FRAME_FLOAT_WIDTH
:
3740 return parent_width
* d_val
- outer_minus_text_width
;
3742 case FRAME_FLOAT_HEIGHT
:
3743 return parent_height
* d_val
- outer_minus_text_height
;
3745 case FRAME_FLOAT_LEFT
:
3747 int rest_width
= (parent_width
3748 - FRAME_TEXT_WIDTH (f
)
3749 - outer_minus_text_width
);
3752 return (rest_width
<= 0 ? 0 : d_val
* rest_width
);
3754 return (rest_width
<= 0
3756 : parent_left
+ d_val
* rest_width
);
3758 case FRAME_FLOAT_TOP
:
3760 int rest_height
= (parent_height
3761 - FRAME_TEXT_HEIGHT (f
)
3762 - outer_minus_text_height
);
3765 return (rest_height
<= 0 ? 0 : d_val
* rest_height
);
3767 return (rest_height
<= 0
3769 : parent_top
+ d_val
* rest_height
);
3777 /* Change the parameters of frame F as specified by ALIST.
3778 If a parameter is not specially recognized, do nothing special;
3779 otherwise call the `x_set_...' function for that parameter.
3780 Except for certain geometry properties, always call store_frame_param
3781 to store the new value in the parameter alist. */
3784 x_set_frame_parameters (struct frame
*f
, Lisp_Object alist
)
3786 Lisp_Object tail
, frame
;
3789 /* If both of these parameters are present, it's more efficient to
3790 set them both at once. So we wait until we've looked at the
3791 entire list before we set them. */
3792 int width
= -1, height
= -1; /* -1 denotes they were not changed. */
3795 Lisp_Object left
, top
;
3797 /* Same with these. */
3798 Lisp_Object icon_left
, icon_top
;
3800 /* And with this. */
3801 Lisp_Object fullscreen
;
3802 bool fullscreen_change
= false;
3804 /* Record in these vectors all the parms specified. */
3806 Lisp_Object
*values
;
3807 ptrdiff_t i
, j
, size
;
3808 bool left_no_change
= 0, top_no_change
= 0;
3809 #ifdef HAVE_X_WINDOWS
3810 bool icon_left_no_change
= 0, icon_top_no_change
= 0;
3812 int parent_done
= -1, outer_done
= -1;
3814 XSETFRAME (frame
, f
);
3815 for (size
= 0, tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
3817 CHECK_LIST_END (tail
, alist
);
3820 SAFE_ALLOCA_LISP (parms
, 2 * size
);
3821 values
= parms
+ size
;
3823 /* Extract parm names and values into those vectors. */
3825 i
= 0, j
= size
- 1;
3826 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
3828 Lisp_Object elt
= XCAR (tail
), prop
= Fcar (elt
), val
= Fcdr (elt
);
3830 /* Some properties are independent of other properties, but other
3831 properties are dependent upon them. These special properties
3832 are foreground_color, background_color (affects cursor_color)
3833 and font (affects fringe widths); they're recorded starting
3834 from the end of PARMS and VALUES to process them first by using
3835 reverse iteration. */
3837 if (EQ (prop
, Qforeground_color
)
3838 || EQ (prop
, Qbackground_color
)
3839 || EQ (prop
, Qfont
))
3853 /* TAIL and ALIST are not used again below here. */
3854 alist
= tail
= Qnil
;
3856 top
= left
= Qunbound
;
3857 icon_left
= icon_top
= Qunbound
;
3859 /* Reverse order is used to make sure that special
3860 properties noticed above are processed first. */
3861 for (i
= size
- 1; i
>= 0; i
--)
3863 Lisp_Object prop
, val
;
3868 if (EQ (prop
, Qwidth
))
3870 if (RANGED_INTEGERP (0, val
, INT_MAX
))
3871 width
= XFASTINT (val
) * FRAME_COLUMN_WIDTH (f
) ;
3872 else if (CONSP (val
) && EQ (XCAR (val
), Qtext_pixels
)
3873 && RANGED_INTEGERP (0, XCDR (val
), INT_MAX
))
3874 width
= XFASTINT (XCDR (val
));
3875 else if (FLOATP (val
))
3876 width
= frame_float (f
, val
, FRAME_FLOAT_WIDTH
, &parent_done
,
3879 else if (EQ (prop
, Qheight
))
3881 if (RANGED_INTEGERP (0, val
, INT_MAX
))
3882 height
= XFASTINT (val
) * FRAME_LINE_HEIGHT (f
);
3883 else if (CONSP (val
) && EQ (XCAR (val
), Qtext_pixels
)
3884 && RANGED_INTEGERP (0, XCDR (val
), INT_MAX
))
3885 height
= XFASTINT (XCDR (val
));
3886 else if (FLOATP (val
))
3887 height
= frame_float (f
, val
, FRAME_FLOAT_HEIGHT
, &parent_done
,
3890 else if (EQ (prop
, Qtop
))
3892 else if (EQ (prop
, Qleft
))
3894 else if (EQ (prop
, Qicon_top
))
3896 else if (EQ (prop
, Qicon_left
))
3898 else if (EQ (prop
, Qfullscreen
))
3901 fullscreen_change
= true;
3905 register Lisp_Object param_index
, old_value
;
3907 old_value
= get_frame_param (f
, prop
);
3909 store_frame_param (f
, prop
, val
);
3911 param_index
= Fget (prop
, Qx_frame_parameter
);
3912 if (NATNUMP (param_index
)
3913 && XFASTINT (param_index
) < ARRAYELTS (frame_parms
)
3914 && FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])
3915 (*(FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])) (f
, val
, old_value
);
3919 /* Don't die if just one of these was set. */
3920 if (EQ (left
, Qunbound
))
3923 if (f
->left_pos
< 0)
3924 left
= list2 (Qplus
, make_number (f
->left_pos
));
3926 XSETINT (left
, f
->left_pos
);
3928 if (EQ (top
, Qunbound
))
3932 top
= list2 (Qplus
, make_number (f
->top_pos
));
3934 XSETINT (top
, f
->top_pos
);
3937 /* If one of the icon positions was not set, preserve or default it. */
3938 if (! TYPE_RANGED_INTEGERP (int, icon_left
))
3940 #ifdef HAVE_X_WINDOWS
3941 icon_left_no_change
= 1;
3943 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
3944 if (NILP (icon_left
))
3945 XSETINT (icon_left
, 0);
3947 if (! TYPE_RANGED_INTEGERP (int, icon_top
))
3949 #ifdef HAVE_X_WINDOWS
3950 icon_top_no_change
= 1;
3952 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
3953 if (NILP (icon_top
))
3954 XSETINT (icon_top
, 0);
3957 /* Don't set these parameters unless they've been explicitly
3958 specified. The window might be mapped or resized while we're in
3959 this function, and we don't want to override that unless the lisp
3960 code has asked for it.
3962 Don't set these parameters unless they actually differ from the
3963 window's current parameters; the window may not actually exist
3965 if ((width
!= -1 && width
!= FRAME_TEXT_WIDTH (f
))
3966 || (height
!= -1 && height
!= FRAME_TEXT_HEIGHT (f
)))
3967 /* We could consider checking f->after_make_frame here, but I
3968 don't have the faintest idea why the following is needed at
3969 all. With the old setting it can get a Heisenbug when
3970 EmacsFrameResize intermittently provokes a delayed
3971 change_frame_size in the middle of adjust_frame_size. */
3972 /** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
3973 adjust_frame_size (f
, width
, height
, 1, 0, Qx_set_frame_parameters
);
3975 if ((!NILP (left
) || !NILP (top
))
3976 && ! (left_no_change
&& top_no_change
)
3977 && ! (NUMBERP (left
) && XINT (left
) == f
->left_pos
3978 && NUMBERP (top
) && XINT (top
) == f
->top_pos
))
3983 /* Record the signs. */
3984 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
3985 if (EQ (left
, Qminus
))
3986 f
->size_hint_flags
|= XNegative
;
3987 else if (TYPE_RANGED_INTEGERP (int, left
))
3989 leftpos
= XINT (left
);
3991 f
->size_hint_flags
|= XNegative
;
3993 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
3994 && CONSP (XCDR (left
))
3995 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (left
)), INT_MAX
))
3997 leftpos
= - XINT (XCAR (XCDR (left
)));
3998 f
->size_hint_flags
|= XNegative
;
4000 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
4001 && CONSP (XCDR (left
))
4002 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left
))))
4003 leftpos
= XINT (XCAR (XCDR (left
)));
4004 else if (FLOATP (left
))
4005 leftpos
= frame_float (f
, left
, FRAME_FLOAT_LEFT
, &parent_done
,
4008 if (EQ (top
, Qminus
))
4009 f
->size_hint_flags
|= YNegative
;
4010 else if (TYPE_RANGED_INTEGERP (int, top
))
4012 toppos
= XINT (top
);
4014 f
->size_hint_flags
|= YNegative
;
4016 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
4017 && CONSP (XCDR (top
))
4018 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (top
)), INT_MAX
))
4020 toppos
= - XINT (XCAR (XCDR (top
)));
4021 f
->size_hint_flags
|= YNegative
;
4023 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
4024 && CONSP (XCDR (top
))
4025 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top
))))
4026 toppos
= XINT (XCAR (XCDR (top
)));
4027 else if (FLOATP (top
))
4028 toppos
= frame_float (f
, top
, FRAME_FLOAT_TOP
, &parent_done
,
4031 /* Store the numeric value of the position. */
4032 f
->top_pos
= toppos
;
4033 f
->left_pos
= leftpos
;
4035 f
->win_gravity
= NorthWestGravity
;
4037 /* Actually set that position, and convert to absolute. */
4038 x_set_offset (f
, leftpos
, toppos
, -1);
4041 if (fullscreen_change
)
4043 Lisp_Object old_value
= get_frame_param (f
, Qfullscreen
);
4045 frame_size_history_add
4046 (f
, Qx_set_fullscreen
, 0, 0, list2 (old_value
, fullscreen
));
4048 store_frame_param (f
, Qfullscreen
, fullscreen
);
4049 if (!EQ (fullscreen
, old_value
))
4050 x_set_fullscreen (f
, fullscreen
, old_value
);
4054 #ifdef HAVE_X_WINDOWS
4055 if ((!NILP (icon_left
) || !NILP (icon_top
))
4056 && ! (icon_left_no_change
&& icon_top_no_change
))
4057 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
4058 #endif /* HAVE_X_WINDOWS */
4064 /* Insert a description of internally-recorded parameters of frame X
4065 into the parameter alist *ALISTPTR that is to be given to the user.
4066 Only parameters that are specific to the X window system
4067 and whose values are not correctly recorded in the frame's
4068 param_alist need to be considered here. */
4071 x_report_frame_params (struct frame
*f
, Lisp_Object
*alistptr
)
4075 char buf
[INT_BUFSIZE_BOUND (w
)];
4077 /* Represent negative positions (off the top or left screen edge)
4078 in a way that Fmodify_frame_parameters will understand correctly. */
4079 XSETINT (tem
, f
->left_pos
);
4080 if (f
->left_pos
>= 0)
4081 store_in_alist (alistptr
, Qleft
, tem
);
4083 store_in_alist (alistptr
, Qleft
, list2 (Qplus
, tem
));
4085 XSETINT (tem
, f
->top_pos
);
4086 if (f
->top_pos
>= 0)
4087 store_in_alist (alistptr
, Qtop
, tem
);
4089 store_in_alist (alistptr
, Qtop
, list2 (Qplus
, tem
));
4091 store_in_alist (alistptr
, Qborder_width
,
4092 make_number (f
->border_width
));
4093 store_in_alist (alistptr
, Qinternal_border_width
,
4094 make_number (FRAME_INTERNAL_BORDER_WIDTH (f
)));
4095 store_in_alist (alistptr
, Qright_divider_width
,
4096 make_number (FRAME_RIGHT_DIVIDER_WIDTH (f
)));
4097 store_in_alist (alistptr
, Qbottom_divider_width
,
4098 make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f
)));
4099 store_in_alist (alistptr
, Qleft_fringe
,
4100 make_number (FRAME_LEFT_FRINGE_WIDTH (f
)));
4101 store_in_alist (alistptr
, Qright_fringe
,
4102 make_number (FRAME_RIGHT_FRINGE_WIDTH (f
)));
4103 store_in_alist (alistptr
, Qscroll_bar_width
,
4104 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4106 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0
4107 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
))
4108 /* nil means "use default width"
4109 for non-toolkit scroll bar.
4110 ruler-mode.el depends on this. */
4112 store_in_alist (alistptr
, Qscroll_bar_height
,
4113 (! FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
)
4115 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) > 0
4116 ? make_number (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
))
4117 /* nil means "use default height"
4118 for non-toolkit scroll bar. */
4120 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
4121 MS-Windows it returns a value whose type is HANDLE, which is
4122 actually a pointer. Explicit casting avoids compiler
4124 w
= (uintptr_t) FRAME_X_WINDOW (f
);
4125 store_in_alist (alistptr
, Qwindow_id
,
4126 make_formatted_string (buf
, "%"pMu
, w
));
4127 #ifdef HAVE_X_WINDOWS
4128 #ifdef USE_X_TOOLKIT
4129 /* Tooltip frame may not have this widget. */
4130 if (FRAME_X_OUTPUT (f
)->widget
)
4132 w
= (uintptr_t) FRAME_OUTER_WINDOW (f
);
4133 store_in_alist (alistptr
, Qouter_window_id
,
4134 make_formatted_string (buf
, "%"pMu
, w
));
4136 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
4137 store_in_alist (alistptr
, Qvisibility
,
4138 (FRAME_VISIBLE_P (f
) ? Qt
4139 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
4140 store_in_alist (alistptr
, Qdisplay
,
4141 XCAR (FRAME_DISPLAY_INFO (f
)->name_list_element
));
4143 if (FRAME_X_OUTPUT (f
)->parent_desc
== FRAME_DISPLAY_INFO (f
)->root_window
)
4146 tem
= make_natnum ((uintptr_t) FRAME_X_OUTPUT (f
)->parent_desc
);
4147 store_in_alist (alistptr
, Qexplicit_name
, (f
->explicit_name
? Qt
: Qnil
));
4148 store_in_alist (alistptr
, Qparent_id
, tem
);
4149 store_in_alist (alistptr
, Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
));
4153 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
4154 the previous value of that parameter, NEW_VALUE is the new value. */
4157 x_set_fullscreen (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4159 if (NILP (new_value
))
4160 f
->want_fullscreen
= FULLSCREEN_NONE
;
4161 else if (EQ (new_value
, Qfullboth
) || EQ (new_value
, Qfullscreen
))
4162 f
->want_fullscreen
= FULLSCREEN_BOTH
;
4163 else if (EQ (new_value
, Qfullwidth
))
4164 f
->want_fullscreen
= FULLSCREEN_WIDTH
;
4165 else if (EQ (new_value
, Qfullheight
))
4166 f
->want_fullscreen
= FULLSCREEN_HEIGHT
;
4167 else if (EQ (new_value
, Qmaximized
))
4168 f
->want_fullscreen
= FULLSCREEN_MAXIMIZED
;
4170 if (FRAME_TERMINAL (f
)->fullscreen_hook
!= NULL
)
4171 FRAME_TERMINAL (f
)->fullscreen_hook (f
);
4175 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
4176 the previous value of that parameter, NEW_VALUE is the new value. */
4179 x_set_line_spacing (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4181 if (NILP (new_value
))
4182 f
->extra_line_spacing
= 0;
4183 else if (RANGED_INTEGERP (0, new_value
, INT_MAX
))
4184 f
->extra_line_spacing
= XFASTINT (new_value
);
4185 else if (FLOATP (new_value
))
4187 int new_spacing
= XFLOAT_DATA (new_value
) * FRAME_LINE_HEIGHT (f
) + 0.5;
4189 if (new_spacing
>= 0)
4190 f
->extra_line_spacing
= new_spacing
;
4192 signal_error ("Invalid line-spacing", new_value
);
4195 signal_error ("Invalid line-spacing", new_value
);
4196 if (FRAME_VISIBLE_P (f
))
4201 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
4202 the previous value of that parameter, NEW_VALUE is the new value. */
4205 x_set_screen_gamma (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4207 Lisp_Object bgcolor
;
4209 if (NILP (new_value
))
4211 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
4212 /* The value 0.4545 is the normal viewing gamma. */
4213 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
4215 signal_error ("Invalid screen-gamma", new_value
);
4217 /* Apply the new gamma value to the frame background. */
4218 bgcolor
= Fassq (Qbackground_color
, f
->param_alist
);
4219 if (CONSP (bgcolor
) && (bgcolor
= XCDR (bgcolor
), STRINGP (bgcolor
)))
4221 Lisp_Object parm_index
= Fget (Qbackground_color
, Qx_frame_parameter
);
4222 if (NATNUMP (parm_index
)
4223 && XFASTINT (parm_index
) < ARRAYELTS (frame_parms
)
4224 && FRAME_RIF (f
)->frame_parm_handlers
[XFASTINT (parm_index
)])
4225 (*FRAME_RIF (f
)->frame_parm_handlers
[XFASTINT (parm_index
)])
4229 clear_face_cache (true); /* FIXME: Why of all frames? */
4235 x_set_font (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4237 Lisp_Object font_object
;
4239 #ifdef HAVE_X_WINDOWS
4240 Lisp_Object font_param
= arg
;
4243 /* Set the frame parameter back to the old value because we may
4244 fail to use ARG as the new parameter value. */
4245 store_frame_param (f
, Qfont
, oldval
);
4247 /* ARG is a fontset name, a font name, a cons of fontset name and a
4248 font object, or a font object. In the last case, this function
4252 fontset
= fs_query_fontset (arg
, 0);
4255 font_object
= font_open_by_name (f
, arg
);
4256 if (NILP (font_object
))
4257 error ("Font `%s' is not defined", SSDATA (arg
));
4258 arg
= AREF (font_object
, FONT_NAME_INDEX
);
4260 else if (fontset
> 0)
4262 font_object
= font_open_by_name (f
, fontset_ascii (fontset
));
4263 if (NILP (font_object
))
4264 error ("Font `%s' is not defined", SDATA (arg
));
4265 arg
= AREF (font_object
, FONT_NAME_INDEX
);
4268 error ("The default fontset can't be used for a frame font");
4270 else if (CONSP (arg
) && STRINGP (XCAR (arg
)) && FONT_OBJECT_P (XCDR (arg
)))
4272 /* This is the case that the ASCII font of F's fontset XCAR
4273 (arg) is changed to the font XCDR (arg) by
4274 `set-fontset-font'. */
4275 fontset
= fs_query_fontset (XCAR (arg
), 0);
4277 error ("Unknown fontset: %s", SDATA (XCAR (arg
)));
4278 font_object
= XCDR (arg
);
4279 arg
= AREF (font_object
, FONT_NAME_INDEX
);
4280 #ifdef HAVE_X_WINDOWS
4281 font_param
= Ffont_get (font_object
, QCname
);
4284 else if (FONT_OBJECT_P (arg
))
4287 #ifdef HAVE_X_WINDOWS
4288 font_param
= Ffont_get (font_object
, QCname
);
4290 /* This is to store the XLFD font name in the frame parameter for
4291 backward compatibility. We should store the font-object
4292 itself in the future. */
4293 arg
= AREF (font_object
, FONT_NAME_INDEX
);
4294 fontset
= FRAME_FONTSET (f
);
4295 /* Check if we can use the current fontset. If not, set FONTSET
4296 to -1 to generate a new fontset from FONT-OBJECT. */
4299 Lisp_Object ascii_font
= fontset_ascii (fontset
);
4300 Lisp_Object spec
= font_spec_from_name (ascii_font
);
4302 /* SPEC might be nil because ASCII_FONT's name doesn't parse
4303 according to stupid XLFD rules, which, for example,
4304 disallow font names that include a dash followed by a
4305 number. So in those cases we simply request x_new_font
4306 below to generate a new fontset. */
4307 if (NILP (spec
) || ! font_match_p (spec
, font_object
))
4312 signal_error ("Invalid font", arg
);
4314 if (! NILP (Fequal (font_object
, oldval
)))
4317 x_new_font (f
, font_object
, fontset
);
4318 store_frame_param (f
, Qfont
, arg
);
4319 #ifdef HAVE_X_WINDOWS
4320 store_frame_param (f
, Qfont_parameter
, font_param
);
4322 /* Recalculate toolbar height. */
4323 f
->n_tool_bar_rows
= 0;
4325 /* Ensure we redraw it. */
4326 clear_current_matrices (f
);
4328 /* Attempt to hunt down bug#16028. */
4329 SET_FRAME_GARBAGED (f
);
4331 /* This is important if we are called by some Lisp as part of
4332 redisplaying the frame, see redisplay_internal. */
4333 f
->fonts_changed
= true;
4335 recompute_basic_faces (f
);
4337 do_pending_window_change (0);
4339 /* We used to call face-set-after-frame-default here, but it leads to
4340 recursive calls (since that function can set the `default' face's
4341 font which in turns changes the frame's `font' parameter).
4342 Also I don't know what this call is meant to do, but it seems the
4343 wrong way to do it anyway (it does a lot more work than what seems
4344 reasonable in response to a change to `font'). */
4349 x_set_font_backend (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4351 if (! NILP (new_value
)
4352 && !CONSP (new_value
))
4356 CHECK_STRING (new_value
);
4357 p0
= p1
= SSDATA (new_value
);
4361 while (*p1
&& ! c_isspace (*p1
) && *p1
!= ',') p1
++;
4363 new_value
= Fcons (Fintern (make_string (p0
, p1
- p0
), Qnil
),
4369 while ((c
= *++p1
) && c_isspace (c
));
4373 new_value
= Fnreverse (new_value
);
4376 if (! NILP (old_value
) && ! NILP (Fequal (old_value
, new_value
)))
4380 free_all_realized_faces (Qnil
);
4382 new_value
= font_update_drivers (f
, NILP (new_value
) ? Qt
: new_value
);
4383 if (NILP (new_value
))
4385 if (NILP (old_value
))
4386 error ("No font backend available");
4387 font_update_drivers (f
, old_value
);
4388 error ("None of specified font backends are available");
4390 store_frame_param (f
, Qfont_backend
, new_value
);
4396 XSETFRAME (frame
, f
);
4397 x_set_font (f
, Fframe_parameter (frame
, Qfont
), Qnil
);
4399 windows_or_buffers_changed
= 18;
4404 x_set_left_fringe (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4406 int unit
= FRAME_COLUMN_WIDTH (f
);
4407 int old_width
= FRAME_LEFT_FRINGE_WIDTH (f
);
4410 new_width
= (RANGED_INTEGERP (-INT_MAX
, new_value
, INT_MAX
)
4411 ? eabs (XINT (new_value
)) : 8);
4413 if (new_width
!= old_width
)
4415 f
->left_fringe_width
= new_width
;
4416 f
->fringe_cols
/* Round up. */
4417 = (new_width
+ FRAME_RIGHT_FRINGE_WIDTH (f
) + unit
- 1) / unit
;
4419 if (FRAME_X_WINDOW (f
) != 0)
4420 adjust_frame_size (f
, -1, -1, 3, 0, Qleft_fringe
);
4422 SET_FRAME_GARBAGED (f
);
4428 x_set_right_fringe (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4430 int unit
= FRAME_COLUMN_WIDTH (f
);
4431 int old_width
= FRAME_RIGHT_FRINGE_WIDTH (f
);
4434 new_width
= (RANGED_INTEGERP (-INT_MAX
, new_value
, INT_MAX
)
4435 ? eabs (XINT (new_value
)) : 8);
4437 if (new_width
!= old_width
)
4439 f
->right_fringe_width
= new_width
;
4440 f
->fringe_cols
/* Round up. */
4441 = (new_width
+ FRAME_LEFT_FRINGE_WIDTH (f
) + unit
- 1) / unit
;
4443 if (FRAME_X_WINDOW (f
) != 0)
4444 adjust_frame_size (f
, -1, -1, 3, 0, Qright_fringe
);
4446 SET_FRAME_GARBAGED (f
);
4452 x_set_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4454 CHECK_TYPE_RANGED_INTEGER (int, arg
);
4456 if (XINT (arg
) == f
->border_width
)
4459 if (FRAME_X_WINDOW (f
) != 0)
4460 error ("Cannot change the border width of a frame");
4462 f
->border_width
= XINT (arg
);
4466 x_set_right_divider_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4468 int old
= FRAME_RIGHT_DIVIDER_WIDTH (f
);
4469 CHECK_TYPE_RANGED_INTEGER (int, arg
);
4470 int new = max (0, XINT (arg
));
4473 f
->right_divider_width
= new;
4474 adjust_frame_size (f
, -1, -1, 4, 0, Qright_divider_width
);
4475 adjust_frame_glyphs (f
);
4476 SET_FRAME_GARBAGED (f
);
4481 x_set_bottom_divider_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4483 int old
= FRAME_BOTTOM_DIVIDER_WIDTH (f
);
4484 CHECK_TYPE_RANGED_INTEGER (int, arg
);
4485 int new = max (0, XINT (arg
));
4488 f
->bottom_divider_width
= new;
4489 adjust_frame_size (f
, -1, -1, 4, 0, Qbottom_divider_width
);
4490 adjust_frame_glyphs (f
);
4491 SET_FRAME_GARBAGED (f
);
4496 x_set_visibility (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
4499 XSETFRAME (frame
, f
);
4502 Fmake_frame_invisible (frame
, Qt
);
4503 else if (EQ (value
, Qicon
))
4504 Ficonify_frame (frame
);
4506 Fmake_frame_visible (frame
);
4510 x_set_autoraise (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4512 f
->auto_raise
= !NILP (arg
);
4516 x_set_autolower (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4518 f
->auto_lower
= !NILP (arg
);
4522 x_set_unsplittable (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4524 f
->no_split
= !NILP (arg
);
4528 x_set_vertical_scroll_bars (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4530 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4531 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
4532 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4533 || (!NILP (arg
) && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
4535 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
4537 ? vertical_scroll_bar_none
4539 ? vertical_scroll_bar_left
4541 ? vertical_scroll_bar_right
4542 : EQ (Qleft
, Vdefault_frame_scroll_bars
)
4543 ? vertical_scroll_bar_left
4544 : EQ (Qright
, Vdefault_frame_scroll_bars
)
4545 ? vertical_scroll_bar_right
4546 : vertical_scroll_bar_none
);
4548 /* We set this parameter before creating the X window for the
4549 frame, so we can get the geometry right from the start.
4550 However, if the window hasn't been created yet, we shouldn't
4551 call x_set_window_size. */
4552 if (FRAME_X_WINDOW (f
))
4553 adjust_frame_size (f
, -1, -1, 3, 0, Qvertical_scroll_bars
);
4555 SET_FRAME_GARBAGED (f
);
4560 x_set_horizontal_scroll_bars (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4562 #if USE_HORIZONTAL_SCROLL_BARS
4563 if ((NILP (arg
) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
))
4564 || (!NILP (arg
) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
)))
4566 f
->horizontal_scroll_bars
= NILP (arg
) ? false : true;
4568 /* We set this parameter before creating the X window for the
4569 frame, so we can get the geometry right from the start.
4570 However, if the window hasn't been created yet, we shouldn't
4571 call x_set_window_size. */
4572 if (FRAME_X_WINDOW (f
))
4573 adjust_frame_size (f
, -1, -1, 3, 0, Qhorizontal_scroll_bars
);
4575 SET_FRAME_GARBAGED (f
);
4581 x_set_scroll_bar_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4583 int unit
= FRAME_COLUMN_WIDTH (f
);
4587 x_set_scroll_bar_default_width (f
);
4589 if (FRAME_X_WINDOW (f
))
4590 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_width
);
4592 SET_FRAME_GARBAGED (f
);
4594 else if (RANGED_INTEGERP (1, arg
, INT_MAX
)
4595 && XFASTINT (arg
) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f
))
4597 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = XFASTINT (arg
);
4598 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + unit
- 1) / unit
;
4599 if (FRAME_X_WINDOW (f
))
4600 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_width
);
4602 SET_FRAME_GARBAGED (f
);
4605 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
4606 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
4610 x_set_scroll_bar_height (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4612 #if USE_HORIZONTAL_SCROLL_BARS
4613 int unit
= FRAME_LINE_HEIGHT (f
);
4617 x_set_scroll_bar_default_height (f
);
4619 if (FRAME_X_WINDOW (f
))
4620 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_height
);
4622 SET_FRAME_GARBAGED (f
);
4624 else if (RANGED_INTEGERP (1, arg
, INT_MAX
)
4625 && XFASTINT (arg
) != FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
))
4627 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = XFASTINT (arg
);
4628 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (XFASTINT (arg
) + unit
- 1) / unit
;
4629 if (FRAME_X_WINDOW (f
))
4630 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_height
);
4632 SET_FRAME_GARBAGED (f
);
4635 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.vpos
= 0;
4636 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.y
= 0;
4641 x_set_alpha (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4648 for (i
= 0; i
< 2; i
++)
4661 else if (FLOATP (item
))
4663 alpha
= XFLOAT_DATA (item
);
4664 if (! (0 <= alpha
&& alpha
<= 1.0))
4665 args_out_of_range (make_float (0.0), make_float (1.0));
4667 else if (INTEGERP (item
))
4669 EMACS_INT ialpha
= XINT (item
);
4670 if (! (0 <= ialpha
&& ialpha
<= 100))
4671 args_out_of_range (make_number (0), make_number (100));
4672 alpha
= ialpha
/ 100.0;
4675 wrong_type_argument (Qnumberp
, item
);
4679 for (i
= 0; i
< 2; i
++)
4680 f
->alpha
[i
] = newval
[i
];
4682 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
4684 x_set_frame_alpha (f
);
4693 * x_set_no_special_glyphs:
4695 * Set frame F's `no-special-glyphs' parameter which, if non-nil,
4696 * suppresses the display of truncation and continuation glyphs
4700 x_set_no_special_glyphs (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
4702 if (!EQ (new_value
, old_value
))
4703 FRAME_NO_SPECIAL_GLYPHS (f
) = !NILP (new_value
);
4709 /* Non-zero if mouse is grabbed on DPYINFO
4710 and we know the frame where it is. */
4712 bool x_mouse_grabbed (Display_Info
*dpyinfo
)
4714 return (dpyinfo
->grabbed
4715 && dpyinfo
->last_mouse_frame
4716 && FRAME_LIVE_P (dpyinfo
->last_mouse_frame
));
4719 /* Re-highlight something with mouse-face properties
4720 on DPYINFO using saved frame and mouse position. */
4723 x_redo_mouse_highlight (Display_Info
*dpyinfo
)
4725 if (dpyinfo
->last_mouse_motion_frame
4726 && FRAME_LIVE_P (dpyinfo
->last_mouse_motion_frame
))
4727 note_mouse_highlight (dpyinfo
->last_mouse_motion_frame
,
4728 dpyinfo
->last_mouse_motion_x
,
4729 dpyinfo
->last_mouse_motion_y
);
4732 #endif /* HAVE_NS */
4734 /* Subroutines of creating an X frame. */
4736 /* Make sure that Vx_resource_name is set to a reasonable value.
4737 Fix it up, or set it to `emacs' if it is too hopeless. */
4740 validate_x_resource_name (void)
4743 /* Number of valid characters in the resource name. */
4744 ptrdiff_t good_count
= 0;
4745 /* Number of invalid characters in the resource name. */
4746 ptrdiff_t bad_count
= 0;
4750 if (!STRINGP (Vx_resource_class
))
4751 Vx_resource_class
= build_string (EMACS_CLASS
);
4753 if (STRINGP (Vx_resource_name
))
4755 unsigned char *p
= SDATA (Vx_resource_name
);
4757 len
= SBYTES (Vx_resource_name
);
4759 /* Only letters, digits, - and _ are valid in resource names.
4760 Count the valid characters and count the invalid ones. */
4761 for (i
= 0; i
< len
; i
++)
4764 if (! ((c
>= 'a' && c
<= 'z')
4765 || (c
>= 'A' && c
<= 'Z')
4766 || (c
>= '0' && c
<= '9')
4767 || c
== '-' || c
== '_'))
4774 /* Not a string => completely invalid. */
4775 bad_count
= 5, good_count
= 0;
4777 /* If name is valid already, return. */
4781 /* If name is entirely invalid, or nearly so, or is so implausibly
4782 large that alloca might not work, use `emacs'. */
4783 if (good_count
< 2 || MAX_ALLOCA
- sizeof ".customization" < len
)
4785 Vx_resource_name
= build_string ("emacs");
4789 /* Name is partly valid. Copy it and replace the invalid characters
4790 with underscores. */
4792 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
4794 for (i
= 0; i
< len
; i
++)
4796 int c
= SREF (new, i
);
4797 if (! ((c
>= 'a' && c
<= 'z')
4798 || (c
>= 'A' && c
<= 'Z')
4799 || (c
>= '0' && c
<= '9')
4800 || c
== '-' || c
== '_'))
4805 /* Get specified attribute from resource database RDB.
4806 See Fx_get_resource below for other parameters. */
4809 xrdb_get_resource (XrmDatabase rdb
, Lisp_Object attribute
, Lisp_Object
class, Lisp_Object component
, Lisp_Object subclass
)
4811 CHECK_STRING (attribute
);
4812 CHECK_STRING (class);
4814 if (!NILP (component
))
4815 CHECK_STRING (component
);
4816 if (!NILP (subclass
))
4817 CHECK_STRING (subclass
);
4818 if (NILP (component
) != NILP (subclass
))
4819 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
4821 validate_x_resource_name ();
4823 /* Allocate space for the components, the dots which separate them,
4824 and the final '\0'. Make them big enough for the worst case. */
4825 ptrdiff_t name_keysize
= (SBYTES (Vx_resource_name
)
4826 + (STRINGP (component
)
4827 ? SBYTES (component
) : 0)
4828 + SBYTES (attribute
)
4831 ptrdiff_t class_keysize
= (SBYTES (Vx_resource_class
)
4833 + (STRINGP (subclass
)
4834 ? SBYTES (subclass
) : 0)
4837 char *name_key
= SAFE_ALLOCA (name_keysize
+ class_keysize
);
4838 char *class_key
= name_key
+ name_keysize
;
4839 name_key
= ptr_bounds_clip (name_key
, name_keysize
);
4840 class_key
= ptr_bounds_clip (class_key
, class_keysize
);
4842 /* Start with emacs.FRAMENAME for the name (the specific one)
4843 and with `Emacs' for the class key (the general one). */
4844 char *nz
= lispstpcpy (name_key
, Vx_resource_name
);
4845 char *cz
= lispstpcpy (class_key
, Vx_resource_class
);
4848 cz
= lispstpcpy (cz
, class);
4850 if (!NILP (component
))
4853 lispstpcpy (cz
, subclass
);
4856 nz
= lispstpcpy (nz
, component
);
4860 lispstpcpy (nz
, attribute
);
4862 char *value
= x_get_string_resource (rdb
, name_key
, class_key
);
4865 if (value
&& *value
)
4866 return build_string (value
);
4872 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
4873 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
4874 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
4875 class, where INSTANCE is the name under which Emacs was invoked, or
4876 the name specified by the `-name' or `-rn' command-line arguments.
4878 The optional arguments COMPONENT and SUBCLASS add to the key and the
4879 class, respectively. You must specify both of them or neither.
4880 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
4881 and the class is `Emacs.CLASS.SUBCLASS'. */)
4882 (Lisp_Object attribute
, Lisp_Object
class, Lisp_Object component
,
4883 Lisp_Object subclass
)
4885 check_window_system (NULL
);
4887 return xrdb_get_resource (check_x_display_info (Qnil
)->xrdb
,
4888 attribute
, class, component
, subclass
);
4891 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
4894 display_x_get_resource (Display_Info
*dpyinfo
, Lisp_Object attribute
,
4895 Lisp_Object
class, Lisp_Object component
,
4896 Lisp_Object subclass
)
4898 return xrdb_get_resource (dpyinfo
->xrdb
,
4899 attribute
, class, component
, subclass
);
4902 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT && !defined USE_GTK
4903 /* Used when C code wants a resource value. */
4904 /* Called from oldXMenu/Create.c. */
4906 x_get_resource_string (const char *attribute
, const char *class)
4909 struct frame
*sf
= SELECTED_FRAME ();
4910 ptrdiff_t invocation_namelen
= SBYTES (Vinvocation_name
);
4913 /* Allocate space for the components, the dots which separate them,
4914 and the final '\0'. */
4915 ptrdiff_t name_keysize
= invocation_namelen
+ strlen (attribute
) + 2;
4916 ptrdiff_t class_keysize
= sizeof (EMACS_CLASS
) - 1 + strlen (class) + 2;
4917 char *name_key
= SAFE_ALLOCA (name_keysize
+ class_keysize
);
4918 char *class_key
= name_key
+ name_keysize
;
4919 name_key
= ptr_bounds_clip (name_key
, name_keysize
);
4920 class_key
= ptr_bounds_clip (class_key
, class_keysize
);
4922 esprintf (name_key
, "%s.%s", SSDATA (Vinvocation_name
), attribute
);
4923 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
4925 result
= x_get_string_resource (FRAME_DISPLAY_INFO (sf
)->xrdb
,
4926 name_key
, class_key
);
4932 /* Return the value of parameter PARAM.
4934 First search ALIST, then Vdefault_frame_alist, then the X defaults
4935 database, using ATTRIBUTE as the attribute name and CLASS as its class.
4937 Convert the resource to the type specified by desired_type.
4939 If no default is specified, return Qunbound. If you call
4940 x_get_arg, make sure you deal with Qunbound in a reasonable way,
4941 and don't let it get stored in any Lisp-visible variables! */
4944 x_get_arg (Display_Info
*dpyinfo
, Lisp_Object alist
, Lisp_Object param
,
4945 const char *attribute
, const char *class, enum resource_types type
)
4949 tem
= Fassq (param
, alist
);
4953 /* If we find this parm in ALIST, clear it out
4954 so that it won't be "left over" at the end. */
4956 XSETCAR (tem
, Qnil
);
4957 /* In case the parameter appears more than once in the alist,
4959 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
4960 if (CONSP (XCAR (tail
))
4961 && EQ (XCAR (XCAR (tail
)), param
))
4962 XSETCAR (XCAR (tail
), Qnil
);
4965 tem
= Fassq (param
, Vdefault_frame_alist
);
4967 /* If it wasn't specified in ALIST or the Lisp-level defaults,
4968 look in the X resources. */
4971 if (attribute
&& dpyinfo
)
4973 AUTO_STRING (at
, attribute
);
4974 AUTO_STRING (cl
, class);
4975 tem
= display_x_get_resource (dpyinfo
, at
, cl
, Qnil
, Qnil
);
4982 case RES_TYPE_NUMBER
:
4983 return make_number (atoi (SSDATA (tem
)));
4985 case RES_TYPE_BOOLEAN_NUMBER
:
4986 if (!strcmp (SSDATA (tem
), "on")
4987 || !strcmp (SSDATA (tem
), "true"))
4988 return make_number (1);
4989 return make_number (atoi (SSDATA (tem
)));
4992 case RES_TYPE_FLOAT
:
4993 return make_float (atof (SSDATA (tem
)));
4995 case RES_TYPE_BOOLEAN
:
4996 tem
= Fdowncase (tem
);
4997 if (!strcmp (SSDATA (tem
), "on")
4999 || !strcmp (SSDATA (tem
), "yes")
5001 || !strcmp (SSDATA (tem
), "true"))
5006 case RES_TYPE_STRING
:
5009 case RES_TYPE_SYMBOL
:
5010 /* As a special case, we map the values `true' and `on'
5011 to Qt, and `false' and `off' to Qnil. */
5014 lower
= Fdowncase (tem
);
5015 if (!strcmp (SSDATA (lower
), "on")
5017 || !strcmp (SSDATA (lower
), "yes")
5019 || !strcmp (SSDATA (lower
), "true"))
5021 else if (!strcmp (SSDATA (lower
), "off")
5023 || !strcmp (SSDATA (lower
), "no")
5025 || !strcmp (SSDATA (lower
), "false"))
5028 return Fintern (tem
, Qnil
);
5042 x_frame_get_arg (struct frame
*f
, Lisp_Object alist
, Lisp_Object param
,
5043 const char *attribute
, const char *class,
5044 enum resource_types type
)
5046 return x_get_arg (FRAME_DISPLAY_INFO (f
),
5047 alist
, param
, attribute
, class, type
);
5050 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
5053 x_frame_get_and_record_arg (struct frame
*f
, Lisp_Object alist
,
5055 const char *attribute
, const char *class,
5056 enum resource_types type
)
5060 value
= x_get_arg (FRAME_DISPLAY_INFO (f
), alist
, param
,
5061 attribute
, class, type
);
5062 if (! NILP (value
) && ! EQ (value
, Qunbound
))
5063 store_frame_param (f
, param
, value
);
5069 /* Record in frame F the specified or default value according to ALIST
5070 of the parameter named PROP (a Lisp symbol).
5071 If no value is specified for PROP, look for an X default for XPROP
5072 on the frame named NAME.
5073 If that is not found either, use the value DEFLT. */
5076 x_default_parameter (struct frame
*f
, Lisp_Object alist
, Lisp_Object prop
,
5077 Lisp_Object deflt
, const char *xprop
, const char *xclass
,
5078 enum resource_types type
)
5082 tem
= x_frame_get_arg (f
, alist
, prop
, xprop
, xclass
, type
);
5083 if (EQ (tem
, Qunbound
))
5085 AUTO_FRAME_ARG (arg
, prop
, tem
);
5086 x_set_frame_parameters (f
, arg
);
5091 #if !defined (HAVE_X_WINDOWS) && defined (NoValue)
5094 * XParseGeometry parses strings of the form
5095 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
5096 * width, height, xoffset, and yoffset are unsigned integers.
5097 * Example: "=80x24+300-49"
5098 * The equal sign is optional.
5099 * It returns a bitmask that indicates which of the four values
5100 * were actually found in the string. For each value found,
5101 * the corresponding argument is updated; for each value
5102 * not found, the corresponding argument is left unchanged.
5106 XParseGeometry (char *string
,
5108 unsigned int *width
, unsigned int *height
)
5112 unsigned long tempWidth UNINIT
, tempHeight UNINIT
;
5113 long int tempX UNINIT
, tempY UNINIT
;
5114 char *nextCharacter
;
5116 if (string
== NULL
|| *string
== '\0')
5119 string
++; /* ignore possible '=' at beg of geometry spec */
5122 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
5124 tempWidth
= strtoul (strind
, &nextCharacter
, 10);
5125 if (strind
== nextCharacter
)
5127 strind
= nextCharacter
;
5131 if (*strind
== 'x' || *strind
== 'X')
5134 tempHeight
= strtoul (strind
, &nextCharacter
, 10);
5135 if (strind
== nextCharacter
)
5137 strind
= nextCharacter
;
5138 mask
|= HeightValue
;
5141 if (*strind
== '+' || *strind
== '-')
5145 tempX
= strtol (strind
, &nextCharacter
, 10);
5146 if (strind
== nextCharacter
)
5148 strind
= nextCharacter
;
5150 if (*strind
== '+' || *strind
== '-')
5154 tempY
= strtol (strind
, &nextCharacter
, 10);
5155 if (strind
== nextCharacter
)
5157 strind
= nextCharacter
;
5162 /* If strind isn't at the end of the string then it's an invalid
5163 geometry specification. */
5165 if (*strind
!= '\0')
5169 *x
= clip_to_bounds (INT_MIN
, tempX
, INT_MAX
);
5171 *y
= clip_to_bounds (INT_MIN
, tempY
, INT_MAX
);
5172 if (mask
& WidthValue
)
5173 *width
= min (tempWidth
, UINT_MAX
);
5174 if (mask
& HeightValue
)
5175 *height
= min (tempHeight
, UINT_MAX
);
5179 #endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
5182 /* NS used to define x-parse-geometry in ns-win.el, but that confused
5183 make-docfile: the documentation string in ns-win.el was used for
5184 x-parse-geometry even in non-NS builds.
5186 With two definitions of x-parse-geometry in this file, various
5187 things still get confused (eg M-x apropos documentation), so that
5188 it is best if the two definitions just share the same doc-string.
5190 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
5191 doc
: /* Parse a display geometry string STRING.
5192 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
5193 The properties returned may include `top', `left', `height', and `width'.
5194 For X, the value of `left' or `top' may be an integer,
5195 or a list (+ N) meaning N pixels relative to top/left corner,
5196 or a list (- N) meaning -N pixels relative to bottom/right corner.
5197 On Nextstep, this just calls `ns-parse-geometry'. */)
5198 (Lisp_Object string
)
5201 unsigned int width
, height
;
5204 CHECK_STRING (string
);
5207 if (strchr (SSDATA (string
), ' ') != NULL
)
5208 return call1 (Qns_parse_geometry
, string
);
5210 geometry
= XParseGeometry (SSDATA (string
),
5211 &x
, &y
, &width
, &height
);
5213 if (geometry
& XValue
)
5215 Lisp_Object element
;
5217 if (x
>= 0 && (geometry
& XNegative
))
5218 element
= list3 (Qleft
, Qminus
, make_number (-x
));
5219 else if (x
< 0 && ! (geometry
& XNegative
))
5220 element
= list3 (Qleft
, Qplus
, make_number (x
));
5222 element
= Fcons (Qleft
, make_number (x
));
5223 result
= Fcons (element
, result
);
5226 if (geometry
& YValue
)
5228 Lisp_Object element
;
5230 if (y
>= 0 && (geometry
& YNegative
))
5231 element
= list3 (Qtop
, Qminus
, make_number (-y
));
5232 else if (y
< 0 && ! (geometry
& YNegative
))
5233 element
= list3 (Qtop
, Qplus
, make_number (y
));
5235 element
= Fcons (Qtop
, make_number (y
));
5236 result
= Fcons (element
, result
);
5239 if (geometry
& WidthValue
)
5240 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
5241 if (geometry
& HeightValue
)
5242 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
5248 /* Calculate the desired size and position of frame F.
5249 Return the flags saying which aspects were specified.
5251 Also set the win_gravity and size_hint_flags of F.
5253 Adjust height for toolbar if TOOLBAR_P is 1.
5255 This function does not make the coordinates positive. */
5257 #define DEFAULT_ROWS 36
5258 #define DEFAULT_COLS 80
5261 x_figure_window_size (struct frame
*f
, Lisp_Object parms
, bool toolbar_p
, int *x_width
, int *x_height
)
5263 Lisp_Object height
, width
, user_size
, top
, left
, user_position
;
5264 long window_prompting
= 0;
5265 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
5266 int parent_done
= -1, outer_done
= -1;
5268 /* Default values if we fall through.
5269 Actually, if that happens we should get
5270 window manager prompting. */
5271 SET_FRAME_WIDTH (f
, DEFAULT_COLS
* FRAME_COLUMN_WIDTH (f
));
5272 SET_FRAME_COLS (f
, DEFAULT_COLS
);
5273 SET_FRAME_HEIGHT (f
, DEFAULT_ROWS
* FRAME_LINE_HEIGHT (f
));
5274 SET_FRAME_LINES (f
, DEFAULT_ROWS
);
5276 /* Window managers expect that if program-specified
5277 positions are not (0,0), they're intentional, not defaults. */
5281 /* Calculate a tool bar height so that the user gets a text display
5282 area of the size he specified with -g or via .Xdefaults. Later
5283 changes of the tool bar height don't change the frame size. This
5284 is done so that users can create tall Emacs frames without having
5285 to guess how tall the tool bar will get. */
5286 if (toolbar_p
&& FRAME_TOOL_BAR_LINES (f
))
5288 if (frame_default_tool_bar_height
)
5289 FRAME_TOOL_BAR_HEIGHT (f
) = frame_default_tool_bar_height
;
5294 relief
= (tool_bar_button_relief
>= 0
5295 ? tool_bar_button_relief
5296 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
5298 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
, INT_MAX
))
5299 margin
= XFASTINT (Vtool_bar_button_margin
);
5300 else if (CONSP (Vtool_bar_button_margin
)
5301 && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
), INT_MAX
))
5302 margin
= XFASTINT (XCDR (Vtool_bar_button_margin
));
5306 FRAME_TOOL_BAR_HEIGHT (f
)
5307 = DEFAULT_TOOL_BAR_IMAGE_HEIGHT
+ 2 * margin
+ 2 * relief
;
5311 /* Ensure that earlier new_width and new_height settings won't
5312 override what we specify below. */
5313 f
->new_width
= f
->new_height
= 0;
5315 height
= x_get_arg (dpyinfo
, parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
5316 width
= x_get_arg (dpyinfo
, parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
5317 if (!EQ (width
, Qunbound
) || !EQ (height
, Qunbound
))
5319 if (!EQ (width
, Qunbound
))
5321 if (CONSP (width
) && EQ (XCAR (width
), Qtext_pixels
))
5323 CHECK_NUMBER (XCDR (width
));
5324 if ((XINT (XCDR (width
)) < 0 || XINT (XCDR (width
)) > INT_MAX
))
5325 xsignal1 (Qargs_out_of_range
, XCDR (width
));
5327 SET_FRAME_WIDTH (f
, XINT (XCDR (width
)));
5328 f
->inhibit_horizontal_resize
= true;
5329 *x_width
= XINT (XCDR (width
));
5331 else if (FLOATP (width
))
5333 double d_width
= XFLOAT_DATA (width
);
5335 if (d_width
< 0.0 || d_width
> 1.0)
5336 xsignal1 (Qargs_out_of_range
, width
);
5339 int new_width
= frame_float (f
, width
, FRAME_FLOAT_WIDTH
,
5340 &parent_done
, &outer_done
, -1);
5343 SET_FRAME_WIDTH (f
, new_width
);
5348 CHECK_NUMBER (width
);
5349 if ((XINT (width
) < 0 || XINT (width
) > INT_MAX
))
5350 xsignal1 (Qargs_out_of_range
, width
);
5352 SET_FRAME_WIDTH (f
, XINT (width
) * FRAME_COLUMN_WIDTH (f
));
5356 if (!EQ (height
, Qunbound
))
5358 if (CONSP (height
) && EQ (XCAR (height
), Qtext_pixels
))
5360 CHECK_NUMBER (XCDR (height
));
5361 if ((XINT (XCDR (height
)) < 0 || XINT (XCDR (height
)) > INT_MAX
))
5362 xsignal1 (Qargs_out_of_range
, XCDR (height
));
5364 SET_FRAME_HEIGHT (f
, XINT (XCDR (height
)));
5365 f
->inhibit_vertical_resize
= true;
5366 *x_height
= XINT (XCDR (height
));
5368 else if (FLOATP (height
))
5370 double d_height
= XFLOAT_DATA (height
);
5372 if (d_height
< 0.0 || d_height
> 1.0)
5373 xsignal1 (Qargs_out_of_range
, height
);
5376 int new_height
= frame_float (f
, height
, FRAME_FLOAT_HEIGHT
,
5377 &parent_done
, &outer_done
, -1);
5379 if (new_height
> -1)
5380 SET_FRAME_HEIGHT (f
, new_height
);
5385 CHECK_NUMBER (height
);
5386 if ((XINT (height
) < 0) || (XINT (height
) > INT_MAX
))
5387 xsignal1 (Qargs_out_of_range
, height
);
5389 SET_FRAME_HEIGHT (f
, XINT (height
) * FRAME_LINE_HEIGHT (f
));
5393 user_size
= x_get_arg (dpyinfo
, parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
5394 if (!NILP (user_size
) && !EQ (user_size
, Qunbound
))
5395 window_prompting
|= USSize
;
5397 window_prompting
|= PSize
;
5400 top
= x_get_arg (dpyinfo
, parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
5401 left
= x_get_arg (dpyinfo
, parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
5402 user_position
= x_get_arg (dpyinfo
, parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
5403 if (! EQ (top
, Qunbound
) || ! EQ (left
, Qunbound
))
5405 if (EQ (top
, Qminus
))
5408 window_prompting
|= YNegative
;
5410 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
5411 && CONSP (XCDR (top
))
5412 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (top
)), INT_MAX
))
5414 f
->top_pos
= - XINT (XCAR (XCDR (top
)));
5415 window_prompting
|= YNegative
;
5417 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
5418 && CONSP (XCDR (top
))
5419 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top
))))
5421 f
->top_pos
= XINT (XCAR (XCDR (top
)));
5423 else if (FLOATP (top
))
5424 f
->top_pos
= frame_float (f
, top
, FRAME_FLOAT_TOP
, &parent_done
,
5426 else if (EQ (top
, Qunbound
))
5430 CHECK_TYPE_RANGED_INTEGER (int, top
);
5431 f
->top_pos
= XINT (top
);
5433 window_prompting
|= YNegative
;
5436 if (EQ (left
, Qminus
))
5439 window_prompting
|= XNegative
;
5441 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
5442 && CONSP (XCDR (left
))
5443 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (left
)), INT_MAX
))
5445 f
->left_pos
= - XINT (XCAR (XCDR (left
)));
5446 window_prompting
|= XNegative
;
5448 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
5449 && CONSP (XCDR (left
))
5450 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left
))))
5452 f
->left_pos
= XINT (XCAR (XCDR (left
)));
5454 else if (FLOATP (left
))
5455 f
->left_pos
= frame_float (f
, left
, FRAME_FLOAT_LEFT
, &parent_done
,
5457 else if (EQ (left
, Qunbound
))
5461 CHECK_TYPE_RANGED_INTEGER (int, left
);
5462 f
->left_pos
= XINT (left
);
5463 if (f
->left_pos
< 0)
5464 window_prompting
|= XNegative
;
5467 if (!NILP (user_position
) && ! EQ (user_position
, Qunbound
))
5468 window_prompting
|= USPosition
;
5470 window_prompting
|= PPosition
;
5473 if (window_prompting
& XNegative
)
5475 if (window_prompting
& YNegative
)
5476 f
->win_gravity
= SouthEastGravity
;
5478 f
->win_gravity
= NorthEastGravity
;
5482 if (window_prompting
& YNegative
)
5483 f
->win_gravity
= SouthWestGravity
;
5485 f
->win_gravity
= NorthWestGravity
;
5488 f
->size_hint_flags
= window_prompting
;
5490 return window_prompting
;
5495 #endif /* HAVE_WINDOW_SYSTEM */
5498 frame_make_pointer_invisible (struct frame
*f
)
5500 if (! NILP (Vmake_pointer_invisible
))
5502 if (f
&& FRAME_LIVE_P (f
) && !f
->pointer_invisible
5503 && FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook
)
5506 FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook (f
, 1);
5507 f
->pointer_invisible
= 1;
5513 frame_make_pointer_visible (struct frame
*f
)
5515 /* We don't check Vmake_pointer_invisible here in case the
5516 pointer was invisible when Vmake_pointer_invisible was set to nil. */
5517 if (f
&& FRAME_LIVE_P (f
) && f
->pointer_invisible
&& f
->mouse_moved
5518 && FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook
)
5520 FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook (f
, 0);
5521 f
->pointer_invisible
= 0;
5525 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p
,
5526 Sframe_pointer_visible_p
, 0, 1, 0,
5527 doc
: /* Return t if the mouse pointer displayed on FRAME is visible.
5528 Otherwise it returns nil. FRAME omitted or nil means the
5529 selected frame. This is useful when `make-pointer-invisible' is set. */)
5532 return decode_any_frame (frame
)->pointer_invisible
? Qnil
: Qt
;
5537 /***********************************************************************
5539 ***********************************************************************/
5541 #ifdef HAVE_WINDOW_SYSTEM
5543 # if (defined HAVE_NS \
5544 || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR)))
5546 free_monitors (struct MonitorInfo
*monitors
, int n_monitors
)
5549 for (i
= 0; i
< n_monitors
; ++i
)
5550 xfree (monitors
[i
].name
);
5556 make_monitor_attribute_list (struct MonitorInfo
*monitors
,
5558 int primary_monitor
,
5559 Lisp_Object monitor_frames
,
5562 Lisp_Object attributes_list
= Qnil
;
5563 Lisp_Object primary_monitor_attributes
= Qnil
;
5566 for (i
= 0; i
< n_monitors
; ++i
)
5568 Lisp_Object geometry
, workarea
, attributes
= Qnil
;
5569 struct MonitorInfo
*mi
= &monitors
[i
];
5571 if (mi
->geom
.width
== 0) continue;
5573 workarea
= list4i (mi
->work
.x
, mi
->work
.y
,
5574 mi
->work
.width
, mi
->work
.height
);
5575 geometry
= list4i (mi
->geom
.x
, mi
->geom
.y
,
5576 mi
->geom
.width
, mi
->geom
.height
);
5577 attributes
= Fcons (Fcons (Qsource
, build_string (source
)),
5579 attributes
= Fcons (Fcons (Qframes
, AREF (monitor_frames
, i
)),
5581 attributes
= Fcons (Fcons (Qmm_size
,
5582 list2i (mi
->mm_width
, mi
->mm_height
)),
5584 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
5585 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
5587 attributes
= Fcons (Fcons (Qname
, make_string (mi
->name
,
5588 strlen (mi
->name
))),
5591 if (i
== primary_monitor
)
5592 primary_monitor_attributes
= attributes
;
5594 attributes_list
= Fcons (attributes
, attributes_list
);
5597 if (!NILP (primary_monitor_attributes
))
5598 attributes_list
= Fcons (primary_monitor_attributes
, attributes_list
);
5599 return attributes_list
;
5602 #endif /* HAVE_WINDOW_SYSTEM */
5605 /***********************************************************************
5607 ***********************************************************************/
5610 syms_of_frame (void)
5612 DEFSYM (Qframep
, "framep");
5613 DEFSYM (Qframe_live_p
, "frame-live-p");
5614 DEFSYM (Qframe_windows_min_size
, "frame-windows-min-size");
5615 DEFSYM (Qdisplay_monitor_attributes_list
, "display-monitor-attributes-list");
5616 DEFSYM (Qwindow__pixel_to_total
, "window--pixel-to-total");
5617 DEFSYM (Qexplicit_name
, "explicit-name");
5618 DEFSYM (Qheight
, "height");
5619 DEFSYM (Qicon
, "icon");
5620 DEFSYM (Qminibuffer
, "minibuffer");
5621 DEFSYM (Qundecorated
, "undecorated");
5622 DEFSYM (Qno_special_glyphs
, "no-special-glyphs");
5623 DEFSYM (Qparent_frame
, "parent-frame");
5624 DEFSYM (Qskip_taskbar
, "skip-taskbar");
5625 DEFSYM (Qno_focus_on_map
, "no-focus-on-map");
5626 DEFSYM (Qno_accept_focus
, "no-accept-focus");
5627 DEFSYM (Qz_group
, "z-group");
5628 DEFSYM (Qoverride_redirect
, "override-redirect");
5629 DEFSYM (Qdelete_before
, "delete-before");
5630 DEFSYM (Qmodeline
, "modeline");
5631 DEFSYM (Qonly
, "only");
5632 DEFSYM (Qnone
, "none");
5633 DEFSYM (Qwidth
, "width");
5634 DEFSYM (Qtext_pixels
, "text-pixels");
5635 DEFSYM (Qgeometry
, "geometry");
5636 DEFSYM (Qicon_left
, "icon-left");
5637 DEFSYM (Qicon_top
, "icon-top");
5638 DEFSYM (Qtooltip
, "tooltip");
5639 DEFSYM (Quser_position
, "user-position");
5640 DEFSYM (Quser_size
, "user-size");
5641 DEFSYM (Qwindow_id
, "window-id");
5642 #ifdef HAVE_X_WINDOWS
5643 DEFSYM (Qouter_window_id
, "outer-window-id");
5645 DEFSYM (Qparent_id
, "parent-id");
5647 DEFSYM (Qw32
, "w32");
5650 DEFSYM (Qvisible
, "visible");
5651 DEFSYM (Qbuffer_predicate
, "buffer-predicate");
5652 DEFSYM (Qbuffer_list
, "buffer-list");
5653 DEFSYM (Qburied_buffer_list
, "buried-buffer-list");
5654 DEFSYM (Qdisplay_type
, "display-type");
5655 DEFSYM (Qbackground_mode
, "background-mode");
5656 DEFSYM (Qnoelisp
, "noelisp");
5657 DEFSYM (Qtty_color_mode
, "tty-color-mode");
5658 DEFSYM (Qtty
, "tty");
5659 DEFSYM (Qtty_type
, "tty-type");
5661 DEFSYM (Qface_set_after_frame_default
, "face-set-after-frame-default");
5663 DEFSYM (Qfullwidth
, "fullwidth");
5664 DEFSYM (Qfullheight
, "fullheight");
5665 DEFSYM (Qfullboth
, "fullboth");
5666 DEFSYM (Qmaximized
, "maximized");
5667 DEFSYM (Qx_resource_name
, "x-resource-name");
5668 DEFSYM (Qx_frame_parameter
, "x-frame-parameter");
5670 DEFSYM (Qworkarea
, "workarea");
5671 DEFSYM (Qmm_size
, "mm-size");
5672 DEFSYM (Qframes
, "frames");
5673 DEFSYM (Qsource
, "source");
5675 DEFSYM (Qframe_edges
, "frame-edges");
5676 DEFSYM (Qouter_edges
, "outer-edges");
5677 DEFSYM (Qouter_position
, "outer-position");
5678 DEFSYM (Qouter_size
, "outer-size");
5679 DEFSYM (Qnative_edges
, "native-edges");
5680 DEFSYM (Qinner_edges
, "inner-edges");
5681 DEFSYM (Qexternal_border_size
, "external-border-size");
5682 DEFSYM (Qtitle_bar_size
, "title-bar-size");
5683 DEFSYM (Qmenu_bar_external
, "menu-bar-external");
5684 DEFSYM (Qmenu_bar_size
, "menu-bar-size");
5685 DEFSYM (Qtool_bar_external
, "tool-bar-external");
5686 DEFSYM (Qtool_bar_size
, "tool-bar-size");
5687 /* The following are used for frame_size_history. */
5688 DEFSYM (Qadjust_frame_size_1
, "adjust-frame-size-1");
5689 DEFSYM (Qadjust_frame_size_2
, "adjust-frame-size-2");
5690 DEFSYM (Qadjust_frame_size_3
, "adjust-frame-size-3");
5691 DEFSYM (Qx_set_frame_parameters
, "x-set-frame-parameters");
5692 DEFSYM (QEmacsFrameResize
, "EmacsFrameResize");
5693 DEFSYM (Qset_frame_size
, "set-frame-size");
5694 DEFSYM (Qframe_inhibit_resize
, "frame-inhibit-resize");
5695 DEFSYM (Qx_set_fullscreen
, "x-set-fullscreen");
5696 DEFSYM (Qx_check_fullscreen
, "x-check-fullscreen");
5697 DEFSYM (Qxg_frame_resized
, "xg-frame-resized");
5698 DEFSYM (Qxg_frame_set_char_size_1
, "xg-frame-set-char-size-1");
5699 DEFSYM (Qxg_frame_set_char_size_2
, "xg-frame-set-char-size-2");
5700 DEFSYM (Qxg_frame_set_char_size_3
, "xg-frame-set-char-size-3");
5701 DEFSYM (Qx_set_window_size_1
, "x-set-window-size-1");
5702 DEFSYM (Qx_set_window_size_2
, "x-set-window-size-2");
5703 DEFSYM (Qx_set_window_size_3
, "x-set-window-size-3");
5704 DEFSYM (Qxg_change_toolbar_position
, "xg-change-toolbar-position");
5705 DEFSYM (Qx_net_wm_state
, "x-net-wm-state");
5706 DEFSYM (Qx_handle_net_wm_state
, "x-handle-net-wm-state");
5707 DEFSYM (Qtb_size_cb
, "tb-size-cb");
5708 DEFSYM (Qupdate_frame_tool_bar
, "update-frame-tool-bar");
5709 DEFSYM (Qfree_frame_tool_bar
, "free-frame-tool-bar");
5710 DEFSYM (Qx_set_menu_bar_lines
, "x-set-menu-bar-lines");
5711 DEFSYM (Qchange_frame_size
, "change-frame-size");
5712 DEFSYM (Qxg_frame_set_char_size
, "xg-frame-set-char-size");
5713 DEFSYM (Qset_window_configuration
, "set-window-configuration");
5714 DEFSYM (Qx_create_frame_1
, "x-create-frame-1");
5715 DEFSYM (Qx_create_frame_2
, "x-create-frame-2");
5716 DEFSYM (Qterminal_frame
, "terminal-frame");
5719 DEFSYM (Qns_parse_geometry
, "ns-parse-geometry");
5721 #ifdef NS_IMPL_COCOA
5722 DEFSYM (Qns_appearance
, "ns-appearance");
5723 DEFSYM (Qns_transparent_titlebar
, "ns-transparent-titlebar");
5726 DEFSYM (Qalpha
, "alpha");
5727 DEFSYM (Qauto_lower
, "auto-lower");
5728 DEFSYM (Qauto_raise
, "auto-raise");
5729 DEFSYM (Qborder_color
, "border-color");
5730 DEFSYM (Qborder_width
, "border-width");
5731 DEFSYM (Qouter_border_width
, "outer-border-width");
5732 DEFSYM (Qbottom_divider_width
, "bottom-divider-width");
5733 DEFSYM (Qcursor_color
, "cursor-color");
5734 DEFSYM (Qcursor_type
, "cursor-type");
5735 DEFSYM (Qfont_backend
, "font-backend");
5736 DEFSYM (Qfullscreen
, "fullscreen");
5737 DEFSYM (Qhorizontal_scroll_bars
, "horizontal-scroll-bars");
5738 DEFSYM (Qicon_name
, "icon-name");
5739 DEFSYM (Qicon_type
, "icon-type");
5740 DEFSYM (Qinternal_border_width
, "internal-border-width");
5741 DEFSYM (Qleft_fringe
, "left-fringe");
5742 DEFSYM (Qline_spacing
, "line-spacing");
5743 DEFSYM (Qmenu_bar_lines
, "menu-bar-lines");
5744 DEFSYM (Qupdate_frame_menubar
, "update-frame-menubar");
5745 DEFSYM (Qfree_frame_menubar_1
, "free-frame-menubar-1");
5746 DEFSYM (Qfree_frame_menubar_2
, "free-frame-menubar-2");
5747 DEFSYM (Qmouse_color
, "mouse-color");
5748 DEFSYM (Qname
, "name");
5749 DEFSYM (Qright_divider_width
, "right-divider-width");
5750 DEFSYM (Qright_fringe
, "right-fringe");
5751 DEFSYM (Qscreen_gamma
, "screen-gamma");
5752 DEFSYM (Qscroll_bar_background
, "scroll-bar-background");
5753 DEFSYM (Qscroll_bar_foreground
, "scroll-bar-foreground");
5754 DEFSYM (Qscroll_bar_height
, "scroll-bar-height");
5755 DEFSYM (Qscroll_bar_width
, "scroll-bar-width");
5756 DEFSYM (Qsticky
, "sticky");
5757 DEFSYM (Qtitle
, "title");
5758 DEFSYM (Qtool_bar_lines
, "tool-bar-lines");
5759 DEFSYM (Qtool_bar_position
, "tool-bar-position");
5760 DEFSYM (Qunsplittable
, "unsplittable");
5761 DEFSYM (Qvertical_scroll_bars
, "vertical-scroll-bars");
5762 DEFSYM (Qvisibility
, "visibility");
5763 DEFSYM (Qwait_for_wm
, "wait-for-wm");
5764 DEFSYM (Qinhibit_double_buffering
, "inhibit-double-buffering");
5765 DEFSYM (Qno_other_frame
, "no-other-frame");
5766 DEFSYM (Qbelow
, "below");
5767 DEFSYM (Qabove_suspended
, "above-suspended");
5768 DEFSYM (Qmin_width
, "min-width");
5769 DEFSYM (Qmin_height
, "min-height");
5770 DEFSYM (Qmouse_wheel_frame
, "mouse-wheel-frame");
5771 DEFSYM (Qkeep_ratio
, "keep-ratio");
5772 DEFSYM (Qwidth_only
, "width-only");
5773 DEFSYM (Qheight_only
, "height-only");
5774 DEFSYM (Qleft_only
, "left-only");
5775 DEFSYM (Qtop_only
, "top-only");
5776 DEFSYM (Qiconify_top_level
, "iconify-top-level");
5777 DEFSYM (Qmake_invisible
, "make-invisible");
5782 for (i
= 0; i
< ARRAYELTS (frame_parms
); i
++)
5784 Lisp_Object v
= (frame_parms
[i
].sym
< 0
5785 ? intern_c_string (frame_parms
[i
].name
)
5786 : builtin_lisp_symbol (frame_parms
[i
].sym
));
5787 Fput (v
, Qx_frame_parameter
, make_number (i
));
5791 #ifdef HAVE_WINDOW_SYSTEM
5792 DEFVAR_LISP ("x-resource-name", Vx_resource_name
,
5793 doc
: /* The name Emacs uses to look up X resources.
5794 `x-get-resource' uses this as the first component of the instance name
5795 when requesting resource values.
5796 Emacs initially sets `x-resource-name' to the name under which Emacs
5797 was invoked, or to the value specified with the `-name' or `-rn'
5798 switches, if present.
5800 It may be useful to bind this variable locally around a call
5801 to `x-get-resource'. See also the variable `x-resource-class'. */);
5802 Vx_resource_name
= Qnil
;
5804 DEFVAR_LISP ("x-resource-class", Vx_resource_class
,
5805 doc
: /* The class Emacs uses to look up X resources.
5806 `x-get-resource' uses this as the first component of the instance class
5807 when requesting resource values.
5809 Emacs initially sets `x-resource-class' to "Emacs".
5811 Setting this variable permanently is not a reasonable thing to do,
5812 but binding this variable locally around a call to `x-get-resource'
5813 is a reasonable practice. See also the variable `x-resource-name'. */);
5814 Vx_resource_class
= build_string (EMACS_CLASS
);
5816 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit
,
5817 doc
: /* The lower limit of the frame opacity (alpha transparency).
5818 The value should range from 0 (invisible) to 100 (completely opaque).
5819 You can also use a floating number between 0.0 and 1.0. */);
5820 Vframe_alpha_lower_limit
= make_number (20);
5823 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist
,
5824 doc
: /* Alist of default values for frame creation.
5825 These may be set in your init file, like this:
5826 (setq default-frame-alist \\='((width . 80) (height . 55) (menu-bar-lines . 1)))
5827 These override values given in window system configuration data,
5828 including X Windows' defaults database.
5829 For values specific to the first Emacs frame, see `initial-frame-alist'.
5830 For window-system specific values, see `window-system-default-frame-alist'.
5831 For values specific to the separate minibuffer frame, see
5832 `minibuffer-frame-alist'.
5833 The `menu-bar-lines' element of the list controls whether new frames
5834 have menu bars; `menu-bar-mode' works by altering this element.
5835 Setting this variable does not affect existing frames, only new ones. */);
5836 Vdefault_frame_alist
= Qnil
;
5838 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars
,
5839 doc
: /* Default position of vertical scroll bars on this window-system. */);
5840 #ifdef HAVE_WINDOW_SYSTEM
5841 #if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
5842 /* MS-Windows, macOS, and GTK have scroll bars on the right by
5844 Vdefault_frame_scroll_bars
= Qright
;
5846 Vdefault_frame_scroll_bars
= Qleft
;
5849 Vdefault_frame_scroll_bars
= Qnil
;
5852 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
5853 scroll_bar_adjust_thumb_portion_p
,
5854 doc
: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
5855 Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards
5856 even if the end of the buffer is shown (i.e. overscrolling).
5857 Set to nil if you want the thumb to be at the bottom when the end of the buffer
5858 is shown. Also, the thumb fills the whole scroll bar when the entire buffer
5859 is visible. In this case you can not overscroll. */);
5860 scroll_bar_adjust_thumb_portion_p
= 1;
5862 DEFVAR_LISP ("terminal-frame", Vterminal_frame
,
5863 doc
: /* The initial frame-object, which represents Emacs's stdout. */);
5865 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function
,
5866 doc
: /* If non-nil, function to transform normal value of `mouse-position'.
5867 `mouse-position' and `mouse-pixel-position' call this function, passing their
5868 usual return value as argument, and return whatever this function returns.
5869 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
5870 which need to do mouse handling at the Lisp level. */);
5871 Vmouse_position_function
= Qnil
;
5873 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight
,
5874 doc
: /* If non-nil, clickable text is highlighted when mouse is over it.
5875 If the value is an integer, highlighting is only shown after moving the
5876 mouse, while keyboard input turns off the highlight even when the mouse
5877 is over the clickable text. However, the mouse shape still indicates
5878 when the mouse is over clickable text. */);
5879 Vmouse_highlight
= Qt
;
5881 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible
,
5882 doc
: /* If non-nil, make pointer invisible while typing.
5883 The pointer becomes visible again when the mouse is moved. */);
5884 Vmake_pointer_invisible
= Qt
;
5886 DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions
,
5887 doc
: /* Functions run after a frame was moved.
5888 The functions are run with one arg, the frame that moved. */);
5889 Vmove_frame_functions
= Qnil
;
5891 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions
,
5892 doc
: /* Functions run before deleting a frame.
5893 The functions are run with one arg, the frame to be deleted.
5896 Note that functions in this list may be called just before the frame is
5897 actually deleted, or some time later (or even both when an earlier function
5898 in `delete-frame-functions' (indirectly) calls `delete-frame'
5900 Vdelete_frame_functions
= Qnil
;
5901 DEFSYM (Qdelete_frame_functions
, "delete-frame-functions");
5903 DEFVAR_LISP ("after-delete-frame-functions",
5904 Vafter_delete_frame_functions
,
5905 doc
: /* Functions run after deleting a frame.
5906 The functions are run with one arg, the frame that was deleted and
5907 which is now dead. */);
5908 Vafter_delete_frame_functions
= Qnil
;
5909 DEFSYM (Qafter_delete_frame_functions
, "after-delete-frame-functions");
5911 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode
,
5912 doc
: /* Non-nil if Menu-Bar mode is enabled.
5913 See the command `menu-bar-mode' for a description of this minor mode.
5914 Setting this variable directly does not take effect;
5915 either customize it (see the info node `Easy Customization')
5916 or call the function `menu-bar-mode'. */);
5917 Vmenu_bar_mode
= Qt
;
5919 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode
,
5920 doc
: /* Non-nil if Tool-Bar mode is enabled.
5921 See the command `tool-bar-mode' for a description of this minor mode.
5922 Setting this variable directly does not take effect;
5923 either customize it (see the info node `Easy Customization')
5924 or call the function `tool-bar-mode'. */);
5925 #ifdef HAVE_WINDOW_SYSTEM
5926 Vtool_bar_mode
= Qt
;
5928 Vtool_bar_mode
= Qnil
;
5931 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame
,
5932 doc
: /* Minibuffer-less frames by default use this frame's minibuffer.
5933 Emacs consults this variable only when creating a minibuffer-less frame
5934 and no explicit minibuffer window has been specified for that frame via
5935 the `minibuffer' frame parameter. Once such a frame has been created,
5936 setting this variable does not change that frame's previous association.
5938 This variable is local to the current terminal and cannot be buffer-local. */);
5940 DEFVAR_LISP ("focus-follows-mouse", focus_follows_mouse
,
5941 doc
: /* Non-nil if window system changes focus when you move the mouse.
5942 You should set this variable to tell Emacs how your window manager
5943 handles focus, since there is no way in general for Emacs to find out
5946 There are three meaningful values:
5948 - The default nil should be used when your window manager follows a
5949 "click-to-focus" policy where you have to click the mouse inside of a
5950 frame in order for that frame to get focus.
5952 - The value t should be used when your window manager has the focus
5953 automatically follow the position of the mouse pointer but a window
5954 that gains focus is not raised automatically.
5956 - The value `auto-raise' should be used when your window manager has the
5957 focus automatically follow the position of the mouse pointer and a
5958 window that gains focus is raised automatically.
5960 If this option is non-nil, Emacs moves the mouse pointer to the frame
5961 selected by `select-frame-set-input-focus'. This function is used by a
5962 number of commands like, for example, `other-frame' and `pop-to-buffer'.
5963 If this option is nil and your focus follows mouse window manager does
5964 not autonomously move the mouse pointer to the newly selected frame, the
5965 previously selected window manager window might get reselected instead
5968 The distinction between the values t and `auto-raise' is not needed for
5969 "normal" frames because the window manager takes care of raising them.
5970 Setting this to `auto-raise' will, however, override the standard
5971 behavior of a window manager that does not automatically raise the frame
5972 that gets focus. Setting this to `auto-raise' is also necessary to
5973 automatically raise child frames which are usually left alone by the
5976 Note that this option does not distinguish "sloppy" focus (where the
5977 frame that previously had focus retains focus as long as the mouse
5978 pointer does not move into another window manager window) from "strict"
5979 focus (where a frame immediately loses focus when it's left by the mouse
5982 In order to extend a "focus follows mouse" policy to individual Emacs
5983 windows, customize the variable `mouse-autoselect-window'. */);
5984 focus_follows_mouse
= Qnil
;
5986 DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise
,
5987 doc
: /* Non-nil means resize frames pixelwise.
5988 If this option is nil, resizing a frame rounds its sizes to the frame's
5989 current values of `frame-char-height' and `frame-char-width'. If this
5990 is non-nil, no rounding occurs, hence frame sizes can increase/decrease
5993 With some window managers you may have to set this to non-nil in order
5994 to set the size of a frame in pixels, to maximize frames or to make them
5995 fullscreen. To resize your initial frame pixelwise, set this option to
5996 a non-nil value in your init file. */);
5997 frame_resize_pixelwise
= 0;
5999 DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize
,
6000 doc
: /* Whether frames should be resized implicitly.
6001 If this option is nil, setting font, menu bar, tool bar, internal
6002 borders, fringes or scroll bars of a specific frame may resize the frame
6003 in order to preserve the number of columns or lines it displays. If
6004 this option is t, no such resizing is done. Note that the size of
6005 fullscreen and maximized frames, the height of fullheight frames and the
6006 width of fullwidth frames never change implicitly.
6008 The value of this option can be also be a list of frame parameters. In
6009 this case, resizing is inhibited when changing a parameter that appears
6010 in that list. The parameters currently handled by this option include
6011 `font', `font-backend', `internal-border-width', `menu-bar-lines' and
6014 Changing any of the parameters `scroll-bar-width', `scroll-bar-height',
6015 `vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and
6016 `right-fringe' is handled as if the frame contained just one live
6017 window. This means, for example, that removing vertical scroll bars on
6018 a frame containing several side by side windows will shrink the frame
6019 width by the width of one scroll bar provided this option is nil and
6020 keep it unchanged if this option is either t or a list containing
6021 `vertical-scroll-bars'.
6023 The default value is \\='(tool-bar-lines) on Lucid, Motif and Windows
6024 \(which means that adding/removing a tool bar does not change the frame
6025 height), nil on all other window systems including GTK+ (which means
6026 that changing any of the parameters listed above may change the size of
6027 the frame), and t otherwise (which means the frame size never changes
6028 implicitly when there's no window system support).
6030 Note that when a frame is not large enough to accommodate a change of
6031 any of the parameters listed above, Emacs may try to enlarge the frame
6032 even if this option is non-nil. */);
6033 #if defined (HAVE_WINDOW_SYSTEM)
6034 #if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI)
6035 frame_inhibit_implied_resize
= list1 (Qtool_bar_lines
);
6037 frame_inhibit_implied_resize
= Qnil
;
6040 frame_inhibit_implied_resize
= Qt
;
6043 DEFVAR_LISP ("frame-size-history", frame_size_history
,
6044 doc
: /* History of frame size adjustments.
6045 If non-nil, list recording frame size adjustment. Adjustments are
6046 recorded only if the first element of this list is a positive number.
6047 Adding an adjustment decrements that number by one.
6049 The remaining elements are the adjustments. Each adjustment is a list
6050 of four elements `frame', `function', `sizes' and `more'. `frame' is
6051 the affected frame and `function' the invoking function. `sizes' is
6052 usually a list of four elements `old-width', `old-height', `new-width'
6053 and `new-height' representing the old and new sizes recorded/requested
6054 by `function'. `more' is a list with additional information.
6056 The function `frame--size-history' displays the value of this variable
6057 in a more readable form. */);
6058 frame_size_history
= Qnil
;
6060 DEFVAR_BOOL ("tooltip-reuse-hidden-frame", tooltip_reuse_hidden_frame
,
6061 doc
: /* Non-nil means reuse hidden tooltip frames.
6062 When this is nil, delete a tooltip frame when hiding the associated
6063 tooltip. When this is non-nil, make the tooltip frame invisible only,
6064 so it can be reused when the next tooltip is shown.
6066 Setting this to non-nil may drastically reduce the consing overhead
6067 incurred by creating new tooltip frames. However, a value of non-nil
6068 means also that intermittent changes of faces or `default-frame-alist'
6069 are not applied when showing a tooltip in a reused frame.
6071 This variable is effective only with the X toolkit (and there only when
6072 Gtk+ tooltips are not used) and on Windows. */);
6073 tooltip_reuse_hidden_frame
= false;
6075 DEFVAR_LISP ("iconify-child-frame", iconify_child_frame
,
6076 doc
: /* How to handle iconification of child frames.
6077 This variable tells Emacs how to proceed when it is asked to iconify a
6078 child frame. If it is nil, `iconify-frame' will do nothing when invoked
6079 on a child frame. If it is `iconify-top-level', Emacs will try to
6080 iconify the top level frame associated with this child frame instead.
6081 If it is `make-invisible', Emacs will try to make this child frame
6084 Any other value means to try iconifying the child frame. Since such an
6085 attempt is not honored by all window managers and may even lead to
6086 making the child frame unresponsive to user actions, the default is to
6087 iconify the top level frame instead. */);
6088 iconify_child_frame
= Qiconify_top_level
;
6090 staticpro (&Vframe_list
);
6093 defsubr (&Sframe_live_p
);
6094 defsubr (&Swindow_system
);
6095 defsubr (&Sframe_windows_min_size
);
6096 defsubr (&Smake_terminal_frame
);
6097 defsubr (&Shandle_switch_frame
);
6098 defsubr (&Sselect_frame
);
6099 defsubr (&Sselected_frame
);
6100 defsubr (&Sframe_list
);
6101 defsubr (&Sframe_parent
);
6102 defsubr (&Sframe_ancestor_p
);
6103 defsubr (&Snext_frame
);
6104 defsubr (&Sprevious_frame
);
6105 defsubr (&Slast_nonminibuf_frame
);
6106 defsubr (&Sdelete_frame
);
6107 defsubr (&Smouse_position
);
6108 defsubr (&Smouse_pixel_position
);
6109 defsubr (&Sset_mouse_position
);
6110 defsubr (&Sset_mouse_pixel_position
);
6112 defsubr (&Sframe_configuration
);
6113 defsubr (&Srestore_frame_configuration
);
6115 defsubr (&Smake_frame_visible
);
6116 defsubr (&Smake_frame_invisible
);
6117 defsubr (&Siconify_frame
);
6118 defsubr (&Sframe_visible_p
);
6119 defsubr (&Svisible_frame_list
);
6120 defsubr (&Sraise_frame
);
6121 defsubr (&Slower_frame
);
6122 defsubr (&Sx_focus_frame
);
6123 defsubr (&Sframe_after_make_frame
);
6124 defsubr (&Sredirect_frame_focus
);
6125 defsubr (&Sframe_focus
);
6126 defsubr (&Sframe_parameters
);
6127 defsubr (&Sframe_parameter
);
6128 defsubr (&Smodify_frame_parameters
);
6129 defsubr (&Sframe_char_height
);
6130 defsubr (&Sframe_char_width
);
6131 defsubr (&Sframe_native_height
);
6132 defsubr (&Sframe_native_width
);
6133 defsubr (&Sframe_text_cols
);
6134 defsubr (&Sframe_text_lines
);
6135 defsubr (&Sframe_total_cols
);
6136 defsubr (&Sframe_total_lines
);
6137 defsubr (&Sframe_text_width
);
6138 defsubr (&Sframe_text_height
);
6139 defsubr (&Sscroll_bar_width
);
6140 defsubr (&Sscroll_bar_height
);
6141 defsubr (&Sfringe_width
);
6142 defsubr (&Sframe_internal_border_width
);
6143 defsubr (&Sright_divider_width
);
6144 defsubr (&Sbottom_divider_width
);
6145 defsubr (&Stool_bar_pixel_width
);
6146 defsubr (&Sset_frame_height
);
6147 defsubr (&Sset_frame_width
);
6148 defsubr (&Sset_frame_size
);
6149 defsubr (&Sframe_position
);
6150 defsubr (&Sset_frame_position
);
6151 defsubr (&Sframe_pointer_visible_p
);
6153 #ifdef HAVE_WINDOW_SYSTEM
6154 defsubr (&Sx_get_resource
);
6155 defsubr (&Sx_parse_geometry
);