1 /* Generic frame functions.
3 Copyright (C) 1993-1995, 1997, 1999-2014 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29 #include "character.h"
31 #ifdef HAVE_WINDOW_SYSTEM
33 #endif /* HAVE_WINDOW_SYSTEM */
36 /* These help us bind and responding to switch-frame events. */
40 #include "blockinput.h"
42 #include "termhooks.h"
43 #include "dispextern.h"
46 #ifdef HAVE_WINDOW_SYSTEM
59 Lisp_Object Qns_parse_geometry
;
62 Lisp_Object Qframep
, Qframe_live_p
;
63 Lisp_Object Qicon
, Qmodeline
;
64 Lisp_Object Qonly
, Qnone
;
65 Lisp_Object Qx
, Qw32
, Qpc
, Qns
;
67 Lisp_Object Qdisplay_type
;
68 static Lisp_Object Qbackground_mode
;
71 static Lisp_Object Qx_frame_parameter
;
72 Lisp_Object Qx_resource_name
;
73 Lisp_Object Qterminal
;
75 /* Frame parameters (set or reported). */
77 Lisp_Object Qauto_raise
, Qauto_lower
;
78 Lisp_Object Qborder_color
, Qborder_width
;
79 Lisp_Object Qcursor_color
, Qcursor_type
;
80 Lisp_Object Qheight
, Qwidth
;
81 Lisp_Object Qicon_left
, Qicon_top
, Qicon_type
, Qicon_name
;
83 Lisp_Object Qinternal_border_width
;
84 Lisp_Object Qright_divider_width
, Qbottom_divider_width
;
85 Lisp_Object Qmouse_color
;
86 Lisp_Object Qminibuffer
;
87 Lisp_Object Qscroll_bar_width
, Qvertical_scroll_bars
;
88 Lisp_Object Qscroll_bar_height
, Qhorizontal_scroll_bars
;
89 Lisp_Object Qvisibility
;
90 Lisp_Object Qscroll_bar_foreground
, Qscroll_bar_background
;
91 Lisp_Object Qscreen_gamma
;
92 Lisp_Object Qline_spacing
;
93 static Lisp_Object Quser_position
, Quser_size
;
94 Lisp_Object Qwait_for_wm
;
95 static Lisp_Object Qwindow_id
;
97 static Lisp_Object Qouter_window_id
;
99 Lisp_Object Qparent_id
;
100 Lisp_Object Qtitle
, Qname
;
101 static Lisp_Object Qexplicit_name
;
102 Lisp_Object Qunsplittable
;
103 Lisp_Object Qmenu_bar_lines
, Qtool_bar_lines
, Qtool_bar_position
;
104 Lisp_Object Qleft_fringe
, Qright_fringe
;
105 Lisp_Object Qbuffer_predicate
;
106 static Lisp_Object Qbuffer_list
, Qburied_buffer_list
;
107 Lisp_Object Qtty_color_mode
;
108 Lisp_Object Qtty
, Qtty_type
;
110 Lisp_Object Qfullscreen
, Qfullwidth
, Qfullheight
, Qfullboth
, Qmaximized
;
112 Lisp_Object Qfont_backend
;
115 Lisp_Object Qface_set_after_frame_default
;
117 static Lisp_Object Qfocus_in_hook
;
118 static Lisp_Object Qfocus_out_hook
;
119 static Lisp_Object Qdelete_frame_functions
;
120 static Lisp_Object Qframe_windows_min_size
;
121 static Lisp_Object Qgeometry
, Qworkarea
, Qmm_size
, Qframes
, Qsource
;
123 Lisp_Object Qframe_position
, Qframe_outer_size
, Qframe_inner_size
;
124 Lisp_Object Qexternal_border_size
, Qtitle_height
;
125 Lisp_Object Qmenu_bar_external
, Qmenu_bar_size
;
126 Lisp_Object Qtool_bar_external
, Qtool_bar_size
;
128 /* The currently selected frame. */
130 Lisp_Object selected_frame
;
132 /* A frame which is not just a mini-buffer, or NULL if there are no such
133 frames. This is usually the most recent such frame that was selected. */
135 static struct frame
*last_nonminibuf_frame
;
137 /* False means there are no visible garbaged frames. */
140 #ifdef HAVE_WINDOW_SYSTEM
141 static void x_report_frame_params (struct frame
*, Lisp_Object
*);
144 /* These setters are used only in this file, so they can be private. */
146 fset_buffer_predicate (struct frame
*f
, Lisp_Object val
)
148 f
->buffer_predicate
= val
;
151 fset_minibuffer_window (struct frame
*f
, Lisp_Object val
)
153 f
->minibuffer_window
= val
;
157 decode_live_frame (register Lisp_Object frame
)
160 frame
= selected_frame
;
161 CHECK_LIVE_FRAME (frame
);
162 return XFRAME (frame
);
166 decode_any_frame (register Lisp_Object frame
)
169 frame
= selected_frame
;
171 return XFRAME (frame
);
174 #ifdef HAVE_WINDOW_SYSTEM
177 window_system_available (struct frame
*f
)
179 return f
? FRAME_WINDOW_P (f
) || FRAME_MSDOS_P (f
) : x_display_list
!= NULL
;
182 #endif /* HAVE_WINDOW_SYSTEM */
185 decode_window_system_frame (Lisp_Object frame
)
187 struct frame
*f
= decode_live_frame (frame
);
189 if (!window_system_available (f
))
190 error ("Window system frame should be used");
195 check_window_system (struct frame
*f
)
197 if (!window_system_available (f
))
198 error (f
? "Window system frame should be used"
199 : "Window system is not in use or not initialized");
202 /* Return the value of frame parameter PROP in frame FRAME. */
205 get_frame_param (register struct frame
*frame
, Lisp_Object prop
)
207 register Lisp_Object tem
;
209 tem
= Fassq (prop
, frame
->param_alist
);
215 /* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
216 state of frame F would be affected by a vertical (horizontal if
217 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
218 parameter that is changed. */
220 frame_inhibit_resize (struct frame
*f
, bool horizontal
, Lisp_Object parameter
)
222 return (EQ (frame_inhibit_implied_resize
, Qt
)
223 || (CONSP (frame_inhibit_implied_resize
)
224 && !NILP (Fmemq (parameter
, frame_inhibit_implied_resize
)))
225 || !NILP (get_frame_param (f
, Qfullscreen
))
226 || FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
));
230 set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
233 int olines
= FRAME_MENU_BAR_LINES (f
);
235 /* Right now, menu bars don't work properly in minibuf-only frames;
236 most of the commands try to apply themselves to the minibuffer
237 frame itself, and get an error because you can't switch buffers
238 in or split the minibuffer window. */
239 if (FRAME_MINIBUF_ONLY_P (f
))
242 if (TYPE_RANGED_INTEGERP (int, value
))
243 nlines
= XINT (value
);
247 if (nlines
!= olines
)
249 windows_or_buffers_changed
= 14;
250 FRAME_MENU_BAR_LINES (f
) = nlines
;
251 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
252 change_frame_size (f
, FRAME_COLS (f
),
253 FRAME_LINES (f
) + olines
- nlines
,
258 Lisp_Object Vframe_list
;
261 DEFUN ("framep", Fframep
, Sframep
, 1, 1, 0,
262 doc
: /* Return non-nil if OBJECT is a frame.
264 t for a termcap frame (a character-only terminal),
265 'x' for an Emacs frame that is really an X window,
266 'w32' for an Emacs frame that is a window on MS-Windows display,
267 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
268 'pc' for a direct-write MS-DOS frame.
269 See also `frame-live-p'. */)
272 if (!FRAMEP (object
))
274 switch (XFRAME (object
)->output_method
)
276 case output_initial
: /* The initial frame is like a termcap frame. */
279 case output_x_window
:
283 case output_msdos_raw
:
292 DEFUN ("frame-live-p", Fframe_live_p
, Sframe_live_p
, 1, 1, 0,
293 doc
: /* Return non-nil if OBJECT is a frame which has not been deleted.
294 Value is nil if OBJECT is not a live frame. If object is a live
295 frame, the return value indicates what sort of terminal device it is
296 displayed on. See the documentation of `framep' for possible
300 return ((FRAMEP (object
)
301 && FRAME_LIVE_P (XFRAME (object
)))
306 DEFUN ("window-system", Fwindow_system
, Swindow_system
, 0, 1, 0,
307 doc
: /* The name of the window system that FRAME is displaying through.
308 The value is a symbol:
309 nil for a termcap frame (a character-only terminal),
310 'x' for an Emacs frame that is really an X window,
311 'w32' for an Emacs frame that is a window on MS-Windows display,
312 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
313 'pc' for a direct-write MS-DOS frame.
315 FRAME defaults to the currently selected frame.
317 Use of this function as a predicate is deprecated. Instead,
318 use `display-graphic-p' or any of the other `display-*-p'
319 predicates which report frame's specific UI-related capabilities. */)
324 frame
= selected_frame
;
326 type
= Fframep (frame
);
329 wrong_type_argument (Qframep
, frame
);
338 frame_windows_min_size (Lisp_Object frame
, Lisp_Object horizontal
, Lisp_Object pixelwise
)
340 return XINT (call3 (Qframe_windows_min_size
, frame
, horizontal
, pixelwise
));
344 /* Make sure windows sizes of frame F are OK. new_width and new_height
345 are in pixels. A value of -1 means no change is requested for that
346 size (but the frame may still have to be resized to accommodate
347 windows with their minimum sizes). This can either issue a request
348 to resize the frame externally (via x_set_window_size), to resize the
349 frame internally (via resize_frame_windows) or do nothing at all.
351 The argument INHIBIT can assume the following values:
353 0 means to unconditionally call x_set_window_size even if sizes
354 apparently do not change. Fx_create_frame uses this to pass the
355 initial size to the window manager.
357 1 means to call x_set_window_size if the outer frame size really
358 changes. Fset_frame_size, Fset_frame_height, ... use this.
360 2 means to call x_set_window_size provided frame_inhibit_resize
361 allows it. The menu and tool bar code use this ("3" won't work
362 here in general because menu and tool bar are often not counted in
363 the frame's text height).
365 3 means call x_set_window_size if window minimum sizes must be
366 preserved or frame_inhibit_resize allows it. x_set_left_fringe,
367 x_set_scroll_bar_width, x_new_font ... use (or should use) this.
369 4 means call x_set_window_size only if window minimum sizes must be
370 preserved. x_set_right_divider_width, x_set_border_width and the
371 code responsible for wrapping the tool bar use this.
373 5 means to never call x_set_window_size. change_frame_size uses
376 Note that even when x_set_window_size is not called, individual
377 windows may have to be resized (via `window--sanitize-window-sizes')
378 in order to support minimum size constraints.
380 PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
381 symbol of the parameter changed (like `menu-bar-lines', `font', ...).
382 This is passed on to frame_inhibit_resize to let the latter decide on
383 a case-by-case basis whether the frame may be resized externally. */
385 adjust_frame_size (struct frame
*f
, int new_width
, int new_height
, int inhibit
,
386 bool pretend
, Lisp_Object parameter
)
388 int unit_width
= FRAME_COLUMN_WIDTH (f
);
389 int unit_height
= FRAME_LINE_HEIGHT (f
);
390 int old_pixel_width
= FRAME_PIXEL_WIDTH (f
);
391 int old_pixel_height
= FRAME_PIXEL_HEIGHT (f
);
392 int new_pixel_width
, new_pixel_height
;
393 /* The following two values are calculated from the old frame pixel
394 sizes and any "new" settings for tool bar, menu bar and internal
395 borders. We do it this way to detect whether we have to call
396 x_set_window_size as consequence of the new settings. */
397 int windows_width
= FRAME_WINDOWS_WIDTH (f
);
398 int windows_height
= FRAME_WINDOWS_HEIGHT (f
);
399 int min_windows_width
, min_windows_height
;
400 /* These are a bit tedious, maybe we should use a macro. */
401 struct window
*r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
402 int old_windows_width
= WINDOW_PIXEL_WIDTH (r
);
403 int old_windows_height
404 = (WINDOW_PIXEL_HEIGHT (r
)
405 + (FRAME_HAS_MINIBUF_P (f
)
406 ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f
)))
408 int new_windows_width
, new_windows_height
;
409 int old_text_width
= FRAME_TEXT_WIDTH (f
);
410 int old_text_height
= FRAME_TEXT_HEIGHT (f
);
411 /* If a size is < 0 use the old value. */
412 int new_text_width
= (new_width
>= 0) ? new_width
: old_text_width
;
413 int new_text_height
= (new_height
>= 0) ? new_height
: old_text_height
;
414 int new_cols
, new_lines
;
415 bool inhibit_horizontal
, inhibit_vertical
;
418 XSETFRAME (frame
, f
);
419 /* The following two values are calculated from the old window body
420 sizes and any "new" settings for scroll bars, dividers, fringes and
421 margins (though the latter should have been processed already). */
422 min_windows_width
= frame_windows_min_size (frame
, Qt
, Qt
);
423 min_windows_height
= frame_windows_min_size (frame
, Qnil
, Qt
);
425 if (inhibit
>= 2 && inhibit
<= 4)
426 /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay
427 within the limits and either frame_inhibit_resize tells us to do
428 so or INHIBIT equals 4. */
430 inhibit_horizontal
= ((windows_width
>= min_windows_width
432 || frame_inhibit_resize (f
, true, parameter
)))
434 inhibit_vertical
= ((windows_height
>= min_windows_height
436 || frame_inhibit_resize (f
, false, parameter
)))
440 /* Otherwise inhibit if INHIBIT equals 5. */
441 inhibit_horizontal
= inhibit_vertical
= inhibit
== 5;
443 new_pixel_width
= ((inhibit_horizontal
&& (inhibit
< 5))
445 : max (FRAME_TEXT_TO_PIXEL_WIDTH (f
, new_text_width
),
447 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)));
448 new_windows_width
= new_pixel_width
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
449 new_text_width
= FRAME_PIXEL_TO_TEXT_WIDTH (f
, new_pixel_width
);
450 new_cols
= new_text_width
/ unit_width
;
452 new_pixel_height
= ((inhibit_vertical
&& (inhibit
< 5))
454 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f
, new_text_height
),
456 + FRAME_TOP_MARGIN_HEIGHT (f
)
457 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)));
458 new_windows_height
= (new_pixel_height
459 - FRAME_TOP_MARGIN_HEIGHT (f
)
460 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
461 new_text_height
= FRAME_PIXEL_TO_TEXT_HEIGHT (f
, new_pixel_height
);
462 new_lines
= new_text_height
/ unit_height
;
464 #ifdef HAVE_WINDOW_SYSTEM
465 if (FRAME_WINDOW_P (f
)
466 && f
->can_x_set_window_size
467 && ((!inhibit_horizontal
468 && (new_pixel_width
!= old_pixel_width
469 || inhibit
== 0 || inhibit
== 2))
470 || (!inhibit_vertical
471 && (new_pixel_height
!= old_pixel_height
472 || inhibit
== 0 || inhibit
== 2))))
473 /* We are either allowed to change the frame size or the minimum
474 sizes request such a change. Do not care for fixing minimum
475 sizes here, we do that eventually when we're called from
476 change_frame_size. */
478 /* Make sure we respect fullheight and fullwidth. */
479 if (inhibit_horizontal
)
480 new_text_width
= old_text_width
;
481 else if (inhibit_vertical
)
482 new_text_height
= old_text_height
;
484 x_set_window_size (f
, 0, new_text_width
, new_text_height
, 1);
491 if (new_text_width
== old_text_width
492 && new_text_height
== old_text_height
493 && new_windows_width
== old_windows_width
494 && new_windows_height
== old_windows_height
495 && new_pixel_width
== old_pixel_width
496 && new_pixel_height
== old_pixel_height
)
497 /* No change. Sanitize window sizes and return. */
499 sanitize_window_sizes (frame
, Qt
);
500 sanitize_window_sizes (frame
, Qnil
);
508 /* We only can set screen dimensions to certain values supported
509 by our video hardware. Try to find the smallest size greater
510 or equal to the requested dimensions. */
511 dos_set_window_size (&new_lines
, &new_cols
);
514 if (new_windows_width
!= old_windows_width
)
516 resize_frame_windows (f
, new_windows_width
, 1, 1);
518 /* MSDOS frames cannot PRETEND, as they change frame size by
519 manipulating video hardware. */
520 if ((FRAME_TERMCAP_P (f
) && !pretend
) || FRAME_MSDOS_P (f
))
521 FrameCols (FRAME_TTY (f
)) = new_cols
;
523 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
524 if (WINDOWP (f
->tool_bar_window
))
526 XWINDOW (f
->tool_bar_window
)->pixel_width
= new_windows_width
;
527 XWINDOW (f
->tool_bar_window
)->total_cols
528 = new_windows_width
/ unit_width
;
533 if (new_windows_height
!= old_windows_height
534 /* When the top margin has changed we have to recalculate the top
535 edges of all windows. No such calculation is necessary for the
537 || WINDOW_TOP_PIXEL_EDGE (r
) != FRAME_TOP_MARGIN_HEIGHT (f
))
539 resize_frame_windows (f
, new_windows_height
, 0, 1);
541 /* MSDOS frames cannot PRETEND, as they change frame size by
542 manipulating video hardware. */
543 if ((FRAME_TERMCAP_P (f
) && !pretend
) || FRAME_MSDOS_P (f
))
544 FrameRows (FRAME_TTY (f
)) = new_lines
+ FRAME_TOP_MARGIN (f
);
547 /* Assign new sizes. */
548 FRAME_TEXT_WIDTH (f
) = new_text_width
;
549 FRAME_TEXT_HEIGHT (f
) = new_text_height
;
550 FRAME_PIXEL_WIDTH (f
) = new_pixel_width
;
551 FRAME_PIXEL_HEIGHT (f
) = new_pixel_height
;
552 SET_FRAME_COLS (f
, new_cols
);
553 SET_FRAME_LINES (f
, new_lines
);
556 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
557 int text_area_x
, text_area_y
, text_area_width
, text_area_height
;
559 window_box (w
, TEXT_AREA
, &text_area_x
, &text_area_y
, &text_area_width
,
561 if (w
->cursor
.x
>= text_area_x
+ text_area_width
)
562 w
->cursor
.hpos
= w
->cursor
.x
= 0;
563 if (w
->cursor
.y
>= text_area_y
+ text_area_height
)
564 w
->cursor
.vpos
= w
->cursor
.y
= 0;
567 /* Sanitize window sizes. */
568 sanitize_window_sizes (frame
, Qt
);
569 sanitize_window_sizes (frame
, Qnil
);
571 adjust_frame_glyphs (f
);
573 SET_FRAME_GARBAGED (f
);
575 /* A frame was "resized" if one of its pixelsizes changed, even if its
576 X window wasn't resized at all. */
577 f
->resized_p
= (new_pixel_width
!= old_pixel_width
578 || new_pixel_height
!= old_pixel_height
);
582 run_window_configuration_change_hook (f
);
587 make_frame (bool mini_p
)
590 register struct frame
*f
;
591 register struct window
*rw
, *mw
;
592 register Lisp_Object root_window
;
593 register Lisp_Object mini_window
;
595 f
= allocate_frame ();
596 XSETFRAME (frame
, f
);
599 /* Initialize Lisp data. Note that allocate_frame initializes all
600 Lisp data to nil, so do it only for slots which should not be nil. */
601 fset_tool_bar_position (f
, Qtop
);
604 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
605 non-Lisp data, so do it only for slots which should not be zero.
606 To avoid subtle bugs and for the sake of readability, it's better to
607 initialize enum members explicitly even if their values are zero. */
608 f
->wants_modeline
= true;
611 f
->can_x_set_window_size
= false;
612 f
->can_run_window_configuration_change_hook
= false;
613 f
->column_width
= 1; /* !FRAME_WINDOW_P value. */
614 f
->line_height
= 1; /* !FRAME_WINDOW_P value. */
615 #ifdef HAVE_WINDOW_SYSTEM
616 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
617 f
->horizontal_scroll_bars
= false;
618 f
->want_fullscreen
= FULLSCREEN_NONE
;
619 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
620 f
->last_tool_bar_item
= -1;
624 root_window
= make_window ();
625 rw
= XWINDOW (root_window
);
628 mini_window
= make_window ();
629 mw
= XWINDOW (mini_window
);
630 wset_next (rw
, mini_window
);
631 wset_prev (mw
, root_window
);
633 wset_frame (mw
, frame
);
634 fset_minibuffer_window (f
, mini_window
);
639 wset_next (rw
, Qnil
);
640 fset_minibuffer_window (f
, Qnil
);
643 wset_frame (rw
, frame
);
646 just so that there is "something there."
647 Correct size will be set up later with adjust_frame_size. */
649 SET_FRAME_COLS (f
, 10);
650 SET_FRAME_LINES (f
, 10);
651 SET_FRAME_WIDTH (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
));
652 SET_FRAME_HEIGHT (f
, FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
));
655 rw
->pixel_width
= rw
->total_cols
* FRAME_COLUMN_WIDTH (f
);
656 rw
->total_lines
= mini_p
? 9 : 10;
657 rw
->pixel_height
= rw
->total_lines
* FRAME_LINE_HEIGHT (f
);
661 mw
->top_line
= rw
->total_lines
;
662 mw
->pixel_top
= rw
->pixel_height
;
663 mw
->total_cols
= rw
->total_cols
;
664 mw
->pixel_width
= rw
->pixel_width
;
666 mw
->pixel_height
= FRAME_LINE_HEIGHT (f
);
669 /* Choose a buffer for the frame's root window. */
671 Lisp_Object buf
= Fcurrent_buffer ();
673 /* If current buffer is hidden, try to find another one. */
674 if (BUFFER_HIDDEN_P (XBUFFER (buf
)))
675 buf
= other_buffer_safely (buf
);
677 /* Use set_window_buffer, not Fset_window_buffer, and don't let
678 hooks be run by it. The reason is that the whole frame/window
679 arrangement is not yet fully initialized at this point. Windows
680 don't have the right size, glyph matrices aren't initialized
681 etc. Running Lisp functions at this point surely ends in a
683 set_window_buffer (root_window
, buf
, 0, 0);
684 fset_buffer_list (f
, list1 (buf
));
689 set_window_buffer (mini_window
,
690 (NILP (Vminibuffer_list
)
692 : Fcar (Vminibuffer_list
)),
694 /* No horizontal scroll bars in minibuffers. */
695 wset_horizontal_scroll_bar (mw
, Qnil
);
698 fset_root_window (f
, root_window
);
699 fset_selected_window (f
, root_window
);
700 /* Make sure this window seems more recently used than
701 a newly-created, never-selected window. */
702 XWINDOW (f
->selected_window
)->use_time
= ++window_select_count
;
707 #ifdef HAVE_WINDOW_SYSTEM
708 /* Make a frame using a separate minibuffer window on another frame.
709 MINI_WINDOW is the minibuffer window to use. nil means use the
710 default (the global minibuffer). */
713 make_frame_without_minibuffer (register Lisp_Object mini_window
, KBOARD
*kb
, Lisp_Object display
)
715 register struct frame
*f
;
718 if (!NILP (mini_window
))
719 CHECK_LIVE_WINDOW (mini_window
);
721 if (!NILP (mini_window
)
722 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window
)->frame
)) != kb
)
723 error ("Frame and minibuffer must be on the same terminal");
725 /* Make a frame containing just a root window. */
728 if (NILP (mini_window
))
730 /* Use default-minibuffer-frame if possible. */
731 if (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
732 || ! FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
))))
734 Lisp_Object frame_dummy
;
736 XSETFRAME (frame_dummy
, f
);
737 GCPRO1 (frame_dummy
);
738 /* If there's no minibuffer frame to use, create one. */
739 kset_default_minibuffer_frame
740 (kb
, call1 (intern ("make-initial-minibuffer-frame"), display
));
745 = XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
))->minibuffer_window
;
748 fset_minibuffer_window (f
, mini_window
);
750 /* Make the chosen minibuffer window display the proper minibuffer,
751 unless it is already showing a minibuffer. */
752 if (NILP (Fmemq (XWINDOW (mini_window
)->contents
, Vminibuffer_list
)))
753 /* Use set_window_buffer instead of Fset_window_buffer (see
754 discussion of bug#11984, bug#12025, bug#12026). */
755 set_window_buffer (mini_window
,
756 (NILP (Vminibuffer_list
)
758 : Fcar (Vminibuffer_list
)), 0, 0);
762 /* Make a frame containing only a minibuffer window. */
765 make_minibuffer_frame (void)
767 /* First make a frame containing just a root window, no minibuffer. */
769 register struct frame
*f
= make_frame (0);
770 register Lisp_Object mini_window
;
771 register Lisp_Object frame
;
773 XSETFRAME (frame
, f
);
778 f
->wants_modeline
= 0;
780 /* Now label the root window as also being the minibuffer.
781 Avoid infinite looping on the window chain by marking next pointer
784 mini_window
= f
->root_window
;
785 fset_minibuffer_window (f
, mini_window
);
786 XWINDOW (mini_window
)->mini
= 1;
787 wset_next (XWINDOW (mini_window
), Qnil
);
788 wset_prev (XWINDOW (mini_window
), Qnil
);
789 wset_frame (XWINDOW (mini_window
), frame
);
791 /* Put the proper buffer in that window. */
793 /* Use set_window_buffer instead of Fset_window_buffer (see
794 discussion of bug#11984, bug#12025, bug#12026). */
795 set_window_buffer (mini_window
,
796 (NILP (Vminibuffer_list
)
798 : Fcar (Vminibuffer_list
)), 0, 0);
801 #endif /* HAVE_WINDOW_SYSTEM */
803 /* Construct a frame that refers to a terminal. */
805 static printmax_t tty_frame_count
;
808 make_initial_frame (void)
811 struct terminal
*terminal
;
814 eassert (initial_kboard
);
816 /* The first call must initialize Vframe_list. */
817 if (! (NILP (Vframe_list
) || CONSP (Vframe_list
)))
820 terminal
= init_initial_terminal ();
823 XSETFRAME (frame
, f
);
825 Vframe_list
= Fcons (frame
, Vframe_list
);
828 fset_name (f
, build_pure_c_string ("F1"));
830 SET_FRAME_VISIBLE (f
, 1);
832 f
->output_method
= terminal
->type
;
833 f
->terminal
= terminal
;
834 f
->terminal
->reference_count
++;
835 f
->output_data
.nothing
= 0;
837 FRAME_FOREGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_FG_COLOR
;
838 FRAME_BACKGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_BG_COLOR
;
840 #ifdef HAVE_WINDOW_SYSTEM
841 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
842 f
->horizontal_scroll_bars
= false;
845 /* The default value of menu-bar-mode is t. */
846 set_menu_bar_lines (f
, make_number (1), Qnil
);
849 init_frame_faces (f
);
851 last_nonminibuf_frame
= f
;
857 static struct frame
*
858 make_terminal_frame (struct terminal
*terminal
)
860 register struct frame
*f
;
862 char name
[sizeof "F" + INT_STRLEN_BOUND (printmax_t
)];
865 error ("Terminal is not live, can't create new frames on it");
869 XSETFRAME (frame
, f
);
870 Vframe_list
= Fcons (frame
, Vframe_list
);
872 fset_name (f
, make_formatted_string (name
, "F%"pMd
, ++tty_frame_count
));
874 SET_FRAME_VISIBLE (f
, 1);
876 f
->terminal
= terminal
;
877 f
->terminal
->reference_count
++;
879 f
->output_data
.tty
->display_info
= &the_only_display_info
;
880 if (!inhibit_window_system
881 && (!FRAMEP (selected_frame
) || !FRAME_LIVE_P (XFRAME (selected_frame
))
882 || XFRAME (selected_frame
)->output_method
== output_msdos_raw
))
883 f
->output_method
= output_msdos_raw
;
885 f
->output_method
= output_termcap
;
886 #else /* not MSDOS */
887 f
->output_method
= output_termcap
;
888 create_tty_output (f
);
889 FRAME_FOREGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_FG_COLOR
;
890 FRAME_BACKGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_BG_COLOR
;
891 #endif /* not MSDOS */
893 #ifdef HAVE_WINDOW_SYSTEM
894 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
895 f
->horizontal_scroll_bars
= false;
898 FRAME_MENU_BAR_LINES (f
) = NILP (Vmenu_bar_mode
) ? 0 : 1;
899 FRAME_LINES (f
) = FRAME_LINES (f
) - FRAME_MENU_BAR_LINES (f
);
900 FRAME_MENU_BAR_HEIGHT (f
) = FRAME_MENU_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
);
901 FRAME_TEXT_HEIGHT (f
) = FRAME_TEXT_HEIGHT (f
) - FRAME_MENU_BAR_HEIGHT (f
);
903 /* Set the top frame to the newly created frame. */
904 if (FRAMEP (FRAME_TTY (f
)->top_frame
)
905 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f
)->top_frame
)))
906 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f
)->top_frame
), 2); /* obscured */
908 FRAME_TTY (f
)->top_frame
= frame
;
911 init_frame_faces (f
);
916 /* Get a suitable value for frame parameter PARAMETER for a newly
917 created frame, based on (1) the user-supplied frame parameter
918 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
921 get_future_frame_param (Lisp_Object parameter
,
922 Lisp_Object supplied_parms
,
927 result
= Fassq (parameter
, supplied_parms
);
929 result
= Fassq (parameter
, XFRAME (selected_frame
)->param_alist
);
930 if (NILP (result
) && current_value
!= NULL
)
931 result
= build_string (current_value
);
932 if (!NILP (result
) && !STRINGP (result
))
933 result
= XCDR (result
);
934 if (NILP (result
) || !STRINGP (result
))
940 DEFUN ("make-terminal-frame", Fmake_terminal_frame
, Smake_terminal_frame
,
942 doc
: /* Create an additional terminal frame, possibly on another terminal.
943 This function takes one argument, an alist specifying frame parameters.
945 You can create multiple frames on a single text terminal, but only one
946 of them (the selected terminal frame) is actually displayed.
948 In practice, generally you don't need to specify any parameters,
949 except when you want to create a new frame on another terminal.
950 In that case, the `tty' parameter specifies the device file to open,
951 and the `tty-type' parameter specifies the terminal type. Example:
953 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
955 Note that changing the size of one terminal frame automatically
956 affects all frames on the same terminal device. */)
960 struct terminal
*t
= NULL
;
961 Lisp_Object frame
, tem
;
962 struct frame
*sf
= SELECTED_FRAME ();
965 if (sf
->output_method
!= output_msdos_raw
966 && sf
->output_method
!= output_termcap
)
968 #else /* not MSDOS */
970 #ifdef WINDOWSNT /* This should work now! */
971 if (sf
->output_method
!= output_termcap
)
972 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
974 #endif /* not MSDOS */
977 Lisp_Object terminal
;
979 terminal
= Fassq (Qterminal
, parms
);
980 if (CONSP (terminal
))
982 terminal
= XCDR (terminal
);
983 t
= decode_live_terminal (terminal
);
986 if (t
&& t
!= the_only_display_info
.terminal
)
987 /* msdos.c assumes a single tty_display_info object. */
988 error ("Multiple terminals are not supported on this platform");
990 t
= the_only_display_info
.terminal
;
996 char *name
= 0, *type
= 0;
997 Lisp_Object tty
, tty_type
;
1000 tty
= get_future_frame_param
1001 (Qtty
, parms
, (FRAME_TERMCAP_P (XFRAME (selected_frame
))
1002 ? FRAME_TTY (XFRAME (selected_frame
))->name
1005 SAFE_ALLOCA_STRING (name
, tty
);
1007 tty_type
= get_future_frame_param
1008 (Qtty_type
, parms
, (FRAME_TERMCAP_P (XFRAME (selected_frame
))
1009 ? FRAME_TTY (XFRAME (selected_frame
))->type
1011 if (!NILP (tty_type
))
1012 SAFE_ALLOCA_STRING (type
, tty_type
);
1014 t
= init_tty (name
, type
, 0); /* Errors are not fatal. */
1018 f
= make_terminal_frame (t
);
1022 get_tty_size (fileno (FRAME_TTY (f
)->input
), &width
, &height
);
1023 adjust_frame_size (f
, width
, height
- FRAME_MENU_BAR_LINES (f
), 5, 0, Qnil
);
1026 adjust_frame_glyphs (f
);
1027 calculate_costs (f
);
1028 XSETFRAME (frame
, f
);
1030 store_in_alist (&parms
, Qtty_type
, build_string (t
->display_info
.tty
->type
));
1031 store_in_alist (&parms
, Qtty
,
1032 (t
->display_info
.tty
->name
1033 ? build_string (t
->display_info
.tty
->name
)
1035 Fmodify_frame_parameters (frame
, parms
);
1037 /* Make the frame face alist be frame-specific, so that each
1038 frame could change its face definitions independently. */
1039 fset_face_alist (f
, Fcopy_alist (sf
->face_alist
));
1040 /* Simple Fcopy_alist isn't enough, because we need the contents of
1041 the vectors which are the CDRs of associations in face_alist to
1042 be copied as well. */
1043 for (tem
= f
->face_alist
; CONSP (tem
); tem
= XCDR (tem
))
1044 XSETCDR (XCAR (tem
), Fcopy_sequence (XCDR (XCAR (tem
))));
1049 /* Perform the switch to frame FRAME.
1051 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
1054 If TRACK is non-zero and the frame that currently has the focus
1055 redirects its focus to the selected frame, redirect that focused
1056 frame's focus to FRAME instead.
1058 FOR_DELETION non-zero means that the selected frame is being
1059 deleted, which includes the possibility that the frame's terminal
1062 The value of NORECORD is passed as argument to Fselect_window. */
1065 do_switch_frame (Lisp_Object frame
, int track
, int for_deletion
, Lisp_Object norecord
)
1067 struct frame
*sf
= SELECTED_FRAME ();
1069 /* If FRAME is a switch-frame event, extract the frame we should
1072 && EQ (XCAR (frame
), Qswitch_frame
)
1073 && CONSP (XCDR (frame
)))
1074 frame
= XCAR (XCDR (frame
));
1076 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
1077 a switch-frame event to arrive after a frame is no longer live,
1078 especially when deleting the initial frame during startup. */
1079 CHECK_FRAME (frame
);
1080 if (! FRAME_LIVE_P (XFRAME (frame
)))
1083 if (sf
== XFRAME (frame
))
1086 /* If a frame's focus has been redirected toward the currently
1087 selected frame, we should change the redirection to point to the
1088 newly selected frame. This means that if the focus is redirected
1089 from a minibufferless frame to a surrogate minibuffer frame, we
1090 can use `other-window' to switch between all the frames using
1091 that minibuffer frame, and the focus redirection will follow us
1094 /* This is too greedy; it causes inappropriate focus redirection
1095 that's hard to get rid of. */
1100 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1104 if (!FRAMEP (XCAR (tail
)))
1107 focus
= FRAME_FOCUS_FRAME (XFRAME (XCAR (tail
)));
1109 if (FRAMEP (focus
) && XFRAME (focus
) == SELECTED_FRAME ())
1110 Fredirect_frame_focus (XCAR (tail
), frame
);
1114 /* Instead, apply it only to the frame we're pointing to. */
1115 #ifdef HAVE_WINDOW_SYSTEM
1116 if (track
&& FRAME_WINDOW_P (XFRAME (frame
)))
1118 Lisp_Object focus
, xfocus
;
1120 xfocus
= x_get_focus_frame (XFRAME (frame
));
1121 if (FRAMEP (xfocus
))
1123 focus
= FRAME_FOCUS_FRAME (XFRAME (xfocus
));
1124 if (FRAMEP (focus
) && XFRAME (focus
) == SELECTED_FRAME ())
1125 Fredirect_frame_focus (xfocus
, frame
);
1128 #endif /* HAVE_X_WINDOWS */
1131 if (!for_deletion
&& FRAME_HAS_MINIBUF_P (sf
))
1132 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf
)), 1);
1134 if (FRAME_TERMCAP_P (XFRAME (frame
)) || FRAME_MSDOS_P (XFRAME (frame
)))
1136 struct frame
*f
= XFRAME (frame
);
1137 struct tty_display_info
*tty
= FRAME_TTY (f
);
1138 Lisp_Object top_frame
= tty
->top_frame
;
1140 /* Don't mark the frame garbaged and/or obscured if we are
1141 switching to the frame that is already the top frame of that
1143 if (!EQ (frame
, top_frame
))
1145 if (FRAMEP (top_frame
))
1146 /* Mark previously displayed frame as now obscured. */
1147 SET_FRAME_VISIBLE (XFRAME (top_frame
), 2);
1148 SET_FRAME_VISIBLE (f
, 1);
1149 /* If the new TTY frame changed dimensions, we need to
1150 resync term.c's idea of the frame size with the new
1152 if (FRAME_COLS (f
) != FrameCols (tty
))
1153 FrameCols (tty
) = FRAME_COLS (f
);
1154 if (FRAME_TOTAL_LINES (f
) != FrameRows (tty
))
1155 FrameRows (tty
) = FRAME_TOTAL_LINES (f
);
1157 tty
->top_frame
= frame
;
1160 selected_frame
= frame
;
1161 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame
)))
1162 last_nonminibuf_frame
= XFRAME (selected_frame
);
1164 Fselect_window (XFRAME (frame
)->selected_window
, norecord
);
1166 /* We want to make sure that the next event generates a frame-switch
1167 event to the appropriate frame. This seems kludgy to me, but
1168 before you take it out, make sure that evaluating something like
1169 (select-window (frame-root-window (new-frame))) doesn't end up
1170 with your typing being interpreted in the new frame instead of
1171 the one you're actually typing in. */
1172 internal_last_event_frame
= Qnil
;
1177 DEFUN ("select-frame", Fselect_frame
, Sselect_frame
, 1, 2, "e",
1178 doc
: /* Select FRAME.
1179 Subsequent editing commands apply to its selected window.
1180 Optional argument NORECORD means to neither change the order of
1181 recently selected windows nor the buffer list.
1183 The selection of FRAME lasts until the next time the user does
1184 something to select a different frame, or until the next time
1185 this function is called. If you are using a window system, the
1186 previously selected frame may be restored as the selected frame
1187 when returning to the command loop, because it still may have
1188 the window system's input focus. On a text terminal, the next
1189 redisplay will display FRAME.
1191 This function returns FRAME, or nil if FRAME has been deleted. */)
1192 (Lisp_Object frame
, Lisp_Object norecord
)
1194 return do_switch_frame (frame
, 1, 0, norecord
);
1197 DEFUN ("handle-switch-frame", Fhandle_switch_frame
, Shandle_switch_frame
, 1, 1, "e",
1198 doc
: /* Handle a switch-frame event EVENT.
1199 Switch-frame events are usually bound to this function.
1200 A switch-frame event tells Emacs that the window manager has requested
1201 that the user's events be directed to the frame mentioned in the event.
1202 This function selects the selected window of the frame of EVENT.
1204 If EVENT is frame object, handle it as if it were a switch-frame event
1208 /* Preserve prefix arg that the command loop just cleared. */
1209 kset_prefix_arg (current_kboard
, Vcurrent_prefix_arg
);
1210 Frun_hooks (1, &Qmouse_leave_buffer_hook
);
1211 /* `switch-frame' implies a focus in. */
1212 call1 (intern ("handle-focus-in"), event
);
1213 return do_switch_frame (event
, 0, 0, Qnil
);
1216 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
1217 doc
: /* Return the frame that is now selected. */)
1220 return selected_frame
;
1223 DEFUN ("frame-list", Fframe_list
, Sframe_list
,
1225 doc
: /* Return a list of all live frames. */)
1229 frames
= Fcopy_sequence (Vframe_list
);
1230 #ifdef HAVE_WINDOW_SYSTEM
1231 if (FRAMEP (tip_frame
))
1232 frames
= Fdelq (tip_frame
, frames
);
1237 /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1238 same tty (for tty frames) or among frames which uses FRAME's keyboard.
1239 If MINIBUF is nil, do not consider minibuffer-only candidate.
1240 If MINIBUF is `visible', do not consider an invisible candidate.
1241 If MINIBUF is a window, consider only its own frame and candidate now
1242 using that window as the minibuffer.
1243 If MINIBUF is 0, consider candidate if it is visible or iconified.
1244 Otherwise consider any candidate and return nil if CANDIDATE is not
1248 candidate_frame (Lisp_Object candidate
, Lisp_Object frame
, Lisp_Object minibuf
)
1250 struct frame
*c
= XFRAME (candidate
), *f
= XFRAME (frame
);
1252 if ((!FRAME_TERMCAP_P (c
) && !FRAME_TERMCAP_P (f
)
1253 && FRAME_KBOARD (c
) == FRAME_KBOARD (f
))
1254 || (FRAME_TERMCAP_P (c
) && FRAME_TERMCAP_P (f
)
1255 && FRAME_TTY (c
) == FRAME_TTY (f
)))
1259 if (!FRAME_MINIBUF_ONLY_P (c
))
1262 else if (EQ (minibuf
, Qvisible
))
1264 if (FRAME_VISIBLE_P (c
))
1267 else if (WINDOWP (minibuf
))
1269 if (EQ (FRAME_MINIBUF_WINDOW (c
), minibuf
)
1270 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)), candidate
)
1271 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
1272 FRAME_FOCUS_FRAME (c
)))
1275 else if (XFASTINT (minibuf
) == 0)
1277 if (FRAME_VISIBLE_P (c
) || FRAME_ICONIFIED_P (c
))
1286 /* Return the next frame in the frame list after FRAME. */
1289 next_frame (Lisp_Object frame
, Lisp_Object minibuf
)
1291 Lisp_Object f
, tail
;
1294 /* There must always be at least one frame in Vframe_list. */
1295 eassert (CONSP (Vframe_list
));
1298 FOR_EACH_FRAME (tail
, f
)
1302 f
= candidate_frame (f
, frame
, minibuf
);
1312 /* Return the previous frame in the frame list before FRAME. */
1315 prev_frame (Lisp_Object frame
, Lisp_Object minibuf
)
1317 Lisp_Object f
, tail
, prev
= Qnil
;
1319 /* There must always be at least one frame in Vframe_list. */
1320 eassert (CONSP (Vframe_list
));
1322 FOR_EACH_FRAME (tail
, f
)
1324 if (EQ (frame
, f
) && !NILP (prev
))
1326 f
= candidate_frame (f
, frame
, minibuf
);
1331 /* We've scanned the entire list. */
1333 /* We went through the whole frame list without finding a single
1334 acceptable frame. Return the original frame. */
1337 /* There were no acceptable frames in the list before FRAME; otherwise,
1338 we would have returned directly from the loop. Since PREV is the last
1339 acceptable frame in the list, return it. */
1344 DEFUN ("next-frame", Fnext_frame
, Snext_frame
, 0, 2, 0,
1345 doc
: /* Return the next frame in the frame list after FRAME.
1346 It considers only frames on the same terminal as FRAME.
1347 By default, skip minibuffer-only frames.
1348 If omitted, FRAME defaults to the selected frame.
1349 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1350 If MINIFRAME is a window, include only its own frame
1351 and any frame now using that window as the minibuffer.
1352 If MINIFRAME is `visible', include all visible frames.
1353 If MINIFRAME is 0, include all visible and iconified frames.
1354 Otherwise, include all frames. */)
1355 (Lisp_Object frame
, Lisp_Object miniframe
)
1358 frame
= selected_frame
;
1359 CHECK_LIVE_FRAME (frame
);
1360 return next_frame (frame
, miniframe
);
1363 DEFUN ("previous-frame", Fprevious_frame
, Sprevious_frame
, 0, 2, 0,
1364 doc
: /* Return the previous frame in the frame list before FRAME.
1365 It considers only frames on the same terminal as FRAME.
1366 By default, skip minibuffer-only frames.
1367 If omitted, FRAME defaults to the selected frame.
1368 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1369 If MINIFRAME is a window, include only its own frame
1370 and any frame now using that window as the minibuffer.
1371 If MINIFRAME is `visible', include all visible frames.
1372 If MINIFRAME is 0, include all visible and iconified frames.
1373 Otherwise, include all frames. */)
1374 (Lisp_Object frame
, Lisp_Object miniframe
)
1377 frame
= selected_frame
;
1378 CHECK_LIVE_FRAME (frame
);
1379 return prev_frame (frame
, miniframe
);
1382 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame
,
1383 Slast_nonminibuf_frame
, 0, 0, 0,
1384 doc
: /* Return last non-minibuffer frame selected. */)
1387 Lisp_Object frame
= Qnil
;
1389 if (last_nonminibuf_frame
)
1390 XSETFRAME (frame
, last_nonminibuf_frame
);
1395 /* Return 1 if it is ok to delete frame F;
1396 0 if all frames aside from F are invisible.
1397 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1400 other_visible_frames (struct frame
*f
)
1402 Lisp_Object frames
, this;
1404 FOR_EACH_FRAME (frames
, this)
1406 if (f
== XFRAME (this))
1409 /* Verify that we can still talk to the frame's X window,
1410 and note any recent change in visibility. */
1411 #ifdef HAVE_X_WINDOWS
1412 if (FRAME_WINDOW_P (XFRAME (this)))
1413 x_sync (XFRAME (this));
1416 if (FRAME_VISIBLE_P (XFRAME (this))
1417 || FRAME_ICONIFIED_P (XFRAME (this))
1418 /* Allow deleting the terminal frame when at least one X
1420 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f
)))
1426 /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1427 window. Preferably use the selected frame's minibuffer window
1428 instead. If the selected frame doesn't have one, get some other
1429 frame's minibuffer window. SELECT non-zero means select the new
1430 minibuffer window. */
1432 check_minibuf_window (Lisp_Object frame
, int select
)
1434 struct frame
*f
= decode_live_frame (frame
);
1436 XSETFRAME (frame
, f
);
1438 if (WINDOWP (minibuf_window
) && EQ (f
->minibuffer_window
, minibuf_window
))
1440 Lisp_Object frames
, this, window
= make_number (0);
1442 if (!EQ (frame
, selected_frame
)
1443 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame
)))
1444 window
= FRAME_MINIBUF_WINDOW (XFRAME (selected_frame
));
1446 FOR_EACH_FRAME (frames
, this)
1448 if (!EQ (this, frame
) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1450 window
= FRAME_MINIBUF_WINDOW (XFRAME (this));
1455 /* Don't abort if no window was found (Bug#15247). */
1456 if (WINDOWP (window
))
1458 /* Use set_window_buffer instead of Fset_window_buffer (see
1459 discussion of bug#11984, bug#12025, bug#12026). */
1460 set_window_buffer (window
, XWINDOW (minibuf_window
)->contents
, 0, 0);
1461 minibuf_window
= window
;
1463 /* SELECT non-zero usually means that FRAME's minibuffer
1464 window was selected; select the new one. */
1466 Fselect_window (minibuf_window
, Qnil
);
1472 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1473 unconditionally. x_connection_closed and delete_terminal use
1474 this. Any other value of FORCE implements the semantics
1475 described for Fdelete_frame. */
1477 delete_frame (Lisp_Object frame
, Lisp_Object force
)
1479 struct frame
*f
= decode_any_frame (frame
);
1483 int minibuffer_selected
, is_tooltip_frame
;
1485 if (! FRAME_LIVE_P (f
))
1488 if (NILP (force
) && !other_visible_frames (f
))
1489 error ("Attempt to delete the sole visible or iconified frame");
1491 /* x_connection_closed must have set FORCE to `noelisp' in order
1492 to delete the last frame, if it is gone. */
1493 if (NILP (XCDR (Vframe_list
)) && !EQ (force
, Qnoelisp
))
1494 error ("Attempt to delete the only frame");
1496 XSETFRAME (frame
, f
);
1498 /* Does this frame have a minibuffer, and is it the surrogate
1499 minibuffer for any other frame? */
1500 if (FRAME_HAS_MINIBUF_P (f
))
1502 Lisp_Object frames
, this;
1504 FOR_EACH_FRAME (frames
, this)
1508 if (EQ (this, frame
))
1511 fminiw
= FRAME_MINIBUF_WINDOW (XFRAME (this));
1513 if (WINDOWP (fminiw
) && EQ (frame
, WINDOW_FRAME (XWINDOW (fminiw
))))
1515 /* If we MUST delete this frame, delete the other first.
1516 But do this only if FORCE equals `noelisp'. */
1517 if (EQ (force
, Qnoelisp
))
1518 delete_frame (this, Qnoelisp
);
1520 error ("Attempt to delete a surrogate minibuffer frame");
1525 is_tooltip_frame
= !NILP (Fframe_parameter (frame
, intern ("tooltip")));
1527 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1528 frame is a tooltip. FORCE is set to `noelisp' when handling
1529 a disconnect from the terminal, so we don't dare call Lisp
1531 if (NILP (Vrun_hooks
) || is_tooltip_frame
)
1533 else if (EQ (force
, Qnoelisp
))
1535 = Fcons (list3 (Qrun_hook_with_args
, Qdelete_frame_functions
, frame
),
1539 #ifdef HAVE_X_WINDOWS
1540 /* Also, save clipboard to the clipboard manager. */
1541 x_clipboard_manager_save_frame (frame
);
1544 safe_call2 (Qrun_hook_with_args
, Qdelete_frame_functions
, frame
);
1547 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1548 if (! FRAME_LIVE_P (f
))
1551 /* At this point, we are committed to deleting the frame.
1552 There is no more chance for errors to prevent it. */
1554 minibuffer_selected
= EQ (minibuf_window
, selected_window
);
1555 sf
= SELECTED_FRAME ();
1556 /* Don't let the frame remain selected. */
1560 Lisp_Object frame1
= Qnil
;
1562 /* Look for another visible frame on the same terminal.
1563 Do not call next_frame here because it may loop forever.
1564 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1565 FOR_EACH_FRAME (tail
, frame1
)
1566 if (!EQ (frame
, frame1
)
1567 && (FRAME_TERMINAL (XFRAME (frame
))
1568 == FRAME_TERMINAL (XFRAME (frame1
)))
1569 && FRAME_VISIBLE_P (XFRAME (frame1
)))
1572 /* If there is none, find *some* other frame. */
1573 if (NILP (frame1
) || EQ (frame1
, frame
))
1575 FOR_EACH_FRAME (tail
, frame1
)
1577 if (! EQ (frame
, frame1
) && FRAME_LIVE_P (XFRAME (frame1
)))
1579 /* Do not change a text terminal's top-frame. */
1580 struct frame
*f1
= XFRAME (frame1
);
1581 if (FRAME_TERMCAP_P (f1
) || FRAME_MSDOS_P (f1
))
1583 Lisp_Object top_frame
= FRAME_TTY (f1
)->top_frame
;
1584 if (!EQ (top_frame
, frame
))
1591 #ifdef NS_IMPL_COCOA
1593 /* Under NS, there is no system mechanism for choosing a new
1594 window to get focus -- it is left to application code.
1595 So the portion of THIS application interfacing with NS
1596 needs to know about it. We call Fraise_frame, but the
1597 purpose is really to transfer focus. */
1598 Fraise_frame (frame1
);
1601 do_switch_frame (frame1
, 0, 1, Qnil
);
1602 sf
= SELECTED_FRAME ();
1605 /* Don't allow minibuf_window to remain on a deleted frame. */
1606 check_minibuf_window (frame
, minibuffer_selected
);
1608 /* Don't let echo_area_window to remain on a deleted frame. */
1609 if (EQ (f
->minibuffer_window
, echo_area_window
))
1610 echo_area_window
= sf
->minibuffer_window
;
1612 /* Clear any X selections for this frame. */
1613 #ifdef HAVE_X_WINDOWS
1615 x_clear_frame_selections (f
);
1619 This function must be called before the window tree of the
1620 frame is deleted because windows contain dynamically allocated
1624 #ifdef HAVE_WINDOW_SYSTEM
1625 /* Give chance to each font driver to free a frame specific data. */
1626 font_update_drivers (f
, Qnil
);
1629 /* Mark all the windows that used to be on FRAME as deleted, and then
1630 remove the reference to them. */
1631 delete_all_child_windows (f
->root_window
);
1632 fset_root_window (f
, Qnil
);
1634 Vframe_list
= Fdelq (frame
, Vframe_list
);
1635 SET_FRAME_VISIBLE (f
, 0);
1637 /* Allow the vector of menu bar contents to be freed in the next
1638 garbage collection. The frame object itself may not be garbage
1639 collected until much later, because recent_keys and other data
1640 structures can still refer to it. */
1641 fset_menu_bar_vector (f
, Qnil
);
1643 /* If FRAME's buffer lists contains killed
1644 buffers, this helps GC to reclaim them. */
1645 fset_buffer_list (f
, Qnil
);
1646 fset_buried_buffer_list (f
, Qnil
);
1648 free_font_driver_list (f
);
1649 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1652 xfree (f
->decode_mode_spec_buffer
);
1653 xfree (FRAME_INSERT_COST (f
));
1654 xfree (FRAME_DELETEN_COST (f
));
1655 xfree (FRAME_INSERTN_COST (f
));
1656 xfree (FRAME_DELETE_COST (f
));
1658 /* Since some events are handled at the interrupt level, we may get
1659 an event for f at any time; if we zero out the frame's terminal
1660 now, then we may trip up the event-handling code. Instead, we'll
1661 promise that the terminal of the frame must be valid until we
1662 have called the window-system-dependent frame destruction
1667 struct terminal
*terminal
;
1669 if (FRAME_TERMINAL (f
)->delete_frame_hook
)
1670 (*FRAME_TERMINAL (f
)->delete_frame_hook
) (f
);
1671 terminal
= FRAME_TERMINAL (f
);
1672 f
->output_data
.nothing
= 0;
1673 f
->terminal
= 0; /* Now the frame is dead. */
1676 /* If needed, delete the terminal that this frame was on.
1677 (This must be done after the frame is killed.) */
1678 terminal
->reference_count
--;
1680 /* FIXME: Deleting the terminal crashes emacs because of a GTK
1682 http://lists.gnu.org/archive/html/emacs-devel/2011-10/msg00363.html */
1683 if (terminal
->reference_count
== 0 && terminal
->type
== output_x_window
)
1684 terminal
->reference_count
= 1;
1685 #endif /* USE_GTK */
1686 if (terminal
->reference_count
== 0)
1689 XSETTERMINAL (tmp
, terminal
);
1692 Fdelete_terminal (tmp
, NILP (force
) ? Qt
: force
);
1695 kb
= terminal
->kboard
;
1698 /* If we've deleted the last_nonminibuf_frame, then try to find
1700 if (f
== last_nonminibuf_frame
)
1702 Lisp_Object frames
, this;
1704 last_nonminibuf_frame
= 0;
1706 FOR_EACH_FRAME (frames
, this)
1709 if (!FRAME_MINIBUF_ONLY_P (f
))
1711 last_nonminibuf_frame
= f
;
1717 /* If there's no other frame on the same kboard, get out of
1718 single-kboard state if we're in it for this kboard. */
1721 Lisp_Object frames
, this;
1722 /* Some frame we found on the same kboard, or nil if there are none. */
1723 Lisp_Object frame_on_same_kboard
= Qnil
;
1725 FOR_EACH_FRAME (frames
, this)
1726 if (kb
== FRAME_KBOARD (XFRAME (this)))
1727 frame_on_same_kboard
= this;
1729 if (NILP (frame_on_same_kboard
))
1730 not_single_kboard_state (kb
);
1734 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1735 find another one. Prefer minibuffer-only frames, but also notice
1736 frames with other windows. */
1737 if (kb
!= NULL
&& EQ (frame
, KVAR (kb
, Vdefault_minibuffer_frame
)))
1739 Lisp_Object frames
, this;
1741 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1742 Lisp_Object frame_with_minibuf
= Qnil
;
1743 /* Some frame we found on the same kboard, or nil if there are none. */
1744 Lisp_Object frame_on_same_kboard
= Qnil
;
1746 FOR_EACH_FRAME (frames
, this)
1748 struct frame
*f1
= XFRAME (this);
1750 /* Consider only frames on the same kboard
1751 and only those with minibuffers. */
1752 if (kb
== FRAME_KBOARD (f1
)
1753 && FRAME_HAS_MINIBUF_P (f1
))
1755 frame_with_minibuf
= this;
1756 if (FRAME_MINIBUF_ONLY_P (f1
))
1760 if (kb
== FRAME_KBOARD (f1
))
1761 frame_on_same_kboard
= this;
1764 if (!NILP (frame_on_same_kboard
))
1766 /* We know that there must be some frame with a minibuffer out
1767 there. If this were not true, all of the frames present
1768 would have to be minibufferless, which implies that at some
1769 point their minibuffer frames must have been deleted, but
1770 that is prohibited at the top; you can't delete surrogate
1771 minibuffer frames. */
1772 if (NILP (frame_with_minibuf
))
1775 kset_default_minibuffer_frame (kb
, frame_with_minibuf
);
1778 /* No frames left on this kboard--say no minibuffer either. */
1779 kset_default_minibuffer_frame (kb
, Qnil
);
1782 /* Cause frame titles to update--necessary if we now have just one frame. */
1783 if (!is_tooltip_frame
)
1784 update_mode_lines
= 15;
1789 DEFUN ("delete-frame", Fdelete_frame
, Sdelete_frame
, 0, 2, "",
1790 doc
: /* Delete FRAME, permanently eliminating it from use.
1791 FRAME defaults to the selected frame.
1793 A frame may not be deleted if its minibuffer is used by other frames.
1794 Normally, you may not delete a frame if all other frames are invisible,
1795 but if the second optional argument FORCE is non-nil, you may do so.
1797 This function runs `delete-frame-functions' before actually
1798 deleting the frame, unless the frame is a tooltip.
1799 The functions are run with one argument, the frame to be deleted. */)
1800 (Lisp_Object frame
, Lisp_Object force
)
1802 return delete_frame (frame
, !NILP (force
) ? Qt
: Qnil
);
1806 /* Return mouse position in character cell units. */
1808 DEFUN ("mouse-position", Fmouse_position
, Smouse_position
, 0, 0, 0,
1809 doc
: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1810 The position is given in canonical character cells, where (0, 0) is the
1811 upper-left corner of the frame, X is the horizontal offset, and Y is the
1812 vertical offset, measured in units of the frame's default character size.
1813 If Emacs is running on a mouseless terminal or hasn't been programmed
1814 to read the mouse position, it returns the selected frame for FRAME
1815 and nil for X and Y.
1816 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1817 passing the normal return value to that function as an argument,
1818 and returns whatever that function returns. */)
1822 Lisp_Object lispy_dummy
;
1823 Lisp_Object x
, y
, retval
;
1824 struct gcpro gcpro1
;
1826 f
= SELECTED_FRAME ();
1829 /* It's okay for the hook to refrain from storing anything. */
1830 if (FRAME_TERMINAL (f
)->mouse_position_hook
)
1832 enum scroll_bar_part party_dummy
;
1834 (*FRAME_TERMINAL (f
)->mouse_position_hook
) (&f
, -1,
1835 &lispy_dummy
, &party_dummy
,
1844 pixel_to_glyph_coords (f
, col
, row
, &col
, &row
, NULL
, 1);
1848 XSETFRAME (lispy_dummy
, f
);
1849 retval
= Fcons (lispy_dummy
, Fcons (x
, y
));
1851 if (!NILP (Vmouse_position_function
))
1852 retval
= call1 (Vmouse_position_function
, retval
);
1853 RETURN_UNGCPRO (retval
);
1856 DEFUN ("mouse-pixel-position", Fmouse_pixel_position
,
1857 Smouse_pixel_position
, 0, 0, 0,
1858 doc
: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1859 The position is given in pixel units, where (0, 0) is the
1860 upper-left corner of the frame, X is the horizontal offset, and Y is
1861 the vertical offset.
1862 If Emacs is running on a mouseless terminal or hasn't been programmed
1863 to read the mouse position, it returns the selected frame for FRAME
1864 and nil for X and Y. */)
1868 Lisp_Object lispy_dummy
;
1869 Lisp_Object x
, y
, retval
;
1870 struct gcpro gcpro1
;
1872 f
= SELECTED_FRAME ();
1875 /* It's okay for the hook to refrain from storing anything. */
1876 if (FRAME_TERMINAL (f
)->mouse_position_hook
)
1878 enum scroll_bar_part party_dummy
;
1880 (*FRAME_TERMINAL (f
)->mouse_position_hook
) (&f
, -1,
1881 &lispy_dummy
, &party_dummy
,
1886 XSETFRAME (lispy_dummy
, f
);
1887 retval
= Fcons (lispy_dummy
, Fcons (x
, y
));
1889 if (!NILP (Vmouse_position_function
))
1890 retval
= call1 (Vmouse_position_function
, retval
);
1891 RETURN_UNGCPRO (retval
);
1894 #ifdef HAVE_WINDOW_SYSTEM
1896 /* On frame F, convert character coordinates X and Y to pixel
1897 coordinates *PIX_X and *PIX_Y. */
1900 frame_char_to_pixel_position (struct frame
*f
, int x
, int y
,
1901 int *pix_x
, int *pix_y
)
1903 *pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
1904 *pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
1908 if (*pix_x
> FRAME_PIXEL_WIDTH (f
))
1909 *pix_x
= FRAME_PIXEL_WIDTH (f
);
1913 if (*pix_y
> FRAME_PIXEL_HEIGHT (f
))
1914 *pix_y
= FRAME_PIXEL_HEIGHT (f
);
1917 /* On frame F, reposition mouse pointer to character coordinates X and Y. */
1920 frame_set_mouse_position (struct frame
*f
, int x
, int y
)
1924 frame_char_to_pixel_position (f
, x
, y
, &pix_x
, &pix_y
);
1925 frame_set_mouse_pixel_position (f
, pix_x
, pix_y
);
1928 #endif /* HAVE_WINDOW_SYSTEM */
1930 DEFUN ("set-mouse-position", Fset_mouse_position
, Sset_mouse_position
, 3, 3, 0,
1931 doc
: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1932 Coordinates are relative to the frame, not a window,
1933 so the coordinates of the top left character in the frame
1934 may be nonzero due to left-hand scroll bars or the menu bar.
1936 The position is given in canonical character cells, where (0, 0) is
1937 the upper-left corner of the frame, X is the horizontal offset, and
1938 Y is the vertical offset, measured in units of the frame's default
1941 This function is a no-op for an X frame that is not visible.
1942 If you have just created a frame, you must wait for it to become visible
1943 before calling this function on it, like this.
1944 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1945 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
1947 CHECK_LIVE_FRAME (frame
);
1948 CHECK_TYPE_RANGED_INTEGER (int, x
);
1949 CHECK_TYPE_RANGED_INTEGER (int, y
);
1951 /* I think this should be done with a hook. */
1952 #ifdef HAVE_WINDOW_SYSTEM
1953 if (FRAME_WINDOW_P (XFRAME (frame
)))
1954 /* Warping the mouse will cause enternotify and focus events. */
1955 frame_set_mouse_position (XFRAME (frame
), XINT (x
), XINT (y
));
1958 if (FRAME_MSDOS_P (XFRAME (frame
)))
1960 Fselect_frame (frame
, Qnil
);
1961 mouse_moveto (XINT (x
), XINT (y
));
1966 Fselect_frame (frame
, Qnil
);
1967 term_mouse_moveto (XINT (x
), XINT (y
));
1976 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position
,
1977 Sset_mouse_pixel_position
, 3, 3, 0,
1978 doc
: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1979 The position is given in pixels, where (0, 0) is the upper-left corner
1980 of the frame, X is the horizontal offset, and Y is the vertical offset.
1982 Note, this is a no-op for an X frame that is not visible.
1983 If you have just created a frame, you must wait for it to become visible
1984 before calling this function on it, like this.
1985 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1986 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
1988 CHECK_LIVE_FRAME (frame
);
1989 CHECK_TYPE_RANGED_INTEGER (int, x
);
1990 CHECK_TYPE_RANGED_INTEGER (int, y
);
1992 /* I think this should be done with a hook. */
1993 #ifdef HAVE_WINDOW_SYSTEM
1994 if (FRAME_WINDOW_P (XFRAME (frame
)))
1995 /* Warping the mouse will cause enternotify and focus events. */
1996 frame_set_mouse_pixel_position (XFRAME (frame
), XINT (x
), XINT (y
));
1999 if (FRAME_MSDOS_P (XFRAME (frame
)))
2001 Fselect_frame (frame
, Qnil
);
2002 mouse_moveto (XINT (x
), XINT (y
));
2007 Fselect_frame (frame
, Qnil
);
2008 term_mouse_moveto (XINT (x
), XINT (y
));
2017 static void make_frame_visible_1 (Lisp_Object
);
2019 DEFUN ("make-frame-visible", Fmake_frame_visible
, Smake_frame_visible
,
2021 doc
: /* Make the frame FRAME visible (assuming it is an X window).
2022 If omitted, FRAME defaults to the currently selected frame. */)
2025 struct frame
*f
= decode_live_frame (frame
);
2027 /* I think this should be done with a hook. */
2028 #ifdef HAVE_WINDOW_SYSTEM
2029 if (FRAME_WINDOW_P (f
))
2030 x_make_frame_visible (f
);
2033 make_frame_visible_1 (f
->root_window
);
2035 /* Make menu bar update for the Buffers and Frames menus. */
2036 /* windows_or_buffers_changed = 15; FIXME: Why? */
2038 XSETFRAME (frame
, f
);
2042 /* Update the display_time slot of the buffers shown in WINDOW
2043 and all its descendants. */
2046 make_frame_visible_1 (Lisp_Object window
)
2050 for (; !NILP (window
); window
= w
->next
)
2052 w
= XWINDOW (window
);
2053 if (WINDOWP (w
->contents
))
2054 make_frame_visible_1 (w
->contents
);
2056 bset_display_time (XBUFFER (w
->contents
), Fcurrent_time ());
2060 DEFUN ("make-frame-invisible", Fmake_frame_invisible
, Smake_frame_invisible
,
2062 doc
: /* Make the frame FRAME invisible.
2063 If omitted, FRAME defaults to the currently selected frame.
2064 On graphical displays, invisible frames are not updated and are
2065 usually not displayed at all, even in a window system's \"taskbar\".
2067 Normally you may not make FRAME invisible if all other frames are invisible,
2068 but if the second optional argument FORCE is non-nil, you may do so.
2070 This function has no effect on text terminal frames. Such frames are
2071 always considered visible, whether or not they are currently being
2072 displayed in the terminal. */)
2073 (Lisp_Object frame
, Lisp_Object force
)
2075 struct frame
*f
= decode_live_frame (frame
);
2077 if (NILP (force
) && !other_visible_frames (f
))
2078 error ("Attempt to make invisible the sole visible or iconified frame");
2080 /* Don't allow minibuf_window to remain on an invisible frame. */
2081 check_minibuf_window (frame
, EQ (minibuf_window
, selected_window
));
2083 /* I think this should be done with a hook. */
2084 #ifdef HAVE_WINDOW_SYSTEM
2085 if (FRAME_WINDOW_P (f
))
2086 x_make_frame_invisible (f
);
2089 /* Make menu bar update for the Buffers and Frames menus. */
2090 windows_or_buffers_changed
= 16;
2095 DEFUN ("iconify-frame", Ficonify_frame
, Siconify_frame
,
2097 doc
: /* Make the frame FRAME into an icon.
2098 If omitted, FRAME defaults to the currently selected frame. */)
2101 struct frame
*f
= decode_live_frame (frame
);
2103 /* Don't allow minibuf_window to remain on an iconified frame. */
2104 check_minibuf_window (frame
, EQ (minibuf_window
, selected_window
));
2106 /* I think this should be done with a hook. */
2107 #ifdef HAVE_WINDOW_SYSTEM
2108 if (FRAME_WINDOW_P (f
))
2109 x_iconify_frame (f
);
2112 /* Make menu bar update for the Buffers and Frames menus. */
2113 windows_or_buffers_changed
= 17;
2118 DEFUN ("frame-visible-p", Fframe_visible_p
, Sframe_visible_p
,
2120 doc
: /* Return t if FRAME is \"visible\" (actually in use for display).
2121 Return the symbol `icon' if FRAME is iconified or \"minimized\".
2122 Return nil if FRAME was made invisible, via `make-frame-invisible'.
2123 On graphical displays, invisible frames are not updated and are
2124 usually not displayed at all, even in a window system's \"taskbar\".
2126 If FRAME is a text terminal frame, this always returns t.
2127 Such frames are always considered visible, whether or not they are
2128 currently being displayed on the terminal. */)
2131 CHECK_LIVE_FRAME (frame
);
2133 if (FRAME_VISIBLE_P (XFRAME (frame
)))
2135 if (FRAME_ICONIFIED_P (XFRAME (frame
)))
2140 DEFUN ("visible-frame-list", Fvisible_frame_list
, Svisible_frame_list
,
2142 doc
: /* Return a list of all frames now \"visible\" (being updated). */)
2145 Lisp_Object tail
, frame
, value
= Qnil
;
2147 FOR_EACH_FRAME (tail
, frame
)
2148 if (FRAME_VISIBLE_P (XFRAME (frame
)))
2149 value
= Fcons (frame
, value
);
2155 DEFUN ("raise-frame", Fraise_frame
, Sraise_frame
, 0, 1, "",
2156 doc
: /* Bring FRAME to the front, so it occludes any frames it overlaps.
2157 If FRAME is invisible or iconified, make it visible.
2158 If you don't specify a frame, the selected frame is used.
2159 If Emacs is displaying on an ordinary terminal or some other device which
2160 doesn't support multiple overlapping frames, this function selects FRAME. */)
2163 struct frame
*f
= decode_live_frame (frame
);
2165 XSETFRAME (frame
, f
);
2167 if (FRAME_TERMCAP_P (f
))
2168 /* On a text terminal select FRAME. */
2169 Fselect_frame (frame
, Qnil
);
2171 /* Do like the documentation says. */
2172 Fmake_frame_visible (frame
);
2174 if (FRAME_TERMINAL (f
)->frame_raise_lower_hook
)
2175 (*FRAME_TERMINAL (f
)->frame_raise_lower_hook
) (f
, 1);
2180 /* Should we have a corresponding function called Flower_Power? */
2181 DEFUN ("lower-frame", Flower_frame
, Slower_frame
, 0, 1, "",
2182 doc
: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2183 If you don't specify a frame, the selected frame is used.
2184 If Emacs is displaying on an ordinary terminal or some other device which
2185 doesn't support multiple overlapping frames, this function does nothing. */)
2188 struct frame
*f
= decode_live_frame (frame
);
2190 if (FRAME_TERMINAL (f
)->frame_raise_lower_hook
)
2191 (*FRAME_TERMINAL (f
)->frame_raise_lower_hook
) (f
, 0);
2197 DEFUN ("redirect-frame-focus", Fredirect_frame_focus
, Sredirect_frame_focus
,
2199 doc
: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2200 In other words, switch-frame events caused by events in FRAME will
2201 request a switch to FOCUS-FRAME, and `last-event-frame' will be
2202 FOCUS-FRAME after reading an event typed at FRAME.
2204 If FOCUS-FRAME is nil, any existing redirection is canceled, and the
2205 frame again receives its own keystrokes.
2207 Focus redirection is useful for temporarily redirecting keystrokes to
2208 a surrogate minibuffer frame when a frame doesn't have its own
2211 A frame's focus redirection can be changed by `select-frame'. If frame
2212 FOO is selected, and then a different frame BAR is selected, any
2213 frames redirecting their focus to FOO are shifted to redirect their
2214 focus to BAR. This allows focus redirection to work properly when the
2215 user switches from one frame to another using `select-window'.
2217 This means that a frame whose focus is redirected to itself is treated
2218 differently from a frame whose focus is redirected to nil; the former
2219 is affected by `select-frame', while the latter is not.
2221 The redirection lasts until `redirect-frame-focus' is called to change it. */)
2222 (Lisp_Object frame
, Lisp_Object focus_frame
)
2224 /* Note that we don't check for a live frame here. It's reasonable
2225 to redirect the focus of a frame you're about to delete, if you
2226 know what other frame should receive those keystrokes. */
2227 struct frame
*f
= decode_any_frame (frame
);
2229 if (! NILP (focus_frame
))
2230 CHECK_LIVE_FRAME (focus_frame
);
2232 fset_focus_frame (f
, focus_frame
);
2234 if (FRAME_TERMINAL (f
)->frame_rehighlight_hook
)
2235 (*FRAME_TERMINAL (f
)->frame_rehighlight_hook
) (f
);
2241 DEFUN ("frame-focus", Fframe_focus
, Sframe_focus
, 0, 1, 0,
2242 doc
: /* Return the frame to which FRAME's keystrokes are currently being sent.
2243 If FRAME is omitted or nil, the selected frame is used.
2244 Return nil if FRAME's focus is not redirected.
2245 See `redirect-frame-focus'. */)
2248 return FRAME_FOCUS_FRAME (decode_live_frame (frame
));
2251 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 1, 0,
2252 doc
: /* Set the input focus to FRAME.
2253 FRAME nil means use the selected frame.
2254 If there is no window system support, this function does nothing. */)
2257 #ifdef HAVE_WINDOW_SYSTEM
2258 x_focus_frame (decode_window_system_frame (frame
));
2263 DEFUN ("frame-can-run-window-configuration-change-hook",
2264 Fcan_run_window_configuration_change_hook
,
2265 Scan_run_window_configuration_change_hook
, 2, 2, 0,
2266 doc
: /* Whether `window-configuration-change-hook' is run for frame FRAME.
2267 FRAME nil means use the selected frame. Second argument ALLOW non-nil
2268 means functions on `window-configuration-change-hook' are called
2269 whenever the window configuration of FRAME changes. ALLOW nil means
2270 these functions are not called.
2272 This function is currently called by `face-set-after-frame-default' only
2273 and should be otherwise used with utter care to avoid that running
2274 functions on `window-configuration-change-hook' is impeded forever. */)
2275 (Lisp_Object frame
, Lisp_Object allow
)
2277 struct frame
*f
= decode_live_frame (frame
);
2279 f
->can_run_window_configuration_change_hook
= NILP (allow
) ? false : true;
2283 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2286 frames_discard_buffer (Lisp_Object buffer
)
2288 Lisp_Object frame
, tail
;
2290 FOR_EACH_FRAME (tail
, frame
)
2293 (XFRAME (frame
), Fdelq (buffer
, XFRAME (frame
)->buffer_list
));
2294 fset_buried_buffer_list
2295 (XFRAME (frame
), Fdelq (buffer
, XFRAME (frame
)->buried_buffer_list
));
2299 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2300 If the alist already has an element for PROP, we change it. */
2303 store_in_alist (Lisp_Object
*alistptr
, Lisp_Object prop
, Lisp_Object val
)
2305 register Lisp_Object tem
;
2307 tem
= Fassq (prop
, *alistptr
);
2309 *alistptr
= Fcons (Fcons (prop
, val
), *alistptr
);
2315 frame_name_fnn_p (char *str
, ptrdiff_t len
)
2317 if (len
> 1 && str
[0] == 'F' && '0' <= str
[1] && str
[1] <= '9')
2320 while ('0' <= *p
&& *p
<= '9')
2328 /* Set the name of the terminal frame. Also used by MSDOS frames.
2329 Modeled after x_set_name which is used for WINDOW frames. */
2332 set_term_frame_name (struct frame
*f
, Lisp_Object name
)
2334 f
->explicit_name
= ! NILP (name
);
2336 /* If NAME is nil, set the name to F<num>. */
2339 char namebuf
[sizeof "F" + INT_STRLEN_BOUND (printmax_t
)];
2341 /* Check for no change needed in this very common case
2342 before we do any consing. */
2343 if (frame_name_fnn_p (SSDATA (f
->name
), SBYTES (f
->name
)))
2346 name
= make_formatted_string (namebuf
, "F%"pMd
, ++tty_frame_count
);
2350 CHECK_STRING (name
);
2352 /* Don't change the name if it's already NAME. */
2353 if (! NILP (Fstring_equal (name
, f
->name
)))
2356 /* Don't allow the user to set the frame name to F<num>, so it
2357 doesn't clash with the names we generate for terminal frames. */
2358 if (frame_name_fnn_p (SSDATA (name
), SBYTES (name
)))
2359 error ("Frame names of the form F<num> are usurped by Emacs");
2362 fset_name (f
, name
);
2363 update_mode_lines
= 16;
2367 store_frame_param (struct frame
*f
, Lisp_Object prop
, Lisp_Object val
)
2369 register Lisp_Object old_alist_elt
;
2371 /* The buffer-list parameters are stored in a special place and not
2372 in the alist. All buffers must be live. */
2373 if (EQ (prop
, Qbuffer_list
))
2375 Lisp_Object list
= Qnil
;
2376 for (; CONSP (val
); val
= XCDR (val
))
2377 if (!NILP (Fbuffer_live_p (XCAR (val
))))
2378 list
= Fcons (XCAR (val
), list
);
2379 fset_buffer_list (f
, Fnreverse (list
));
2382 if (EQ (prop
, Qburied_buffer_list
))
2384 Lisp_Object list
= Qnil
;
2385 for (; CONSP (val
); val
= XCDR (val
))
2386 if (!NILP (Fbuffer_live_p (XCAR (val
))))
2387 list
= Fcons (XCAR (val
), list
);
2388 fset_buried_buffer_list (f
, Fnreverse (list
));
2392 /* If PROP is a symbol which is supposed to have frame-local values,
2393 and it is set up based on this frame, switch to the global
2394 binding. That way, we can create or alter the frame-local binding
2395 without messing up the symbol's status. */
2398 struct Lisp_Symbol
*sym
= XSYMBOL (prop
);
2400 switch (sym
->redirect
)
2402 case SYMBOL_VARALIAS
: sym
= indirect_variable (sym
); goto start
;
2403 case SYMBOL_PLAINVAL
: case SYMBOL_FORWARDED
: break;
2404 case SYMBOL_LOCALIZED
:
2405 { struct Lisp_Buffer_Local_Value
*blv
= sym
->val
.blv
;
2406 if (blv
->frame_local
&& blv_found (blv
) && XFRAME (blv
->where
) == f
)
2407 swap_in_global_binding (sym
);
2410 default: emacs_abort ();
2414 /* The tty color needed to be set before the frame's parameter
2415 alist was updated with the new value. This is not true any more,
2416 but we still do this test early on. */
2417 if (FRAME_TERMCAP_P (f
) && EQ (prop
, Qtty_color_mode
)
2418 && f
== FRAME_TTY (f
)->previous_frame
)
2419 /* Force redisplay of this tty. */
2420 FRAME_TTY (f
)->previous_frame
= NULL
;
2422 /* Update the frame parameter alist. */
2423 old_alist_elt
= Fassq (prop
, f
->param_alist
);
2424 if (EQ (old_alist_elt
, Qnil
))
2425 fset_param_alist (f
, Fcons (Fcons (prop
, val
), f
->param_alist
));
2427 Fsetcdr (old_alist_elt
, val
);
2429 /* Update some other special parameters in their special places
2430 in addition to the alist. */
2432 if (EQ (prop
, Qbuffer_predicate
))
2433 fset_buffer_predicate (f
, val
);
2435 if (! FRAME_WINDOW_P (f
))
2437 if (EQ (prop
, Qmenu_bar_lines
))
2438 set_menu_bar_lines (f
, val
, make_number (FRAME_MENU_BAR_LINES (f
)));
2439 else if (EQ (prop
, Qname
))
2440 set_term_frame_name (f
, val
);
2443 if (EQ (prop
, Qminibuffer
) && WINDOWP (val
))
2445 if (! MINI_WINDOW_P (XWINDOW (val
)))
2446 error ("Surrogate minibuffer windows must be minibuffer windows");
2448 if ((FRAME_HAS_MINIBUF_P (f
) || FRAME_MINIBUF_ONLY_P (f
))
2449 && !EQ (val
, f
->minibuffer_window
))
2450 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2452 /* Install the chosen minibuffer window, with proper buffer. */
2453 fset_minibuffer_window (f
, val
);
2457 /* Return color matches UNSPEC on frame F or nil if UNSPEC
2458 is not an unspecified foreground or background color. */
2461 frame_unspecified_color (struct frame
*f
, Lisp_Object unspec
)
2463 return (!strncmp (SSDATA (unspec
), unspecified_bg
, SBYTES (unspec
))
2464 ? tty_color_name (f
, FRAME_BACKGROUND_PIXEL (f
))
2465 : (!strncmp (SSDATA (unspec
), unspecified_fg
, SBYTES (unspec
))
2466 ? tty_color_name (f
, FRAME_FOREGROUND_PIXEL (f
)) : Qnil
));
2469 DEFUN ("frame-parameters", Fframe_parameters
, Sframe_parameters
, 0, 1, 0,
2470 doc
: /* Return the parameters-alist of frame FRAME.
2471 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2472 The meaningful PARMs depend on the kind of frame.
2473 If FRAME is omitted or nil, return information on the currently selected frame. */)
2477 struct frame
*f
= decode_any_frame (frame
);
2479 struct gcpro gcpro1
;
2481 if (!FRAME_LIVE_P (f
))
2484 alist
= Fcopy_alist (f
->param_alist
);
2487 if (!FRAME_WINDOW_P (f
))
2491 /* If the frame's parameter alist says the colors are
2492 unspecified and reversed, take the frame's background pixel
2493 for foreground and vice versa. */
2494 elt
= Fassq (Qforeground_color
, alist
);
2495 if (CONSP (elt
) && STRINGP (XCDR (elt
)))
2497 elt
= frame_unspecified_color (f
, XCDR (elt
));
2499 store_in_alist (&alist
, Qforeground_color
, elt
);
2502 store_in_alist (&alist
, Qforeground_color
,
2503 tty_color_name (f
, FRAME_FOREGROUND_PIXEL (f
)));
2504 elt
= Fassq (Qbackground_color
, alist
);
2505 if (CONSP (elt
) && STRINGP (XCDR (elt
)))
2507 elt
= frame_unspecified_color (f
, XCDR (elt
));
2509 store_in_alist (&alist
, Qbackground_color
, elt
);
2512 store_in_alist (&alist
, Qbackground_color
,
2513 tty_color_name (f
, FRAME_BACKGROUND_PIXEL (f
)));
2514 store_in_alist (&alist
, intern ("font"),
2515 build_string (FRAME_MSDOS_P (f
)
2517 : FRAME_W32_P (f
) ? "w32term"
2520 store_in_alist (&alist
, Qname
, f
->name
);
2521 height
= (f
->new_height
2523 ? (f
->new_height
/ FRAME_LINE_HEIGHT (f
))
2526 store_in_alist (&alist
, Qheight
, make_number (height
));
2527 width
= (f
->new_width
2529 ? (f
->new_width
/ FRAME_COLUMN_WIDTH (f
))
2532 store_in_alist (&alist
, Qwidth
, make_number (width
));
2533 store_in_alist (&alist
, Qmodeline
, (FRAME_WANTS_MODELINE_P (f
) ? Qt
: Qnil
));
2534 store_in_alist (&alist
, Qminibuffer
,
2535 (! FRAME_HAS_MINIBUF_P (f
) ? Qnil
2536 : FRAME_MINIBUF_ONLY_P (f
) ? Qonly
2537 : FRAME_MINIBUF_WINDOW (f
)));
2538 store_in_alist (&alist
, Qunsplittable
, (FRAME_NO_SPLIT_P (f
) ? Qt
: Qnil
));
2539 store_in_alist (&alist
, Qbuffer_list
, f
->buffer_list
);
2540 store_in_alist (&alist
, Qburied_buffer_list
, f
->buried_buffer_list
);
2542 /* I think this should be done with a hook. */
2543 #ifdef HAVE_WINDOW_SYSTEM
2544 if (FRAME_WINDOW_P (f
))
2545 x_report_frame_params (f
, &alist
);
2549 /* This ought to be correct in f->param_alist for an X frame. */
2551 XSETFASTINT (lines
, FRAME_MENU_BAR_LINES (f
));
2552 store_in_alist (&alist
, Qmenu_bar_lines
, lines
);
2560 DEFUN ("frame-parameter", Fframe_parameter
, Sframe_parameter
, 2, 2, 0,
2561 doc
: /* Return FRAME's value for parameter PARAMETER.
2562 If FRAME is nil, describe the currently selected frame. */)
2563 (Lisp_Object frame
, Lisp_Object parameter
)
2565 struct frame
*f
= decode_any_frame (frame
);
2566 Lisp_Object value
= Qnil
;
2568 CHECK_SYMBOL (parameter
);
2570 XSETFRAME (frame
, f
);
2572 if (FRAME_LIVE_P (f
))
2574 /* Avoid consing in frequent cases. */
2575 if (EQ (parameter
, Qname
))
2577 #ifdef HAVE_X_WINDOWS
2578 else if (EQ (parameter
, Qdisplay
) && FRAME_X_P (f
))
2579 value
= XCAR (FRAME_DISPLAY_INFO (f
)->name_list_element
);
2580 #endif /* HAVE_X_WINDOWS */
2581 else if (EQ (parameter
, Qbackground_color
)
2582 || EQ (parameter
, Qforeground_color
))
2584 value
= Fassq (parameter
, f
->param_alist
);
2587 value
= XCDR (value
);
2588 /* Fframe_parameters puts the actual fg/bg color names,
2589 even if f->param_alist says otherwise. This is
2590 important when param_alist's notion of colors is
2591 "unspecified". We need to do the same here. */
2592 if (STRINGP (value
) && !FRAME_WINDOW_P (f
))
2593 value
= frame_unspecified_color (f
, value
);
2596 value
= Fcdr (Fassq (parameter
, Fframe_parameters (frame
)));
2598 else if (EQ (parameter
, Qdisplay_type
)
2599 || EQ (parameter
, Qbackground_mode
))
2600 value
= Fcdr (Fassq (parameter
, f
->param_alist
));
2602 /* FIXME: Avoid this code path at all (as well as code duplication)
2603 by sharing more code with Fframe_parameters. */
2604 value
= Fcdr (Fassq (parameter
, Fframe_parameters (frame
)));
2611 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters
,
2612 Smodify_frame_parameters
, 2, 2, 0,
2613 doc
: /* Modify the parameters of frame FRAME according to ALIST.
2614 If FRAME is nil, it defaults to the selected frame.
2615 ALIST is an alist of parameters to change and their new values.
2616 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2617 The meaningful PARMs depend on the kind of frame.
2618 Undefined PARMs are ignored, but stored in the frame's parameter list
2619 so that `frame-parameters' will return them.
2621 The value of frame parameter FOO can also be accessed
2622 as a frame-local binding for the variable FOO, if you have
2623 enabled such bindings for that variable with `make-variable-frame-local'.
2624 Note that this functionality is obsolete as of Emacs 22.2, and its
2625 use is not recommended. Explicitly check for a frame-parameter instead. */)
2626 (Lisp_Object frame
, Lisp_Object alist
)
2628 struct frame
*f
= decode_live_frame (frame
);
2629 register Lisp_Object prop
, val
;
2633 /* I think this should be done with a hook. */
2634 #ifdef HAVE_WINDOW_SYSTEM
2635 if (FRAME_WINDOW_P (f
))
2636 x_set_frame_parameters (f
, alist
);
2640 if (FRAME_MSDOS_P (f
))
2641 IT_set_frame_parameters (f
, alist
);
2646 EMACS_INT length
= XFASTINT (Flength (alist
));
2649 Lisp_Object
*values
;
2651 SAFE_ALLOCA_LISP (parms
, 2 * length
);
2652 values
= parms
+ length
;
2654 /* Extract parm names and values into those vectors. */
2656 for (i
= 0; CONSP (alist
); alist
= XCDR (alist
))
2661 parms
[i
] = Fcar (elt
);
2662 values
[i
] = Fcdr (elt
);
2666 /* Now process them in reverse of specified order. */
2671 store_frame_param (f
, prop
, val
);
2673 if (EQ (prop
, Qforeground_color
)
2674 || EQ (prop
, Qbackground_color
))
2675 update_face_from_frame_parameter (f
, prop
, val
);
2683 DEFUN ("frame-char-height", Fframe_char_height
, Sframe_char_height
,
2685 doc
: /* Height in pixels of a line in the font in frame FRAME.
2686 If FRAME is omitted or nil, the selected frame is used.
2687 For a terminal frame, the value is always 1. */)
2690 #ifdef HAVE_WINDOW_SYSTEM
2691 struct frame
*f
= decode_any_frame (frame
);
2693 if (FRAME_WINDOW_P (f
))
2694 return make_number (FRAME_LINE_HEIGHT (f
));
2697 return make_number (1);
2701 DEFUN ("frame-char-width", Fframe_char_width
, Sframe_char_width
,
2703 doc
: /* Width in pixels of characters in the font in frame FRAME.
2704 If FRAME is omitted or nil, the selected frame is used.
2705 On a graphical screen, the width is the standard width of the default font.
2706 For a terminal screen, the value is always 1. */)
2709 #ifdef HAVE_WINDOW_SYSTEM
2710 struct frame
*f
= decode_any_frame (frame
);
2712 if (FRAME_WINDOW_P (f
))
2713 return make_number (FRAME_COLUMN_WIDTH (f
));
2716 return make_number (1);
2719 DEFUN ("frame-pixel-height", Fframe_pixel_height
,
2720 Sframe_pixel_height
, 0, 1, 0,
2721 doc
: /* Return a FRAME's height in pixels.
2722 If FRAME is omitted or nil, the selected frame is used. The exact value
2723 of the result depends on the window-system and toolkit in use:
2725 In the Gtk+ version of Emacs, it includes only any window (including
2726 the minibuffer or echo area), mode line, and header line. It does not
2727 include the tool bar or menu bar.
2729 With other graphical versions, it also includes the tool bar and the
2732 For a text terminal, it includes the menu bar. In this case, the
2733 result is really in characters rather than pixels (i.e., is identical
2734 to `frame-height'). */)
2737 struct frame
*f
= decode_any_frame (frame
);
2739 #ifdef HAVE_WINDOW_SYSTEM
2740 if (FRAME_WINDOW_P (f
))
2741 return make_number (FRAME_PIXEL_HEIGHT (f
));
2744 return make_number (FRAME_TOTAL_LINES (f
));
2747 DEFUN ("frame-pixel-width", Fframe_pixel_width
,
2748 Sframe_pixel_width
, 0, 1, 0,
2749 doc
: /* Return FRAME's width in pixels.
2750 For a terminal frame, the result really gives the width in characters.
2751 If FRAME is omitted or nil, the selected frame is used. */)
2754 struct frame
*f
= decode_any_frame (frame
);
2756 #ifdef HAVE_WINDOW_SYSTEM
2757 if (FRAME_WINDOW_P (f
))
2758 return make_number (FRAME_PIXEL_WIDTH (f
));
2761 return make_number (FRAME_TOTAL_COLS (f
));
2764 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width
,
2765 Stool_bar_pixel_width
, 0, 1, 0,
2766 doc
: /* Return width in pixels of FRAME's tool bar.
2767 The result is greater than zero only when the tool bar is on the left
2768 or right side of FRAME. If FRAME is omitted or nil, the selected frame
2772 #ifdef FRAME_TOOLBAR_WIDTH
2773 struct frame
*f
= decode_any_frame (frame
);
2775 if (FRAME_WINDOW_P (f
))
2776 return make_number (FRAME_TOOLBAR_WIDTH (f
));
2778 return make_number (0);
2781 DEFUN ("frame-text-cols", Fframe_text_cols
, Sframe_text_cols
, 0, 1, 0,
2782 doc
: /* Return width in columns of FRAME's text area. */)
2785 return make_number (FRAME_COLS (decode_any_frame (frame
)));
2788 DEFUN ("frame-text-lines", Fframe_text_lines
, Sframe_text_lines
, 0, 1, 0,
2789 doc
: /* Return height in lines of FRAME's text area. */)
2792 return make_number (FRAME_LINES (decode_any_frame (frame
)));
2795 DEFUN ("frame-total-cols", Fframe_total_cols
, Sframe_total_cols
, 0, 1, 0,
2796 doc
: /* Return number of total columns of FRAME. */)
2799 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame
)));
2802 DEFUN ("frame-total-lines", Fframe_total_lines
, Sframe_total_lines
, 0, 1, 0,
2803 doc
: /* Return number of total lines of FRAME. */)
2806 return make_number (FRAME_TOTAL_LINES (decode_any_frame (frame
)));
2809 DEFUN ("frame-text-width", Fframe_text_width
, Sframe_text_width
, 0, 1, 0,
2810 doc
: /* Return text area width of FRAME in pixels. */)
2813 return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame
)));
2816 DEFUN ("frame-text-height", Fframe_text_height
, Sframe_text_height
, 0, 1, 0,
2817 doc
: /* Return text area height of FRAME in pixels. */)
2820 return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame
)));
2823 DEFUN ("frame-scroll-bar-width", Fscroll_bar_width
, Sscroll_bar_width
, 0, 1, 0,
2824 doc
: /* Return scroll bar width of FRAME in pixels. */)
2827 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame
)));
2830 DEFUN ("frame-scroll-bar-height", Fscroll_bar_height
, Sscroll_bar_height
, 0, 1, 0,
2831 doc
: /* Return scroll bar height of FRAME in pixels. */)
2834 return make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (decode_any_frame (frame
)));
2837 DEFUN ("frame-fringe-width", Ffringe_width
, Sfringe_width
, 0, 1, 0,
2838 doc
: /* Return fringe width of FRAME in pixels. */)
2841 return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame
)));
2844 DEFUN ("frame-border-width", Fborder_width
, Sborder_width
, 0, 1, 0,
2845 doc
: /* Return border width of FRAME in pixels. */)
2848 return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame
)));
2851 DEFUN ("frame-right-divider-width", Fright_divider_width
, Sright_divider_width
, 0, 1, 0,
2852 doc
: /* Return width (in pixels) of vertical window dividers on FRAME. */)
2855 return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame
)));
2858 DEFUN ("frame-bottom-divider-width", Fbottom_divider_width
, Sbottom_divider_width
, 0, 1, 0,
2859 doc
: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
2862 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame
)));
2865 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 4, 0,
2866 doc
: /* Set height of frame FRAME to HEIGHT lines.
2867 Optional third arg PRETEND non-nil means that redisplay should use
2868 HEIGHT lines but that the idea of the actual height of the frame should
2871 Optional fourth argument PIXELWISE non-nil means that FRAME should be
2872 HEIGHT pixels high. Note: When `frame-resize-pixelwise' is nil, some
2873 window managers may refuse to honor a HEIGHT that is not an integer
2874 multiple of the default frame font height. */)
2875 (Lisp_Object frame
, Lisp_Object height
, Lisp_Object pretend
, Lisp_Object pixelwise
)
2877 struct frame
*f
= decode_live_frame (frame
);
2880 CHECK_TYPE_RANGED_INTEGER (int, height
);
2882 pixel_height
= (!NILP (pixelwise
)
2884 : XINT (height
) * FRAME_LINE_HEIGHT (f
));
2885 if (pixel_height
!= FRAME_TEXT_HEIGHT (f
))
2886 adjust_frame_size (f
, -1, pixel_height
, 1, !NILP (pretend
), Qheight
);
2891 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 4, 0,
2892 doc
: /* Set width of frame FRAME to WIDTH columns.
2893 Optional third arg PRETEND non-nil means that redisplay should use WIDTH
2894 columns but that the idea of the actual width of the frame should not
2897 Optional fourth argument PIXELWISE non-nil means that FRAME should be
2898 WIDTH pixels wide. Note: When `frame-resize-pixelwise' is nil, some
2899 window managers may refuse to honor a WIDTH that is not an integer
2900 multiple of the default frame font width. */)
2901 (Lisp_Object frame
, Lisp_Object width
, Lisp_Object pretend
, Lisp_Object pixelwise
)
2903 struct frame
*f
= decode_live_frame (frame
);
2906 CHECK_TYPE_RANGED_INTEGER (int, width
);
2908 pixel_width
= (!NILP (pixelwise
)
2910 : XINT (width
) * FRAME_COLUMN_WIDTH (f
));
2911 if (pixel_width
!= FRAME_TEXT_WIDTH (f
))
2912 adjust_frame_size (f
, pixel_width
, -1, 1, !NILP (pretend
), Qwidth
);
2917 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 4, 0,
2918 doc
: /* Set size of FRAME to WIDTH by HEIGHT, measured in characters.
2919 Optional argument PIXELWISE non-nil means to measure in pixels. Note:
2920 When `frame-resize-pixelwise' is nil, some window managers may refuse to
2921 honor a WIDTH that is not an integer multiple of the default frame font
2922 width or a HEIGHT that is not an integer multiple of the default frame
2924 (Lisp_Object frame
, Lisp_Object width
, Lisp_Object height
, Lisp_Object pixelwise
)
2926 struct frame
*f
= decode_live_frame (frame
);
2927 int pixel_width
, pixel_height
;
2929 CHECK_TYPE_RANGED_INTEGER (int, width
);
2930 CHECK_TYPE_RANGED_INTEGER (int, height
);
2932 pixel_width
= (!NILP (pixelwise
)
2934 : XINT (width
) * FRAME_COLUMN_WIDTH (f
));
2935 pixel_height
= (!NILP (pixelwise
)
2937 : XINT (height
) * FRAME_LINE_HEIGHT (f
));
2939 if (pixel_width
!= FRAME_TEXT_WIDTH (f
)
2940 || pixel_height
!= FRAME_TEXT_HEIGHT (f
))
2941 adjust_frame_size (f
, pixel_width
, pixel_height
, 1, 0, Qsize
);
2946 DEFUN ("set-frame-position", Fset_frame_position
,
2947 Sset_frame_position
, 3, 3, 0,
2948 doc
: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2949 If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are
2950 actually the position of the upper left corner of the frame. Negative
2951 values for XOFFSET or YOFFSET are interpreted relative to the rightmost
2952 or bottommost possible position (that stays within the screen). */)
2953 (Lisp_Object frame
, Lisp_Object xoffset
, Lisp_Object yoffset
)
2955 register struct frame
*f
= decode_live_frame (frame
);
2957 CHECK_TYPE_RANGED_INTEGER (int, xoffset
);
2958 CHECK_TYPE_RANGED_INTEGER (int, yoffset
);
2960 /* I think this should be done with a hook. */
2961 #ifdef HAVE_WINDOW_SYSTEM
2962 if (FRAME_WINDOW_P (f
))
2963 x_set_offset (f
, XINT (xoffset
), XINT (yoffset
), 1);
2970 /***********************************************************************
2972 ***********************************************************************/
2974 /* Connect the frame-parameter names for X frames
2975 to the ways of passing the parameter values to the window system.
2977 The name of a parameter, as a Lisp symbol,
2978 has an `x-frame-parameter' property which is an integer in Lisp
2979 that is an index in this table. */
2981 struct frame_parm_table
{
2983 Lisp_Object
*variable
;
2986 static const struct frame_parm_table frame_parms
[] =
2988 {"auto-raise", &Qauto_raise
},
2989 {"auto-lower", &Qauto_lower
},
2990 {"background-color", 0},
2991 {"border-color", &Qborder_color
},
2992 {"border-width", &Qborder_width
},
2993 {"cursor-color", &Qcursor_color
},
2994 {"cursor-type", &Qcursor_type
},
2996 {"foreground-color", 0},
2997 {"icon-name", &Qicon_name
},
2998 {"icon-type", &Qicon_type
},
2999 {"internal-border-width", &Qinternal_border_width
},
3000 {"right-divider-width", &Qright_divider_width
},
3001 {"bottom-divider-width", &Qbottom_divider_width
},
3002 {"menu-bar-lines", &Qmenu_bar_lines
},
3003 {"mouse-color", &Qmouse_color
},
3005 {"scroll-bar-width", &Qscroll_bar_width
},
3006 {"scroll-bar-height", &Qscroll_bar_height
},
3008 {"unsplittable", &Qunsplittable
},
3009 {"vertical-scroll-bars", &Qvertical_scroll_bars
},
3010 {"horizontal-scroll-bars", &Qhorizontal_scroll_bars
},
3011 {"visibility", &Qvisibility
},
3012 {"tool-bar-lines", &Qtool_bar_lines
},
3013 {"scroll-bar-foreground", &Qscroll_bar_foreground
},
3014 {"scroll-bar-background", &Qscroll_bar_background
},
3015 {"screen-gamma", &Qscreen_gamma
},
3016 {"line-spacing", &Qline_spacing
},
3017 {"left-fringe", &Qleft_fringe
},
3018 {"right-fringe", &Qright_fringe
},
3019 {"wait-for-wm", &Qwait_for_wm
},
3020 {"fullscreen", &Qfullscreen
},
3021 {"font-backend", &Qfont_backend
},
3023 {"sticky", &Qsticky
},
3024 {"tool-bar-position", &Qtool_bar_position
},
3027 #ifdef HAVE_WINDOW_SYSTEM
3029 /* Change the parameters of frame F as specified by ALIST.
3030 If a parameter is not specially recognized, do nothing special;
3031 otherwise call the `x_set_...' function for that parameter.
3032 Except for certain geometry properties, always call store_frame_param
3033 to store the new value in the parameter alist. */
3036 x_set_frame_parameters (struct frame
*f
, Lisp_Object alist
)
3040 /* If both of these parameters are present, it's more efficient to
3041 set them both at once. So we wait until we've looked at the
3042 entire list before we set them. */
3043 int width
IF_LINT (= 0), height
IF_LINT (= 0);
3044 bool width_change
= 0, height_change
= 0;
3047 Lisp_Object left
, top
;
3049 /* Same with these. */
3050 Lisp_Object icon_left
, icon_top
;
3052 /* Record in these vectors all the parms specified. */
3054 Lisp_Object
*values
;
3056 bool left_no_change
= 0, top_no_change
= 0;
3057 #ifdef HAVE_X_WINDOWS
3058 bool icon_left_no_change
= 0, icon_top_no_change
= 0;
3062 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
3066 SAFE_ALLOCA_LISP (parms
, 2 * i
);
3069 /* Extract parm names and values into those vectors. */
3072 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
3077 parms
[i
] = Fcar (elt
);
3078 values
[i
] = Fcdr (elt
);
3081 /* TAIL and ALIST are not used again below here. */
3082 alist
= tail
= Qnil
;
3084 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
3085 because their values appear in VALUES and strings are not valid. */
3086 top
= left
= Qunbound
;
3087 icon_left
= icon_top
= Qunbound
;
3089 /* Process foreground_color and background_color before anything else.
3090 They are independent of other properties, but other properties (e.g.,
3091 cursor_color) are dependent upon them. */
3092 /* Process default font as well, since fringe widths depends on it. */
3093 for (p
= 0; p
< i
; p
++)
3095 Lisp_Object prop
, val
;
3099 if (EQ (prop
, Qforeground_color
)
3100 || EQ (prop
, Qbackground_color
)
3101 || EQ (prop
, Qfont
))
3103 register Lisp_Object param_index
, old_value
;
3105 old_value
= get_frame_param (f
, prop
);
3106 if (NILP (Fequal (val
, old_value
)))
3108 store_frame_param (f
, prop
, val
);
3110 param_index
= Fget (prop
, Qx_frame_parameter
);
3111 if (NATNUMP (param_index
)
3112 && XFASTINT (param_index
) < ARRAYELTS (frame_parms
)
3113 && FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])
3114 (*(FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])) (f
, val
, old_value
);
3119 /* Now process them in reverse of specified order. */
3122 Lisp_Object prop
, val
;
3127 if (EQ (prop
, Qwidth
) && RANGED_INTEGERP (0, val
, INT_MAX
))
3130 width
= XFASTINT (val
) * FRAME_COLUMN_WIDTH (f
) ;
3132 else if (EQ (prop
, Qheight
) && RANGED_INTEGERP (0, val
, INT_MAX
))
3135 height
= XFASTINT (val
) * FRAME_LINE_HEIGHT (f
);
3137 else if (EQ (prop
, Qtop
))
3139 else if (EQ (prop
, Qleft
))
3141 else if (EQ (prop
, Qicon_top
))
3143 else if (EQ (prop
, Qicon_left
))
3145 else if (EQ (prop
, Qforeground_color
)
3146 || EQ (prop
, Qbackground_color
)
3147 || EQ (prop
, Qfont
))
3148 /* Processed above. */
3152 register Lisp_Object param_index
, old_value
;
3154 old_value
= get_frame_param (f
, prop
);
3156 store_frame_param (f
, prop
, val
);
3158 param_index
= Fget (prop
, Qx_frame_parameter
);
3159 if (NATNUMP (param_index
)
3160 && XFASTINT (param_index
) < ARRAYELTS (frame_parms
)
3161 && FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])
3162 (*(FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])) (f
, val
, old_value
);
3166 /* Don't die if just one of these was set. */
3167 if (EQ (left
, Qunbound
))
3170 if (f
->left_pos
< 0)
3171 left
= list2 (Qplus
, make_number (f
->left_pos
));
3173 XSETINT (left
, f
->left_pos
);
3175 if (EQ (top
, Qunbound
))
3179 top
= list2 (Qplus
, make_number (f
->top_pos
));
3181 XSETINT (top
, f
->top_pos
);
3184 /* If one of the icon positions was not set, preserve or default it. */
3185 if (! TYPE_RANGED_INTEGERP (int, icon_left
))
3187 #ifdef HAVE_X_WINDOWS
3188 icon_left_no_change
= 1;
3190 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
3191 if (NILP (icon_left
))
3192 XSETINT (icon_left
, 0);
3194 if (! TYPE_RANGED_INTEGERP (int, icon_top
))
3196 #ifdef HAVE_X_WINDOWS
3197 icon_top_no_change
= 1;
3199 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
3200 if (NILP (icon_top
))
3201 XSETINT (icon_top
, 0);
3204 /* Don't set these parameters unless they've been explicitly
3205 specified. The window might be mapped or resized while we're in
3206 this function, and we don't want to override that unless the lisp
3207 code has asked for it.
3209 Don't set these parameters unless they actually differ from the
3210 window's current parameters; the window may not actually exist
3215 XSETFRAME (frame
, f
);
3217 if ((width_change
&& width
!= FRAME_TEXT_WIDTH (f
))
3218 || (height_change
&& height
!= FRAME_TEXT_HEIGHT (f
))
3219 || f
->new_height
|| f
->new_width
)
3221 /* If necessary provide default values for HEIGHT and WIDTH. Do
3222 that here since otherwise a size change implied by an
3223 intermittent font change may get lost as in Bug#17142. */
3225 width
= (f
->new_width
3228 : (f
->new_width
* FRAME_COLUMN_WIDTH (f
)))
3229 : FRAME_TEXT_WIDTH (f
));
3232 height
= (f
->new_height
3235 : (f
->new_height
* FRAME_LINE_HEIGHT (f
)))
3236 : FRAME_TEXT_HEIGHT (f
));
3238 Fset_frame_size (frame
, make_number (width
), make_number (height
), Qt
);
3241 if ((!NILP (left
) || !NILP (top
))
3242 && ! (left_no_change
&& top_no_change
)
3243 && ! (NUMBERP (left
) && XINT (left
) == f
->left_pos
3244 && NUMBERP (top
) && XINT (top
) == f
->top_pos
))
3249 /* Record the signs. */
3250 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
3251 if (EQ (left
, Qminus
))
3252 f
->size_hint_flags
|= XNegative
;
3253 else if (TYPE_RANGED_INTEGERP (int, left
))
3255 leftpos
= XINT (left
);
3257 f
->size_hint_flags
|= XNegative
;
3259 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
3260 && CONSP (XCDR (left
))
3261 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (left
)), INT_MAX
))
3263 leftpos
= - XINT (XCAR (XCDR (left
)));
3264 f
->size_hint_flags
|= XNegative
;
3266 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
3267 && CONSP (XCDR (left
))
3268 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left
))))
3270 leftpos
= XINT (XCAR (XCDR (left
)));
3273 if (EQ (top
, Qminus
))
3274 f
->size_hint_flags
|= YNegative
;
3275 else if (TYPE_RANGED_INTEGERP (int, top
))
3277 toppos
= XINT (top
);
3279 f
->size_hint_flags
|= YNegative
;
3281 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
3282 && CONSP (XCDR (top
))
3283 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (top
)), INT_MAX
))
3285 toppos
= - XINT (XCAR (XCDR (top
)));
3286 f
->size_hint_flags
|= YNegative
;
3288 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
3289 && CONSP (XCDR (top
))
3290 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top
))))
3292 toppos
= XINT (XCAR (XCDR (top
)));
3296 /* Store the numeric value of the position. */
3297 f
->top_pos
= toppos
;
3298 f
->left_pos
= leftpos
;
3300 f
->win_gravity
= NorthWestGravity
;
3302 /* Actually set that position, and convert to absolute. */
3303 x_set_offset (f
, leftpos
, toppos
, -1);
3305 #ifdef HAVE_X_WINDOWS
3306 if ((!NILP (icon_left
) || !NILP (icon_top
))
3307 && ! (icon_left_no_change
&& icon_top_no_change
))
3308 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
3309 #endif /* HAVE_X_WINDOWS */
3316 /* Insert a description of internally-recorded parameters of frame X
3317 into the parameter alist *ALISTPTR that is to be given to the user.
3318 Only parameters that are specific to the X window system
3319 and whose values are not correctly recorded in the frame's
3320 param_alist need to be considered here. */
3323 x_report_frame_params (struct frame
*f
, Lisp_Object
*alistptr
)
3327 char buf
[INT_BUFSIZE_BOUND (w
)];
3329 /* Represent negative positions (off the top or left screen edge)
3330 in a way that Fmodify_frame_parameters will understand correctly. */
3331 XSETINT (tem
, f
->left_pos
);
3332 if (f
->left_pos
>= 0)
3333 store_in_alist (alistptr
, Qleft
, tem
);
3335 store_in_alist (alistptr
, Qleft
, list2 (Qplus
, tem
));
3337 XSETINT (tem
, f
->top_pos
);
3338 if (f
->top_pos
>= 0)
3339 store_in_alist (alistptr
, Qtop
, tem
);
3341 store_in_alist (alistptr
, Qtop
, list2 (Qplus
, tem
));
3343 store_in_alist (alistptr
, Qborder_width
,
3344 make_number (f
->border_width
));
3345 store_in_alist (alistptr
, Qinternal_border_width
,
3346 make_number (FRAME_INTERNAL_BORDER_WIDTH (f
)));
3347 store_in_alist (alistptr
, Qright_divider_width
,
3348 make_number (FRAME_RIGHT_DIVIDER_WIDTH (f
)));
3349 store_in_alist (alistptr
, Qbottom_divider_width
,
3350 make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f
)));
3351 store_in_alist (alistptr
, Qleft_fringe
,
3352 make_number (FRAME_LEFT_FRINGE_WIDTH (f
)));
3353 store_in_alist (alistptr
, Qright_fringe
,
3354 make_number (FRAME_RIGHT_FRINGE_WIDTH (f
)));
3355 store_in_alist (alistptr
, Qscroll_bar_width
,
3356 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
3358 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0
3359 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
))
3360 /* nil means "use default width"
3361 for non-toolkit scroll bar.
3362 ruler-mode.el depends on this. */
3364 store_in_alist (alistptr
, Qscroll_bar_height
,
3365 (! FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
)
3367 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) > 0
3368 ? make_number (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
))
3369 /* nil means "use default height"
3370 for non-toolkit scroll bar. */
3372 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
3373 MS-Windows it returns a value whose type is HANDLE, which is
3374 actually a pointer. Explicit casting avoids compiler
3376 w
= (uintptr_t) FRAME_X_WINDOW (f
);
3377 store_in_alist (alistptr
, Qwindow_id
,
3378 make_formatted_string (buf
, "%"pMu
, w
));
3379 #ifdef HAVE_X_WINDOWS
3380 #ifdef USE_X_TOOLKIT
3381 /* Tooltip frame may not have this widget. */
3382 if (FRAME_X_OUTPUT (f
)->widget
)
3384 w
= (uintptr_t) FRAME_OUTER_WINDOW (f
);
3385 store_in_alist (alistptr
, Qouter_window_id
,
3386 make_formatted_string (buf
, "%"pMu
, w
));
3388 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
3389 store_in_alist (alistptr
, Qvisibility
,
3390 (FRAME_VISIBLE_P (f
) ? Qt
3391 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
3392 store_in_alist (alistptr
, Qdisplay
,
3393 XCAR (FRAME_DISPLAY_INFO (f
)->name_list_element
));
3395 if (FRAME_X_OUTPUT (f
)->parent_desc
== FRAME_DISPLAY_INFO (f
)->root_window
)
3398 tem
= make_natnum ((uintptr_t) FRAME_X_OUTPUT (f
)->parent_desc
);
3399 store_in_alist (alistptr
, Qexplicit_name
, (f
->explicit_name
? Qt
: Qnil
));
3400 store_in_alist (alistptr
, Qparent_id
, tem
);
3401 store_in_alist (alistptr
, Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
));
3405 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3406 the previous value of that parameter, NEW_VALUE is the new value. */
3409 x_set_fullscreen (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3411 if (NILP (new_value
))
3412 f
->want_fullscreen
= FULLSCREEN_NONE
;
3413 else if (EQ (new_value
, Qfullboth
) || EQ (new_value
, Qfullscreen
))
3414 f
->want_fullscreen
= FULLSCREEN_BOTH
;
3415 else if (EQ (new_value
, Qfullwidth
))
3416 f
->want_fullscreen
= FULLSCREEN_WIDTH
;
3417 else if (EQ (new_value
, Qfullheight
))
3418 f
->want_fullscreen
= FULLSCREEN_HEIGHT
;
3419 else if (EQ (new_value
, Qmaximized
))
3420 f
->want_fullscreen
= FULLSCREEN_MAXIMIZED
;
3422 if (FRAME_TERMINAL (f
)->fullscreen_hook
!= NULL
)
3423 FRAME_TERMINAL (f
)->fullscreen_hook (f
);
3427 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3428 the previous value of that parameter, NEW_VALUE is the new value. */
3431 x_set_line_spacing (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3433 if (NILP (new_value
))
3434 f
->extra_line_spacing
= 0;
3435 else if (RANGED_INTEGERP (0, new_value
, INT_MAX
))
3436 f
->extra_line_spacing
= XFASTINT (new_value
);
3437 else if (FLOATP (new_value
))
3439 int new_spacing
= XFLOAT_DATA (new_value
) * FRAME_LINE_HEIGHT (f
) + 0.5;
3441 if (new_spacing
>= 0)
3442 f
->extra_line_spacing
= new_spacing
;
3444 signal_error ("Invalid line-spacing", new_value
);
3447 signal_error ("Invalid line-spacing", new_value
);
3448 if (FRAME_VISIBLE_P (f
))
3453 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3454 the previous value of that parameter, NEW_VALUE is the new value. */
3457 x_set_screen_gamma (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3459 Lisp_Object bgcolor
;
3461 if (NILP (new_value
))
3463 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
3464 /* The value 0.4545 is the normal viewing gamma. */
3465 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
3467 signal_error ("Invalid screen-gamma", new_value
);
3469 /* Apply the new gamma value to the frame background. */
3470 bgcolor
= Fassq (Qbackground_color
, f
->param_alist
);
3471 if (CONSP (bgcolor
) && (bgcolor
= XCDR (bgcolor
), STRINGP (bgcolor
)))
3473 Lisp_Object parm_index
= Fget (Qbackground_color
, Qx_frame_parameter
);
3474 if (NATNUMP (parm_index
)
3475 && XFASTINT (parm_index
) < ARRAYELTS (frame_parms
)
3476 && FRAME_RIF (f
)->frame_parm_handlers
[XFASTINT (parm_index
)])
3477 (*FRAME_RIF (f
)->frame_parm_handlers
[XFASTINT (parm_index
)])
3481 Fclear_face_cache (Qnil
);
3486 x_set_font (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3488 Lisp_Object font_object
;
3490 #ifdef HAVE_X_WINDOWS
3491 Lisp_Object font_param
= arg
;
3494 /* Set the frame parameter back to the old value because we may
3495 fail to use ARG as the new parameter value. */
3496 store_frame_param (f
, Qfont
, oldval
);
3498 /* ARG is a fontset name, a font name, a cons of fontset name and a
3499 font object, or a font object. In the last case, this function
3503 fontset
= fs_query_fontset (arg
, 0);
3506 font_object
= font_open_by_name (f
, arg
);
3507 if (NILP (font_object
))
3508 error ("Font `%s' is not defined", SSDATA (arg
));
3509 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3511 else if (fontset
> 0)
3513 font_object
= font_open_by_name (f
, fontset_ascii (fontset
));
3514 if (NILP (font_object
))
3515 error ("Font `%s' is not defined", SDATA (arg
));
3516 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3519 error ("The default fontset can't be used for a frame font");
3521 else if (CONSP (arg
) && STRINGP (XCAR (arg
)) && FONT_OBJECT_P (XCDR (arg
)))
3523 /* This is the case that the ASCII font of F's fontset XCAR
3524 (arg) is changed to the font XCDR (arg) by
3525 `set-fontset-font'. */
3526 fontset
= fs_query_fontset (XCAR (arg
), 0);
3528 error ("Unknown fontset: %s", SDATA (XCAR (arg
)));
3529 font_object
= XCDR (arg
);
3530 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3531 #ifdef HAVE_X_WINDOWS
3532 font_param
= Ffont_get (font_object
, QCname
);
3535 else if (FONT_OBJECT_P (arg
))
3538 #ifdef HAVE_X_WINDOWS
3539 font_param
= Ffont_get (font_object
, QCname
);
3541 /* This is to store the XLFD font name in the frame parameter for
3542 backward compatibility. We should store the font-object
3543 itself in the future. */
3544 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3545 fontset
= FRAME_FONTSET (f
);
3546 /* Check if we can use the current fontset. If not, set FONTSET
3547 to -1 to generate a new fontset from FONT-OBJECT. */
3550 Lisp_Object ascii_font
= fontset_ascii (fontset
);
3551 Lisp_Object spec
= font_spec_from_name (ascii_font
);
3554 signal_error ("Invalid font name", ascii_font
);
3556 if (! font_match_p (spec
, font_object
))
3561 signal_error ("Invalid font", arg
);
3563 if (! NILP (Fequal (font_object
, oldval
)))
3566 x_new_font (f
, font_object
, fontset
);
3567 store_frame_param (f
, Qfont
, arg
);
3568 #ifdef HAVE_X_WINDOWS
3569 store_frame_param (f
, Qfont_param
, font_param
);
3571 /* Recalculate toolbar height. */
3572 f
->n_tool_bar_rows
= 0;
3574 /* Ensure we redraw it. */
3575 clear_current_matrices (f
);
3577 /* Attempt to hunt down bug#16028. */
3578 SET_FRAME_GARBAGED (f
);
3580 recompute_basic_faces (f
);
3582 do_pending_window_change (0);
3584 /* We used to call face-set-after-frame-default here, but it leads to
3585 recursive calls (since that function can set the `default' face's
3586 font which in turns changes the frame's `font' parameter).
3587 Also I don't know what this call is meant to do, but it seems the
3588 wrong way to do it anyway (it does a lot more work than what seems
3589 reasonable in response to a change to `font'). */
3594 x_set_font_backend (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3596 if (! NILP (new_value
)
3597 && !CONSP (new_value
))
3601 CHECK_STRING (new_value
);
3602 p0
= p1
= SSDATA (new_value
);
3606 while (*p1
&& ! c_isspace (*p1
) && *p1
!= ',') p1
++;
3608 new_value
= Fcons (Fintern (make_string (p0
, p1
- p0
), Qnil
),
3614 while ((c
= *++p1
) && c_isspace (c
));
3618 new_value
= Fnreverse (new_value
);
3621 if (! NILP (old_value
) && ! NILP (Fequal (old_value
, new_value
)))
3625 free_all_realized_faces (Qnil
);
3627 new_value
= font_update_drivers (f
, NILP (new_value
) ? Qt
: new_value
);
3628 if (NILP (new_value
))
3630 if (NILP (old_value
))
3631 error ("No font backend available");
3632 font_update_drivers (f
, old_value
);
3633 error ("None of specified font backends are available");
3635 store_frame_param (f
, Qfont_backend
, new_value
);
3641 XSETFRAME (frame
, f
);
3642 x_set_font (f
, Fframe_parameter (frame
, Qfont
), Qnil
);
3643 ++face_change_count
;
3644 windows_or_buffers_changed
= 18;
3649 x_set_left_fringe (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3651 int unit
= FRAME_COLUMN_WIDTH (f
);
3652 int old_width
= FRAME_LEFT_FRINGE_WIDTH (f
);
3655 new_width
= (RANGED_INTEGERP (-INT_MAX
, new_value
, INT_MAX
)
3656 ? eabs (XINT (new_value
)) : 8);
3658 if (new_width
!= old_width
)
3660 FRAME_LEFT_FRINGE_WIDTH (f
) = new_width
;
3661 FRAME_FRINGE_COLS (f
) /* Round up. */
3662 = (new_width
+ FRAME_RIGHT_FRINGE_WIDTH (f
) + unit
- 1) / unit
;
3664 if (FRAME_X_WINDOW (f
) != 0)
3665 adjust_frame_size (f
, -1, -1, 3, 0, Qleft_fringe
);
3667 SET_FRAME_GARBAGED (f
);
3673 x_set_right_fringe (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3675 int unit
= FRAME_COLUMN_WIDTH (f
);
3676 int old_width
= FRAME_RIGHT_FRINGE_WIDTH (f
);
3679 new_width
= (RANGED_INTEGERP (-INT_MAX
, new_value
, INT_MAX
)
3680 ? eabs (XINT (new_value
)) : 8);
3682 if (new_width
!= old_width
)
3684 FRAME_RIGHT_FRINGE_WIDTH (f
) = new_width
;
3685 FRAME_FRINGE_COLS (f
) /* Round up. */
3686 = (new_width
+ FRAME_LEFT_FRINGE_WIDTH (f
) + unit
- 1) / unit
;
3688 if (FRAME_X_WINDOW (f
) != 0)
3689 adjust_frame_size (f
, -1, -1, 3, 0, Qright_fringe
);
3691 SET_FRAME_GARBAGED (f
);
3697 x_set_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3699 CHECK_TYPE_RANGED_INTEGER (int, arg
);
3701 if (XINT (arg
) == f
->border_width
)
3704 if (FRAME_X_WINDOW (f
) != 0)
3705 error ("Cannot change the border width of a frame");
3707 f
->border_width
= XINT (arg
);
3711 x_set_right_divider_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3713 int old
= FRAME_RIGHT_DIVIDER_WIDTH (f
);
3715 CHECK_TYPE_RANGED_INTEGER (int, arg
);
3716 FRAME_RIGHT_DIVIDER_WIDTH (f
) = XINT (arg
);
3717 if (FRAME_RIGHT_DIVIDER_WIDTH (f
) < 0)
3718 FRAME_RIGHT_DIVIDER_WIDTH (f
) = 0;
3719 if (FRAME_RIGHT_DIVIDER_WIDTH (f
) != old
)
3721 adjust_frame_size (f
, -1, -1, 4, 0, Qright_divider_width
);
3722 adjust_frame_glyphs (f
);
3723 SET_FRAME_GARBAGED (f
);
3729 x_set_bottom_divider_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3731 int old
= FRAME_BOTTOM_DIVIDER_WIDTH (f
);
3733 CHECK_TYPE_RANGED_INTEGER (int, arg
);
3734 FRAME_BOTTOM_DIVIDER_WIDTH (f
) = XINT (arg
);
3735 if (FRAME_BOTTOM_DIVIDER_WIDTH (f
) < 0)
3736 FRAME_BOTTOM_DIVIDER_WIDTH (f
) = 0;
3737 if (FRAME_BOTTOM_DIVIDER_WIDTH (f
) != old
)
3739 adjust_frame_size (f
, -1, -1, 4, 0, Qbottom_divider_width
);
3740 adjust_frame_glyphs (f
);
3741 SET_FRAME_GARBAGED (f
);
3746 x_set_visibility (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
3749 XSETFRAME (frame
, f
);
3752 Fmake_frame_invisible (frame
, Qt
);
3753 else if (EQ (value
, Qicon
))
3754 Ficonify_frame (frame
);
3756 Fmake_frame_visible (frame
);
3760 x_set_autoraise (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3762 f
->auto_raise
= !EQ (Qnil
, arg
);
3766 x_set_autolower (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3768 f
->auto_lower
= !EQ (Qnil
, arg
);
3772 x_set_unsplittable (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3774 f
->no_split
= !NILP (arg
);
3778 x_set_vertical_scroll_bars (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3780 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
3781 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
3782 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3783 || (!NILP (arg
) && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
3785 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
3787 ? vertical_scroll_bar_none
3789 ? vertical_scroll_bar_left
3791 ? vertical_scroll_bar_right
3792 : EQ (Qleft
, Vdefault_frame_scroll_bars
)
3793 ? vertical_scroll_bar_left
3794 : EQ (Qright
, Vdefault_frame_scroll_bars
)
3795 ? vertical_scroll_bar_right
3796 : vertical_scroll_bar_none
);
3798 /* We set this parameter before creating the X window for the
3799 frame, so we can get the geometry right from the start.
3800 However, if the window hasn't been created yet, we shouldn't
3801 call x_set_window_size. */
3802 if (FRAME_X_WINDOW (f
))
3803 adjust_frame_size (f
, -1, -1, 3, 0, Qvertical_scroll_bars
);
3805 SET_FRAME_GARBAGED (f
);
3810 x_set_horizontal_scroll_bars (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3812 #if USE_HORIZONTAL_SCROLL_BARS
3813 if ((NILP (arg
) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
))
3814 || (!NILP (arg
) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
)))
3816 f
->horizontal_scroll_bars
= NILP (arg
) ? false : true;
3818 /* We set this parameter before creating the X window for the
3819 frame, so we can get the geometry right from the start.
3820 However, if the window hasn't been created yet, we shouldn't
3821 call x_set_window_size. */
3822 if (FRAME_X_WINDOW (f
))
3823 adjust_frame_size (f
, -1, -1, 3, 0, Qhorizontal_scroll_bars
);
3825 SET_FRAME_GARBAGED (f
);
3831 x_set_scroll_bar_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3833 int unit
= FRAME_COLUMN_WIDTH (f
);
3837 x_set_scroll_bar_default_width (f
);
3839 if (FRAME_X_WINDOW (f
))
3840 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_width
);
3842 SET_FRAME_GARBAGED (f
);
3844 else if (RANGED_INTEGERP (1, arg
, INT_MAX
)
3845 && XFASTINT (arg
) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f
))
3847 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = XFASTINT (arg
);
3848 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + unit
- 1) / unit
;
3849 if (FRAME_X_WINDOW (f
))
3850 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_width
);
3852 SET_FRAME_GARBAGED (f
);
3855 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
3856 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
3860 x_set_scroll_bar_height (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3862 #if USE_HORIZONTAL_SCROLL_BARS
3863 int unit
= FRAME_LINE_HEIGHT (f
);
3867 x_set_scroll_bar_default_height (f
);
3869 if (FRAME_X_WINDOW (f
))
3870 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_height
);
3872 SET_FRAME_GARBAGED (f
);
3874 else if (RANGED_INTEGERP (1, arg
, INT_MAX
)
3875 && XFASTINT (arg
) != FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
))
3877 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = XFASTINT (arg
);
3878 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (XFASTINT (arg
) + unit
- 1) / unit
;
3879 if (FRAME_X_WINDOW (f
))
3880 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_height
);
3882 SET_FRAME_GARBAGED (f
);
3885 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.vpos
= 0;
3886 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.y
= 0;
3891 x_set_alpha (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3898 for (i
= 0; i
< 2; i
++)
3911 else if (FLOATP (item
))
3913 alpha
= XFLOAT_DATA (item
);
3914 if (! (0 <= alpha
&& alpha
<= 1.0))
3915 args_out_of_range (make_float (0.0), make_float (1.0));
3917 else if (INTEGERP (item
))
3919 EMACS_INT ialpha
= XINT (item
);
3920 if (! (0 <= ialpha
&& alpha
<= 100))
3921 args_out_of_range (make_number (0), make_number (100));
3922 alpha
= ialpha
/ 100.0;
3925 wrong_type_argument (Qnumberp
, item
);
3929 for (i
= 0; i
< 2; i
++)
3930 f
->alpha
[i
] = newval
[i
];
3932 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3934 x_set_frame_alpha (f
);
3943 /* Non-zero if mouse is grabbed on DPYINFO
3944 and we know the frame where it is. */
3946 bool x_mouse_grabbed (Display_Info
*dpyinfo
)
3948 return (dpyinfo
->grabbed
3949 && dpyinfo
->last_mouse_frame
3950 && FRAME_LIVE_P (dpyinfo
->last_mouse_frame
));
3953 /* Re-highlight something with mouse-face properties
3954 on DPYINFO using saved frame and mouse position. */
3957 x_redo_mouse_highlight (Display_Info
*dpyinfo
)
3959 if (dpyinfo
->last_mouse_motion_frame
3960 && FRAME_LIVE_P (dpyinfo
->last_mouse_motion_frame
))
3961 note_mouse_highlight (dpyinfo
->last_mouse_motion_frame
,
3962 dpyinfo
->last_mouse_motion_x
,
3963 dpyinfo
->last_mouse_motion_y
);
3966 #endif /* HAVE_NS */
3968 /* Subroutines of creating an X frame. */
3970 /* Make sure that Vx_resource_name is set to a reasonable value.
3971 Fix it up, or set it to `emacs' if it is too hopeless. */
3974 validate_x_resource_name (void)
3977 /* Number of valid characters in the resource name. */
3978 ptrdiff_t good_count
= 0;
3979 /* Number of invalid characters in the resource name. */
3980 ptrdiff_t bad_count
= 0;
3984 if (!STRINGP (Vx_resource_class
))
3985 Vx_resource_class
= build_string (EMACS_CLASS
);
3987 if (STRINGP (Vx_resource_name
))
3989 unsigned char *p
= SDATA (Vx_resource_name
);
3991 len
= SBYTES (Vx_resource_name
);
3993 /* Only letters, digits, - and _ are valid in resource names.
3994 Count the valid characters and count the invalid ones. */
3995 for (i
= 0; i
< len
; i
++)
3998 if (! ((c
>= 'a' && c
<= 'z')
3999 || (c
>= 'A' && c
<= 'Z')
4000 || (c
>= '0' && c
<= '9')
4001 || c
== '-' || c
== '_'))
4008 /* Not a string => completely invalid. */
4009 bad_count
= 5, good_count
= 0;
4011 /* If name is valid already, return. */
4015 /* If name is entirely invalid, or nearly so, or is so implausibly
4016 large that alloca might not work, use `emacs'. */
4017 if (good_count
< 2 || MAX_ALLOCA
- sizeof ".customization" < len
)
4019 Vx_resource_name
= build_string ("emacs");
4023 /* Name is partly valid. Copy it and replace the invalid characters
4024 with underscores. */
4026 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
4028 for (i
= 0; i
< len
; i
++)
4030 int c
= SREF (new, i
);
4031 if (! ((c
>= 'a' && c
<= 'z')
4032 || (c
>= 'A' && c
<= 'Z')
4033 || (c
>= '0' && c
<= '9')
4034 || c
== '-' || c
== '_'))
4039 /* Get specified attribute from resource database RDB.
4040 See Fx_get_resource below for other parameters. */
4043 xrdb_get_resource (XrmDatabase rdb
, Lisp_Object attribute
, Lisp_Object
class, Lisp_Object component
, Lisp_Object subclass
)
4045 CHECK_STRING (attribute
);
4046 CHECK_STRING (class);
4048 if (!NILP (component
))
4049 CHECK_STRING (component
);
4050 if (!NILP (subclass
))
4051 CHECK_STRING (subclass
);
4052 if (NILP (component
) != NILP (subclass
))
4053 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
4055 validate_x_resource_name ();
4057 /* Allocate space for the components, the dots which separate them,
4058 and the final '\0'. Make them big enough for the worst case. */
4059 ptrdiff_t name_keysize
= (SBYTES (Vx_resource_name
)
4060 + (STRINGP (component
)
4061 ? SBYTES (component
) : 0)
4062 + SBYTES (attribute
)
4065 ptrdiff_t class_keysize
= (SBYTES (Vx_resource_class
)
4067 + (STRINGP (subclass
)
4068 ? SBYTES (subclass
) : 0)
4071 char *name_key
= SAFE_ALLOCA (name_keysize
+ class_keysize
);
4072 char *class_key
= name_key
+ name_keysize
;
4074 /* Start with emacs.FRAMENAME for the name (the specific one)
4075 and with `Emacs' for the class key (the general one). */
4076 lispstpcpy (name_key
, Vx_resource_name
);
4077 lispstpcpy (class_key
, Vx_resource_class
);
4079 strcat (class_key
, ".");
4080 strcat (class_key
, SSDATA (class));
4082 if (!NILP (component
))
4084 strcat (class_key
, ".");
4085 strcat (class_key
, SSDATA (subclass
));
4087 strcat (name_key
, ".");
4088 strcat (name_key
, SSDATA (component
));
4091 strcat (name_key
, ".");
4092 strcat (name_key
, SSDATA (attribute
));
4094 char *value
= x_get_string_resource (rdb
, name_key
, class_key
);
4097 if (value
&& *value
)
4098 return build_string (value
);
4104 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
4105 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
4106 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
4107 class, where INSTANCE is the name under which Emacs was invoked, or
4108 the name specified by the `-name' or `-rn' command-line arguments.
4110 The optional arguments COMPONENT and SUBCLASS add to the key and the
4111 class, respectively. You must specify both of them or neither.
4112 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
4113 and the class is `Emacs.CLASS.SUBCLASS'. */)
4114 (Lisp_Object attribute
, Lisp_Object
class, Lisp_Object component
,
4115 Lisp_Object subclass
)
4117 check_window_system (NULL
);
4119 return xrdb_get_resource (check_x_display_info (Qnil
)->xrdb
,
4120 attribute
, class, component
, subclass
);
4123 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
4126 display_x_get_resource (Display_Info
*dpyinfo
, Lisp_Object attribute
,
4127 Lisp_Object
class, Lisp_Object component
,
4128 Lisp_Object subclass
)
4130 return xrdb_get_resource (dpyinfo
->xrdb
,
4131 attribute
, class, component
, subclass
);
4134 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
4135 /* Used when C code wants a resource value. */
4136 /* Called from oldXMenu/Create.c. */
4138 x_get_resource_string (const char *attribute
, const char *class)
4141 struct frame
*sf
= SELECTED_FRAME ();
4142 ptrdiff_t invocation_namelen
= SBYTES (Vinvocation_name
);
4145 /* Allocate space for the components, the dots which separate them,
4146 and the final '\0'. */
4147 ptrdiff_t name_keysize
= invocation_namelen
+ strlen (attribute
) + 2;
4148 ptrdiff_t class_keysize
= sizeof (EMACS_CLASS
) - 1 + strlen (class) + 2;
4149 char *name_key
= SAFE_ALLOCA (name_keysize
+ class_keysize
);
4150 char *class_key
= name_key
+ name_keysize
;
4152 esprintf (name_key
, "%s.%s", SSDATA (Vinvocation_name
), attribute
);
4153 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
4155 result
= x_get_string_resource (FRAME_DISPLAY_INFO (sf
)->xrdb
,
4156 name_key
, class_key
);
4162 /* Return the value of parameter PARAM.
4164 First search ALIST, then Vdefault_frame_alist, then the X defaults
4165 database, using ATTRIBUTE as the attribute name and CLASS as its class.
4167 Convert the resource to the type specified by desired_type.
4169 If no default is specified, return Qunbound. If you call
4170 x_get_arg, make sure you deal with Qunbound in a reasonable way,
4171 and don't let it get stored in any Lisp-visible variables! */
4174 x_get_arg (Display_Info
*dpyinfo
, Lisp_Object alist
, Lisp_Object param
,
4175 const char *attribute
, const char *class, enum resource_types type
)
4179 tem
= Fassq (param
, alist
);
4183 /* If we find this parm in ALIST, clear it out
4184 so that it won't be "left over" at the end. */
4186 XSETCAR (tem
, Qnil
);
4187 /* In case the parameter appears more than once in the alist,
4189 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
4190 if (CONSP (XCAR (tail
))
4191 && EQ (XCAR (XCAR (tail
)), param
))
4192 XSETCAR (XCAR (tail
), Qnil
);
4195 tem
= Fassq (param
, Vdefault_frame_alist
);
4197 /* If it wasn't specified in ALIST or the Lisp-level defaults,
4198 look in the X resources. */
4201 if (attribute
&& dpyinfo
)
4203 AUTO_STRING (at
, attribute
);
4204 AUTO_STRING (cl
, class);
4205 tem
= display_x_get_resource (dpyinfo
, at
, cl
, Qnil
, Qnil
);
4212 case RES_TYPE_NUMBER
:
4213 return make_number (atoi (SSDATA (tem
)));
4215 case RES_TYPE_BOOLEAN_NUMBER
:
4216 if (!strcmp (SSDATA (tem
), "on")
4217 || !strcmp (SSDATA (tem
), "true"))
4218 return make_number (1);
4219 return make_number (atoi (SSDATA (tem
)));
4222 case RES_TYPE_FLOAT
:
4223 return make_float (atof (SSDATA (tem
)));
4225 case RES_TYPE_BOOLEAN
:
4226 tem
= Fdowncase (tem
);
4227 if (!strcmp (SSDATA (tem
), "on")
4229 || !strcmp (SSDATA (tem
), "yes")
4231 || !strcmp (SSDATA (tem
), "true"))
4236 case RES_TYPE_STRING
:
4239 case RES_TYPE_SYMBOL
:
4240 /* As a special case, we map the values `true' and `on'
4241 to Qt, and `false' and `off' to Qnil. */
4244 lower
= Fdowncase (tem
);
4245 if (!strcmp (SSDATA (lower
), "on")
4247 || !strcmp (SSDATA (lower
), "yes")
4249 || !strcmp (SSDATA (lower
), "true"))
4251 else if (!strcmp (SSDATA (lower
), "off")
4253 || !strcmp (SSDATA (lower
), "no")
4255 || !strcmp (SSDATA (lower
), "false"))
4258 return Fintern (tem
, Qnil
);
4272 x_frame_get_arg (struct frame
*f
, Lisp_Object alist
, Lisp_Object param
,
4273 const char *attribute
, const char *class,
4274 enum resource_types type
)
4276 return x_get_arg (FRAME_DISPLAY_INFO (f
),
4277 alist
, param
, attribute
, class, type
);
4280 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
4283 x_frame_get_and_record_arg (struct frame
*f
, Lisp_Object alist
,
4285 const char *attribute
, const char *class,
4286 enum resource_types type
)
4290 value
= x_get_arg (FRAME_DISPLAY_INFO (f
), alist
, param
,
4291 attribute
, class, type
);
4292 if (! NILP (value
) && ! EQ (value
, Qunbound
))
4293 store_frame_param (f
, param
, value
);
4299 /* Record in frame F the specified or default value according to ALIST
4300 of the parameter named PROP (a Lisp symbol).
4301 If no value is specified for PROP, look for an X default for XPROP
4302 on the frame named NAME.
4303 If that is not found either, use the value DEFLT. */
4306 x_default_parameter (struct frame
*f
, Lisp_Object alist
, Lisp_Object prop
,
4307 Lisp_Object deflt
, const char *xprop
, const char *xclass
,
4308 enum resource_types type
)
4312 tem
= x_frame_get_arg (f
, alist
, prop
, xprop
, xclass
, type
);
4313 if (EQ (tem
, Qunbound
))
4315 AUTO_FRAME_ARG (arg
, prop
, tem
);
4316 x_set_frame_parameters (f
, arg
);
4321 #if !defined (HAVE_X_WINDOWS) && defined (NoValue)
4324 * XParseGeometry parses strings of the form
4325 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
4326 * width, height, xoffset, and yoffset are unsigned integers.
4327 * Example: "=80x24+300-49"
4328 * The equal sign is optional.
4329 * It returns a bitmask that indicates which of the four values
4330 * were actually found in the string. For each value found,
4331 * the corresponding argument is updated; for each value
4332 * not found, the corresponding argument is left unchanged.
4336 XParseGeometry (char *string
,
4338 unsigned int *width
, unsigned int *height
)
4342 unsigned long tempWidth
, tempHeight
;
4343 long int tempX
, tempY
;
4344 char *nextCharacter
;
4346 if (string
== NULL
|| *string
== '\0')
4349 string
++; /* ignore possible '=' at beg of geometry spec */
4352 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
4354 tempWidth
= strtoul (strind
, &nextCharacter
, 10);
4355 if (strind
== nextCharacter
)
4357 strind
= nextCharacter
;
4361 if (*strind
== 'x' || *strind
== 'X')
4364 tempHeight
= strtoul (strind
, &nextCharacter
, 10);
4365 if (strind
== nextCharacter
)
4367 strind
= nextCharacter
;
4368 mask
|= HeightValue
;
4371 if (*strind
== '+' || *strind
== '-')
4375 tempX
= strtol (strind
, &nextCharacter
, 10);
4376 if (strind
== nextCharacter
)
4378 strind
= nextCharacter
;
4380 if (*strind
== '+' || *strind
== '-')
4384 tempY
= strtol (strind
, &nextCharacter
, 10);
4385 if (strind
== nextCharacter
)
4387 strind
= nextCharacter
;
4392 /* If strind isn't at the end of the string then it's an invalid
4393 geometry specification. */
4395 if (*strind
!= '\0')
4399 *x
= clip_to_bounds (INT_MIN
, tempX
, INT_MAX
);
4401 *y
= clip_to_bounds (INT_MIN
, tempY
, INT_MAX
);
4402 if (mask
& WidthValue
)
4403 *width
= min (tempWidth
, UINT_MAX
);
4404 if (mask
& HeightValue
)
4405 *height
= min (tempHeight
, UINT_MAX
);
4409 #endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
4412 /* NS used to define x-parse-geometry in ns-win.el, but that confused
4413 make-docfile: the documentation string in ns-win.el was used for
4414 x-parse-geometry even in non-NS builds.
4416 With two definitions of x-parse-geometry in this file, various
4417 things still get confused (eg M-x apropos documentation), so that
4418 it is best if the two definitions just share the same doc-string.
4420 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
4421 doc
: /* Parse a display geometry string STRING.
4422 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4423 The properties returned may include `top', `left', `height', and `width'.
4424 For X, the value of `left' or `top' may be an integer,
4425 or a list (+ N) meaning N pixels relative to top/left corner,
4426 or a list (- N) meaning -N pixels relative to bottom/right corner.
4427 On Nextstep, this just calls `ns-parse-geometry'. */)
4428 (Lisp_Object string
)
4431 unsigned int width
, height
;
4434 CHECK_STRING (string
);
4437 if (strchr (SSDATA (string
), ' ') != NULL
)
4438 return call1 (Qns_parse_geometry
, string
);
4440 geometry
= XParseGeometry (SSDATA (string
),
4441 &x
, &y
, &width
, &height
);
4443 if (geometry
& XValue
)
4445 Lisp_Object element
;
4447 if (x
>= 0 && (geometry
& XNegative
))
4448 element
= list3 (Qleft
, Qminus
, make_number (-x
));
4449 else if (x
< 0 && ! (geometry
& XNegative
))
4450 element
= list3 (Qleft
, Qplus
, make_number (x
));
4452 element
= Fcons (Qleft
, make_number (x
));
4453 result
= Fcons (element
, result
);
4456 if (geometry
& YValue
)
4458 Lisp_Object element
;
4460 if (y
>= 0 && (geometry
& YNegative
))
4461 element
= list3 (Qtop
, Qminus
, make_number (-y
));
4462 else if (y
< 0 && ! (geometry
& YNegative
))
4463 element
= list3 (Qtop
, Qplus
, make_number (y
));
4465 element
= Fcons (Qtop
, make_number (y
));
4466 result
= Fcons (element
, result
);
4469 if (geometry
& WidthValue
)
4470 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
4471 if (geometry
& HeightValue
)
4472 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
4478 /* Calculate the desired size and position of frame F.
4479 Return the flags saying which aspects were specified.
4481 Also set the win_gravity and size_hint_flags of F.
4483 Adjust height for toolbar if TOOLBAR_P is 1.
4485 This function does not make the coordinates positive. */
4487 #define DEFAULT_ROWS 35
4488 #define DEFAULT_COLS 80
4491 x_figure_window_size (struct frame
*f
, Lisp_Object parms
, bool toolbar_p
)
4493 Lisp_Object height
, width
, user_size
, top
, left
, user_position
;
4494 long window_prompting
= 0;
4495 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
4497 /* Default values if we fall through.
4498 Actually, if that happens we should get
4499 window manager prompting. */
4500 SET_FRAME_WIDTH (f
, DEFAULT_COLS
* FRAME_COLUMN_WIDTH (f
));
4501 SET_FRAME_COLS (f
, DEFAULT_COLS
);
4502 SET_FRAME_HEIGHT (f
, DEFAULT_ROWS
* FRAME_LINE_HEIGHT (f
));
4503 SET_FRAME_LINES (f
, DEFAULT_ROWS
);
4505 /* Window managers expect that if program-specified
4506 positions are not (0,0), they're intentional, not defaults. */
4510 /* Ensure that earlier new_width and new_height settings won't
4511 override what we specify below. */
4512 f
->new_width
= f
->new_height
= 0;
4514 height
= x_get_arg (dpyinfo
, parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
4515 width
= x_get_arg (dpyinfo
, parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
4516 if (!EQ (width
, Qunbound
) || !EQ (height
, Qunbound
))
4518 if (!EQ (width
, Qunbound
))
4520 CHECK_NUMBER (width
);
4521 if (! (0 <= XINT (width
) && XINT (width
) <= INT_MAX
))
4522 xsignal1 (Qargs_out_of_range
, width
);
4524 SET_FRAME_WIDTH (f
, XINT (width
) * FRAME_COLUMN_WIDTH (f
));
4527 if (!EQ (height
, Qunbound
))
4529 CHECK_NUMBER (height
);
4530 if (! (0 <= XINT (height
) && XINT (height
) <= INT_MAX
))
4531 xsignal1 (Qargs_out_of_range
, height
);
4533 SET_FRAME_HEIGHT (f
, XINT (height
) * FRAME_LINE_HEIGHT (f
));
4536 user_size
= x_get_arg (dpyinfo
, parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
4537 if (!NILP (user_size
) && !EQ (user_size
, Qunbound
))
4538 window_prompting
|= USSize
;
4540 window_prompting
|= PSize
;
4543 /* Add a tool bar height to the initial frame height so that the user
4544 gets a text display area of the size he specified with -g or via
4545 .Xdefaults. Later changes of the tool bar height don't change the
4546 frame size. This is done so that users can create tall Emacs
4547 frames without having to guess how tall the tool bar will get. */
4548 if (toolbar_p
&& FRAME_TOOL_BAR_LINES (f
))
4552 relief
= (tool_bar_button_relief
>= 0
4553 ? tool_bar_button_relief
4554 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
4556 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
, INT_MAX
))
4557 margin
= XFASTINT (Vtool_bar_button_margin
);
4558 else if (CONSP (Vtool_bar_button_margin
)
4559 && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
), INT_MAX
))
4560 margin
= XFASTINT (XCDR (Vtool_bar_button_margin
));
4564 FRAME_TOOL_BAR_HEIGHT (f
)
4565 = DEFAULT_TOOL_BAR_IMAGE_HEIGHT
+ 2 * margin
+ 2 * relief
;
4566 Vframe_initial_frame_tool_bar_height
= make_number (FRAME_TOOL_BAR_HEIGHT (f
));
4569 top
= x_get_arg (dpyinfo
, parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
4570 left
= x_get_arg (dpyinfo
, parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
4571 user_position
= x_get_arg (dpyinfo
, parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
4572 if (! EQ (top
, Qunbound
) || ! EQ (left
, Qunbound
))
4574 if (EQ (top
, Qminus
))
4577 window_prompting
|= YNegative
;
4579 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
4580 && CONSP (XCDR (top
))
4581 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (top
)), INT_MAX
))
4583 f
->top_pos
= - XINT (XCAR (XCDR (top
)));
4584 window_prompting
|= YNegative
;
4586 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
4587 && CONSP (XCDR (top
))
4588 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top
))))
4590 f
->top_pos
= XINT (XCAR (XCDR (top
)));
4592 else if (EQ (top
, Qunbound
))
4596 CHECK_TYPE_RANGED_INTEGER (int, top
);
4597 f
->top_pos
= XINT (top
);
4599 window_prompting
|= YNegative
;
4602 if (EQ (left
, Qminus
))
4605 window_prompting
|= XNegative
;
4607 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
4608 && CONSP (XCDR (left
))
4609 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (left
)), INT_MAX
))
4611 f
->left_pos
= - XINT (XCAR (XCDR (left
)));
4612 window_prompting
|= XNegative
;
4614 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
4615 && CONSP (XCDR (left
))
4616 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left
))))
4618 f
->left_pos
= XINT (XCAR (XCDR (left
)));
4620 else if (EQ (left
, Qunbound
))
4624 CHECK_TYPE_RANGED_INTEGER (int, left
);
4625 f
->left_pos
= XINT (left
);
4626 if (f
->left_pos
< 0)
4627 window_prompting
|= XNegative
;
4630 if (!NILP (user_position
) && ! EQ (user_position
, Qunbound
))
4631 window_prompting
|= USPosition
;
4633 window_prompting
|= PPosition
;
4636 if (window_prompting
& XNegative
)
4638 if (window_prompting
& YNegative
)
4639 f
->win_gravity
= SouthEastGravity
;
4641 f
->win_gravity
= NorthEastGravity
;
4645 if (window_prompting
& YNegative
)
4646 f
->win_gravity
= SouthWestGravity
;
4648 f
->win_gravity
= NorthWestGravity
;
4651 f
->size_hint_flags
= window_prompting
;
4653 return window_prompting
;
4658 #endif /* HAVE_WINDOW_SYSTEM */
4661 frame_make_pointer_invisible (struct frame
*f
)
4663 if (! NILP (Vmake_pointer_invisible
))
4665 if (f
&& FRAME_LIVE_P (f
) && !f
->pointer_invisible
4666 && FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook
)
4669 FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook (f
, 1);
4670 f
->pointer_invisible
= 1;
4676 frame_make_pointer_visible (struct frame
*f
)
4678 /* We don't check Vmake_pointer_invisible here in case the
4679 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4680 if (f
&& FRAME_LIVE_P (f
) && f
->pointer_invisible
&& f
->mouse_moved
4681 && FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook
)
4683 FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook (f
, 0);
4684 f
->pointer_invisible
= 0;
4688 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p
,
4689 Sframe_pointer_visible_p
, 0, 1, 0,
4690 doc
: /* Return t if the mouse pointer displayed on FRAME is visible.
4691 Otherwise it returns nil. FRAME omitted or nil means the
4692 selected frame. This is useful when `make-pointer-invisible' is set. */)
4695 return decode_any_frame (frame
)->pointer_invisible
? Qnil
: Qt
;
4700 /***********************************************************************
4702 ***********************************************************************/
4704 #ifdef HAVE_WINDOW_SYSTEM
4706 # if (defined HAVE_NS \
4707 || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR)))
4709 free_monitors (struct MonitorInfo
*monitors
, int n_monitors
)
4712 for (i
= 0; i
< n_monitors
; ++i
)
4713 xfree (monitors
[i
].name
);
4719 make_monitor_attribute_list (struct MonitorInfo
*monitors
,
4721 int primary_monitor
,
4722 Lisp_Object monitor_frames
,
4725 Lisp_Object attributes_list
= Qnil
;
4726 Lisp_Object primary_monitor_attributes
= Qnil
;
4729 for (i
= 0; i
< n_monitors
; ++i
)
4731 Lisp_Object geometry
, workarea
, attributes
= Qnil
;
4732 struct MonitorInfo
*mi
= &monitors
[i
];
4734 if (mi
->geom
.width
== 0) continue;
4736 workarea
= list4i (mi
->work
.x
, mi
->work
.y
,
4737 mi
->work
.width
, mi
->work
.height
);
4738 geometry
= list4i (mi
->geom
.x
, mi
->geom
.y
,
4739 mi
->geom
.width
, mi
->geom
.height
);
4740 attributes
= Fcons (Fcons (Qsource
, build_string (source
)),
4742 attributes
= Fcons (Fcons (Qframes
, AREF (monitor_frames
, i
)),
4744 attributes
= Fcons (Fcons (Qmm_size
,
4745 list2i (mi
->mm_width
, mi
->mm_height
)),
4747 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
4748 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
4750 attributes
= Fcons (Fcons (Qname
, make_string (mi
->name
,
4751 strlen (mi
->name
))),
4754 if (i
== primary_monitor
)
4755 primary_monitor_attributes
= attributes
;
4757 attributes_list
= Fcons (attributes
, attributes_list
);
4760 if (!NILP (primary_monitor_attributes
))
4761 attributes_list
= Fcons (primary_monitor_attributes
, attributes_list
);
4762 return attributes_list
;
4765 #endif /* HAVE_WINDOW_SYSTEM */
4768 /***********************************************************************
4770 ***********************************************************************/
4773 syms_of_frame (void)
4775 DEFSYM (Qframep
, "framep");
4776 DEFSYM (Qframe_live_p
, "frame-live-p");
4777 DEFSYM (Qframe_windows_min_size
, "frame-windows-min-size");
4778 DEFSYM (Qexplicit_name
, "explicit-name");
4779 DEFSYM (Qheight
, "height");
4780 DEFSYM (Qicon
, "icon");
4781 DEFSYM (Qminibuffer
, "minibuffer");
4782 DEFSYM (Qmodeline
, "modeline");
4783 DEFSYM (Qonly
, "only");
4784 DEFSYM (Qnone
, "none");
4785 DEFSYM (Qwidth
, "width");
4786 DEFSYM (Qgeometry
, "geometry");
4787 DEFSYM (Qicon_left
, "icon-left");
4788 DEFSYM (Qicon_top
, "icon-top");
4789 DEFSYM (Qtooltip
, "tooltip");
4790 DEFSYM (Quser_position
, "user-position");
4791 DEFSYM (Quser_size
, "user-size");
4792 DEFSYM (Qwindow_id
, "window-id");
4793 #ifdef HAVE_X_WINDOWS
4794 DEFSYM (Qouter_window_id
, "outer-window-id");
4796 DEFSYM (Qparent_id
, "parent-id");
4798 DEFSYM (Qw32
, "w32");
4801 DEFSYM (Qvisible
, "visible");
4802 DEFSYM (Qbuffer_predicate
, "buffer-predicate");
4803 DEFSYM (Qbuffer_list
, "buffer-list");
4804 DEFSYM (Qburied_buffer_list
, "buried-buffer-list");
4805 DEFSYM (Qdisplay_type
, "display-type");
4806 DEFSYM (Qbackground_mode
, "background-mode");
4807 DEFSYM (Qnoelisp
, "noelisp");
4808 DEFSYM (Qtty_color_mode
, "tty-color-mode");
4809 DEFSYM (Qtty
, "tty");
4810 DEFSYM (Qtty_type
, "tty-type");
4812 DEFSYM (Qface_set_after_frame_default
, "face-set-after-frame-default");
4814 DEFSYM (Qfullwidth
, "fullwidth");
4815 DEFSYM (Qfullheight
, "fullheight");
4816 DEFSYM (Qfullboth
, "fullboth");
4817 DEFSYM (Qmaximized
, "maximized");
4818 DEFSYM (Qx_resource_name
, "x-resource-name");
4819 DEFSYM (Qx_frame_parameter
, "x-frame-parameter");
4821 DEFSYM (Qterminal
, "terminal");
4823 DEFSYM (Qworkarea
, "workarea");
4824 DEFSYM (Qmm_size
, "mm-size");
4825 DEFSYM (Qframes
, "frames");
4826 DEFSYM (Qsource
, "source");
4828 DEFSYM (Qframe_position
, "frame-position");
4829 DEFSYM (Qframe_outer_size
, "frame-outer-size");
4830 DEFSYM (Qexternal_border_size
, "external-border-size");
4831 DEFSYM (Qtitle_height
, "title-height");
4832 DEFSYM (Qmenu_bar_external
, "menu-bar-external");
4833 DEFSYM (Qmenu_bar_size
, "menu-bar-size");
4834 DEFSYM (Qtool_bar_external
, "tool-bar-external");
4835 DEFSYM (Qtool_bar_size
, "tool-bar-size");
4836 DEFSYM (Qframe_inner_size
, "frame-inner-size");
4839 DEFSYM (Qns_parse_geometry
, "ns-parse-geometry");
4845 for (i
= 0; i
< ARRAYELTS (frame_parms
); i
++)
4847 Lisp_Object v
= intern_c_string (frame_parms
[i
].name
);
4848 if (frame_parms
[i
].variable
)
4850 *frame_parms
[i
].variable
= v
;
4851 staticpro (frame_parms
[i
].variable
);
4853 Fput (v
, Qx_frame_parameter
, make_number (i
));
4857 #ifdef HAVE_WINDOW_SYSTEM
4858 DEFVAR_LISP ("x-resource-name", Vx_resource_name
,
4859 doc
: /* The name Emacs uses to look up X resources.
4860 `x-get-resource' uses this as the first component of the instance name
4861 when requesting resource values.
4862 Emacs initially sets `x-resource-name' to the name under which Emacs
4863 was invoked, or to the value specified with the `-name' or `-rn'
4864 switches, if present.
4866 It may be useful to bind this variable locally around a call
4867 to `x-get-resource'. See also the variable `x-resource-class'. */);
4868 Vx_resource_name
= Qnil
;
4870 DEFVAR_LISP ("x-resource-class", Vx_resource_class
,
4871 doc
: /* The class Emacs uses to look up X resources.
4872 `x-get-resource' uses this as the first component of the instance class
4873 when requesting resource values.
4875 Emacs initially sets `x-resource-class' to "Emacs".
4877 Setting this variable permanently is not a reasonable thing to do,
4878 but binding this variable locally around a call to `x-get-resource'
4879 is a reasonable practice. See also the variable `x-resource-name'. */);
4880 Vx_resource_class
= build_string (EMACS_CLASS
);
4882 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit
,
4883 doc
: /* The lower limit of the frame opacity (alpha transparency).
4884 The value should range from 0 (invisible) to 100 (completely opaque).
4885 You can also use a floating number between 0.0 and 1.0. */);
4886 Vframe_alpha_lower_limit
= make_number (20);
4889 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist
,
4890 doc
: /* Alist of default values for frame creation.
4891 These may be set in your init file, like this:
4892 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4893 These override values given in window system configuration data,
4894 including X Windows' defaults database.
4895 For values specific to the first Emacs frame, see `initial-frame-alist'.
4896 For window-system specific values, see `window-system-default-frame-alist'.
4897 For values specific to the separate minibuffer frame, see
4898 `minibuffer-frame-alist'.
4899 The `menu-bar-lines' element of the list controls whether new frames
4900 have menu bars; `menu-bar-mode' works by altering this element.
4901 Setting this variable does not affect existing frames, only new ones. */);
4902 Vdefault_frame_alist
= Qnil
;
4904 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars
,
4905 doc
: /* Default position of vertical scroll bars on this window-system. */);
4906 #ifdef HAVE_WINDOW_SYSTEM
4907 #if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
4908 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
4910 Vdefault_frame_scroll_bars
= Qright
;
4912 Vdefault_frame_scroll_bars
= Qleft
;
4915 Vdefault_frame_scroll_bars
= Qnil
;
4918 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
4919 scroll_bar_adjust_thumb_portion_p
,
4920 doc
: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
4921 Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards
4922 even if the end of the buffer is shown (i.e. overscrolling).
4923 Set to nil if you want the thumb to be at the bottom when the end of the buffer
4924 is shown. Also, the thumb fills the whole scroll bar when the entire buffer
4925 is visible. In this case you can not overscroll. */);
4926 scroll_bar_adjust_thumb_portion_p
= 1;
4928 DEFVAR_LISP ("terminal-frame", Vterminal_frame
,
4929 doc
: /* The initial frame-object, which represents Emacs's stdout. */);
4931 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function
,
4932 doc
: /* If non-nil, function to transform normal value of `mouse-position'.
4933 `mouse-position' and `mouse-pixel-position' call this function, passing their
4934 usual return value as argument, and return whatever this function returns.
4935 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4936 which need to do mouse handling at the Lisp level. */);
4937 Vmouse_position_function
= Qnil
;
4939 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight
,
4940 doc
: /* If non-nil, clickable text is highlighted when mouse is over it.
4941 If the value is an integer, highlighting is only shown after moving the
4942 mouse, while keyboard input turns off the highlight even when the mouse
4943 is over the clickable text. However, the mouse shape still indicates
4944 when the mouse is over clickable text. */);
4945 Vmouse_highlight
= Qt
;
4947 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible
,
4948 doc
: /* If non-nil, make pointer invisible while typing.
4949 The pointer becomes visible again when the mouse is moved. */);
4950 Vmake_pointer_invisible
= Qt
;
4952 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook
,
4953 doc
: /* Normal hook run when a frame gains input focus. */);
4954 Vfocus_in_hook
= Qnil
;
4955 DEFSYM (Qfocus_in_hook
, "focus-in-hook");
4957 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook
,
4958 doc
: /* Normal hook run when a frame loses input focus. */);
4959 Vfocus_out_hook
= Qnil
;
4960 DEFSYM (Qfocus_out_hook
, "focus-out-hook");
4962 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions
,
4963 doc
: /* Functions run before deleting a frame.
4964 The functions are run with one arg, the frame to be deleted.
4967 Note that functions in this list may be called just before the frame is
4968 actually deleted, or some time later (or even both when an earlier function
4969 in `delete-frame-functions' (indirectly) calls `delete-frame'
4971 Vdelete_frame_functions
= Qnil
;
4972 DEFSYM (Qdelete_frame_functions
, "delete-frame-functions");
4974 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode
,
4975 doc
: /* Non-nil if Menu-Bar mode is enabled.
4976 See the command `menu-bar-mode' for a description of this minor mode.
4977 Setting this variable directly does not take effect;
4978 either customize it (see the info node `Easy Customization')
4979 or call the function `menu-bar-mode'. */);
4980 Vmenu_bar_mode
= Qt
;
4982 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode
,
4983 doc
: /* Non-nil if Tool-Bar mode is enabled.
4984 See the command `tool-bar-mode' for a description of this minor mode.
4985 Setting this variable directly does not take effect;
4986 either customize it (see the info node `Easy Customization')
4987 or call the function `tool-bar-mode'. */);
4988 #ifdef HAVE_WINDOW_SYSTEM
4989 Vtool_bar_mode
= Qt
;
4991 Vtool_bar_mode
= Qnil
;
4994 DEFVAR_LISP ("frame-initial-frame-tool-bar-height", Vframe_initial_frame_tool_bar_height
,
4995 doc
: /* Height of tool bar of initial frame. */);
4996 Vframe_initial_frame_tool_bar_height
= make_number (0);
4998 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame
,
4999 doc
: /* Minibufferless frames use this frame's minibuffer.
5000 Emacs cannot create minibufferless frames unless this is set to an
5001 appropriate surrogate.
5003 Emacs consults this variable only when creating minibufferless
5004 frames; once the frame is created, it sticks with its assigned
5005 minibuffer, no matter what this variable is set to. This means that
5006 this variable doesn't necessarily say anything meaningful about the
5007 current set of frames, or where the minibuffer is currently being
5010 This variable is local to the current terminal and cannot be buffer-local. */);
5012 DEFVAR_BOOL ("focus-follows-mouse", focus_follows_mouse
,
5013 doc
: /* Non-nil if window system changes focus when you move the mouse.
5014 You should set this variable to tell Emacs how your window manager
5015 handles focus, since there is no way in general for Emacs to find out
5016 automatically. See also `mouse-autoselect-window'. */);
5017 focus_follows_mouse
= 0;
5019 DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise
,
5020 doc
: /* Non-nil means resize frames pixelwise.
5021 If this option is nil, resizing a frame rounds its sizes to the frame's
5022 current values of `frame-char-height' and `frame-char-width'. If this
5023 is non-nil, no rounding occurs, hence frame sizes can increase/decrease
5026 With some window managers you may have to set this to non-nil in order
5027 to set the size of a frame in pixels, to maximize frames or to make them
5028 fullscreen. To resize your initial frame pixelwise, set this option to
5029 a non-nil value in your init file. */);
5030 frame_resize_pixelwise
= 0;
5032 DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize
,
5033 doc
: /* Whether frames should be resized implicitly.
5034 If this option is nil, setting font, menu bar, tool bar, internal
5035 borders, fringes or scroll bars of a specific frame may resize the frame
5036 in order to preserve the number of columns or lines it displays. If
5037 this option is `t', no such resizing is done. Note that the size of
5038 fullscreen and maximized frames, the height of fullheight frames and the
5039 width of fullwidth frames never change implicitly.
5041 The value of this option can be also be a list of frame parameters. In
5042 this case, resizing is inhibited when changing a parameter that appears
5043 in that list. The parameters currently handled by this option include
5044 `font', `font-backend', `internal-border-width', `menu-bar-lines' and
5047 Changing any of the parameters `scroll-bar-width', `scroll-bar-height',
5048 `vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and
5049 `right-fringe' is handled as if the frame contained just one live
5050 window. This means, for example, that removing vertical scroll bars on
5051 a frame containing several side by side windows will shrink the frame
5052 width by the width of one scroll bar provided this option is nil and
5053 keep it unchanged if this option is either `t' or a list containing
5054 `vertical-scroll-bars'.
5056 The default value is '(tool-bar-lines) on Lucid, Motif and Windows
5057 (which means that adding/removing a tool bar does not change the frame
5058 height), nil on all other window systems including GTK+ (which means
5059 that changing any of the parameters listed above may change the size of
5060 the frame), and `t' otherwise (which means the frame size never changes
5061 implicitly when there's no window system support).
5063 Note that when a frame is not large enough to accommodate a change of
5064 any of the parameters listed above, Emacs may try to enlarge the frame
5065 even if this option is non-nil. */);
5066 #if defined (HAVE_WINDOW_SYSTEM)
5067 #if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI)
5068 frame_inhibit_implied_resize
= list1 (Qtool_bar_lines
);
5070 frame_inhibit_implied_resize
= Qnil
;
5073 frame_inhibit_implied_resize
= Qt
;
5076 staticpro (&Vframe_list
);
5079 defsubr (&Sframe_live_p
);
5080 defsubr (&Swindow_system
);
5081 defsubr (&Smake_terminal_frame
);
5082 defsubr (&Shandle_switch_frame
);
5083 defsubr (&Sselect_frame
);
5084 defsubr (&Sselected_frame
);
5085 defsubr (&Sframe_list
);
5086 defsubr (&Snext_frame
);
5087 defsubr (&Sprevious_frame
);
5088 defsubr (&Slast_nonminibuf_frame
);
5089 defsubr (&Sdelete_frame
);
5090 defsubr (&Smouse_position
);
5091 defsubr (&Smouse_pixel_position
);
5092 defsubr (&Sset_mouse_position
);
5093 defsubr (&Sset_mouse_pixel_position
);
5095 defsubr (&Sframe_configuration
);
5096 defsubr (&Srestore_frame_configuration
);
5098 defsubr (&Smake_frame_visible
);
5099 defsubr (&Smake_frame_invisible
);
5100 defsubr (&Siconify_frame
);
5101 defsubr (&Sframe_visible_p
);
5102 defsubr (&Svisible_frame_list
);
5103 defsubr (&Sraise_frame
);
5104 defsubr (&Slower_frame
);
5105 defsubr (&Sx_focus_frame
);
5106 defsubr (&Scan_run_window_configuration_change_hook
);
5107 defsubr (&Sredirect_frame_focus
);
5108 defsubr (&Sframe_focus
);
5109 defsubr (&Sframe_parameters
);
5110 defsubr (&Sframe_parameter
);
5111 defsubr (&Smodify_frame_parameters
);
5112 defsubr (&Sframe_char_height
);
5113 defsubr (&Sframe_char_width
);
5114 defsubr (&Sframe_pixel_height
);
5115 defsubr (&Sframe_pixel_width
);
5116 defsubr (&Sframe_text_cols
);
5117 defsubr (&Sframe_text_lines
);
5118 defsubr (&Sframe_total_cols
);
5119 defsubr (&Sframe_total_lines
);
5120 defsubr (&Sframe_text_width
);
5121 defsubr (&Sframe_text_height
);
5122 defsubr (&Sscroll_bar_width
);
5123 defsubr (&Sscroll_bar_height
);
5124 defsubr (&Sfringe_width
);
5125 defsubr (&Sborder_width
);
5126 defsubr (&Sright_divider_width
);
5127 defsubr (&Sbottom_divider_width
);
5128 defsubr (&Stool_bar_pixel_width
);
5129 defsubr (&Sset_frame_height
);
5130 defsubr (&Sset_frame_width
);
5131 defsubr (&Sset_frame_size
);
5132 defsubr (&Sset_frame_position
);
5133 defsubr (&Sframe_pointer_visible_p
);
5135 #ifdef HAVE_WINDOW_SYSTEM
5136 defsubr (&Sx_get_resource
);
5137 defsubr (&Sx_parse_geometry
);