1 /* Generic frame functions.
3 Copyright (C) 1993-1995, 1997, 1999-2017 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or (at
10 your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31 #ifdef HAVE_WINDOW_SYSTEM
33 #endif /* HAVE_WINDOW_SYSTEM */
36 /* These help us bind and responding to switch-frame events. */
39 #include "blockinput.h"
41 #include "termhooks.h"
42 #include "dispextern.h"
44 #ifdef HAVE_WINDOW_SYSTEM
56 /* The currently selected frame. */
58 Lisp_Object selected_frame
;
60 /* A frame which is not just a mini-buffer, or NULL if there are no such
61 frames. This is usually the most recent such frame that was selected. */
63 static struct frame
*last_nonminibuf_frame
;
65 /* False means there are no visible garbaged frames. */
68 /* The default tool bar height for future frames. */
69 #if defined USE_GTK || defined HAVE_NS
70 enum { frame_default_tool_bar_height
= 0 };
72 int frame_default_tool_bar_height
;
75 #ifdef HAVE_WINDOW_SYSTEM
76 static void x_report_frame_params (struct frame
*, Lisp_Object
*);
79 /* These setters are used only in this file, so they can be private. */
81 fset_buffer_predicate (struct frame
*f
, Lisp_Object val
)
83 f
->buffer_predicate
= val
;
86 fset_minibuffer_window (struct frame
*f
, Lisp_Object val
)
88 f
->minibuffer_window
= val
;
92 decode_live_frame (register Lisp_Object frame
)
95 frame
= selected_frame
;
96 CHECK_LIVE_FRAME (frame
);
97 return XFRAME (frame
);
101 decode_any_frame (register Lisp_Object frame
)
104 frame
= selected_frame
;
106 return XFRAME (frame
);
109 #ifdef HAVE_WINDOW_SYSTEM
111 display_available (void)
113 return x_display_list
!= NULL
;
118 decode_window_system_frame (Lisp_Object frame
)
120 struct frame
*f
= decode_live_frame (frame
);
121 check_window_system (f
);
122 #ifdef HAVE_WINDOW_SYSTEM
128 check_window_system (struct frame
*f
)
130 #ifdef HAVE_WINDOW_SYSTEM
131 if (window_system_available (f
))
134 error (f
? "Window system frame should be used"
135 : "Window system is not in use or not initialized");
138 /* Return the value of frame parameter PROP in frame FRAME. */
141 get_frame_param (register struct frame
*frame
, Lisp_Object prop
)
143 register Lisp_Object tem
;
145 tem
= Fassq (prop
, frame
->param_alist
);
153 frame_size_history_add (struct frame
*f
, Lisp_Object fun_symbol
,
154 int width
, int height
, Lisp_Object rest
)
158 XSETFRAME (frame
, f
);
159 if (CONSP (frame_size_history
)
160 && INTEGERP (XCAR (frame_size_history
))
161 && 0 < XINT (XCAR (frame_size_history
)))
163 Fcons (make_number (XINT (XCAR (frame_size_history
)) - 1),
167 ? list4 (make_number (FRAME_TEXT_WIDTH (f
)),
168 make_number (FRAME_TEXT_HEIGHT (f
)),
170 make_number (height
))
173 XCDR (frame_size_history
)));
177 /* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
178 state of frame F would be affected by a vertical (horizontal if
179 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
180 parameter that is changed. */
182 frame_inhibit_resize (struct frame
*f
, bool horizontal
, Lisp_Object parameter
)
184 Lisp_Object fullscreen
= get_frame_param (f
, Qfullscreen
);
186 = (f
->after_make_frame
187 ? (EQ (frame_inhibit_implied_resize
, Qt
)
188 || (CONSP (frame_inhibit_implied_resize
)
189 && !NILP (Fmemq (parameter
, frame_inhibit_implied_resize
)))
191 && !EQ (fullscreen
, Qnil
) && !EQ (fullscreen
, Qfullheight
))
193 && !EQ (fullscreen
, Qnil
) && !EQ (fullscreen
, Qfullwidth
))
194 || FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
195 : ((horizontal
&& f
->inhibit_horizontal_resize
)
196 || (!horizontal
&& f
->inhibit_vertical_resize
)));
197 if (inhibit
&& !FRAME_TERMCAP_P (f
) && !FRAME_MSDOS_P (f
))
198 frame_size_history_add
199 (f
, Qframe_inhibit_resize
, 0, 0,
200 list5 (horizontal
? Qt
: Qnil
, parameter
,
201 f
->after_make_frame
? Qt
: Qnil
,
202 frame_inhibit_implied_resize
,
209 set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
212 int olines
= FRAME_MENU_BAR_LINES (f
);
214 /* Right now, menu bars don't work properly in minibuf-only frames;
215 most of the commands try to apply themselves to the minibuffer
216 frame itself, and get an error because you can't switch buffers
217 in or split the minibuffer window. */
218 if (FRAME_MINIBUF_ONLY_P (f
))
221 if (TYPE_RANGED_INTEGERP (int, value
))
222 nlines
= XINT (value
);
226 if (nlines
!= olines
)
228 windows_or_buffers_changed
= 14;
229 FRAME_MENU_BAR_LINES (f
) = nlines
;
230 FRAME_MENU_BAR_HEIGHT (f
) = nlines
* FRAME_LINE_HEIGHT (f
);
231 change_frame_size (f
, FRAME_COLS (f
),
232 FRAME_LINES (f
) + olines
- nlines
,
237 Lisp_Object Vframe_list
;
240 DEFUN ("framep", Fframep
, Sframep
, 1, 1, 0,
241 doc
: /* Return non-nil if OBJECT is a frame.
243 t for a termcap frame (a character-only terminal),
244 `x' for an Emacs frame that is really an X window,
245 `w32' for an Emacs frame that is a window on MS-Windows display,
246 `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
247 `pc' for a direct-write MS-DOS frame.
248 See also `frame-live-p'. */)
251 if (!FRAMEP (object
))
253 switch (XFRAME (object
)->output_method
)
255 case output_initial
: /* The initial frame is like a termcap frame. */
258 case output_x_window
:
262 case output_msdos_raw
:
271 DEFUN ("frame-live-p", Fframe_live_p
, Sframe_live_p
, 1, 1, 0,
272 doc
: /* Return non-nil if OBJECT is a frame which has not been deleted.
273 Value is nil if OBJECT is not a live frame. If object is a live
274 frame, the return value indicates what sort of terminal device it is
275 displayed on. See the documentation of `framep' for possible
279 return ((FRAMEP (object
)
280 && FRAME_LIVE_P (XFRAME (object
)))
285 DEFUN ("window-system", Fwindow_system
, Swindow_system
, 0, 1, 0,
286 doc
: /* The name of the window system that FRAME is displaying through.
287 The value is a symbol:
288 nil for a termcap frame (a character-only terminal),
289 `x' for an Emacs frame that is really an X window,
290 `w32' for an Emacs frame that is a window on MS-Windows display,
291 `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
292 `pc' for a direct-write MS-DOS frame.
294 FRAME defaults to the currently selected frame.
296 Use of this function as a predicate is deprecated. Instead,
297 use `display-graphic-p' or any of the other `display-*-p'
298 predicates which report frame's specific UI-related capabilities. */)
303 frame
= selected_frame
;
305 type
= Fframep (frame
);
308 wrong_type_argument (Qframep
, frame
);
316 /* Placeholder used by temacs -nw before window.el is loaded. */
317 DEFUN ("frame-windows-min-size", Fframe_windows_min_size
,
318 Sframe_windows_min_size
, 4, 4, 0,
321 (Lisp_Object frame
, Lisp_Object horizontal
,
322 Lisp_Object ignore
, Lisp_Object pixelwise
)
324 return make_number (0);
328 * frame_windows_min_size:
330 * Return the minimum number of lines (columns if HORIZONTAL is non-nil)
331 * of FRAME. If PIXELWISE is non-nil, return the minimum height (width)
334 * This value is calculated by the function `frame-windows-min-size' in
335 * window.el unless the `min-height' (`min-width' if HORIZONTAL is
336 * non-nil) parameter of FRAME is non-nil thus explicitly specifying the
337 * value to be returned. In that latter case IGNORE is ignored.
339 * If `frame-windows-min-size' is called, it will make sure that the
340 * return value accommodates all windows of FRAME respecting the values
341 * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil).
342 * With IGNORE non-nil the values of these variables are ignored.
344 * In either case never return a value less than 1.
347 frame_windows_min_size (Lisp_Object frame
, Lisp_Object horizontal
,
348 Lisp_Object ignore
, Lisp_Object pixelwise
)
350 struct frame
*f
= XFRAME (frame
);
351 Lisp_Object par_size
;
353 if ((!NILP (horizontal
)
354 && NUMBERP (par_size
= get_frame_param (f
, Qmin_width
)))
355 || (NILP (horizontal
)
356 && NUMBERP (par_size
= get_frame_param (f
, Qmin_height
))))
358 int min_size
= XINT (par_size
);
360 /* Don't allow phantom frames. */
364 return (NILP (pixelwise
)
366 : min_size
* (NILP (horizontal
)
367 ? FRAME_LINE_HEIGHT (f
)
368 : FRAME_COLUMN_WIDTH (f
)));
371 return XINT (call4 (Qframe_windows_min_size
, frame
, horizontal
,
376 /* Make sure windows sizes of frame F are OK. new_width and new_height
377 are in pixels. A value of -1 means no change is requested for that
378 size (but the frame may still have to be resized to accommodate
379 windows with their minimum sizes). This can either issue a request
380 to resize the frame externally (via x_set_window_size), to resize the
381 frame internally (via resize_frame_windows) or do nothing at all.
383 The argument INHIBIT can assume the following values:
385 0 means to unconditionally call x_set_window_size even if sizes
386 apparently do not change. Fx_create_frame uses this to pass the
387 initial size to the window manager.
389 1 means to call x_set_window_size if the outer frame size really
390 changes. Fset_frame_size, Fset_frame_height, ... use this.
392 2 means to call x_set_window_size provided frame_inhibit_resize
393 allows it. The menu and tool bar code use this ("3" won't work
394 here in general because menu and tool bar are often not counted in
395 the frame's text height).
397 3 means call x_set_window_size if window minimum sizes must be
398 preserved or frame_inhibit_resize allows it. x_set_left_fringe,
399 x_set_scroll_bar_width, x_new_font ... use (or should use) this.
401 4 means call x_set_window_size only if window minimum sizes must be
402 preserved. x_set_right_divider_width, x_set_border_width and the
403 code responsible for wrapping the tool bar use this.
405 5 means to never call x_set_window_size. change_frame_size uses
408 Note that even when x_set_window_size is not called, individual
409 windows may have to be resized (via `window--sanitize-window-sizes')
410 in order to support minimum size constraints.
412 PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the
413 symbol of the parameter changed (like `menu-bar-lines', `font', ...).
414 This is passed on to frame_inhibit_resize to let the latter decide on
415 a case-by-case basis whether the frame may be resized externally. */
417 adjust_frame_size (struct frame
*f
, int new_width
, int new_height
, int inhibit
,
418 bool pretend
, Lisp_Object parameter
)
420 int unit_width
= FRAME_COLUMN_WIDTH (f
);
421 int unit_height
= FRAME_LINE_HEIGHT (f
);
422 int old_pixel_width
= FRAME_PIXEL_WIDTH (f
);
423 int old_pixel_height
= FRAME_PIXEL_HEIGHT (f
);
424 int old_cols
= FRAME_COLS (f
);
425 int old_lines
= FRAME_LINES (f
);
426 int new_pixel_width
, new_pixel_height
;
427 /* The following two values are calculated from the old frame pixel
428 sizes and any "new" settings for tool bar, menu bar and internal
429 borders. We do it this way to detect whether we have to call
430 x_set_window_size as consequence of the new settings. */
431 int windows_width
= FRAME_WINDOWS_WIDTH (f
);
432 int windows_height
= FRAME_WINDOWS_HEIGHT (f
);
433 int min_windows_width
, min_windows_height
;
434 /* These are a bit tedious, maybe we should use a macro. */
435 struct window
*r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
436 int old_windows_width
= WINDOW_PIXEL_WIDTH (r
);
437 int old_windows_height
438 = (WINDOW_PIXEL_HEIGHT (r
)
439 + ((FRAME_HAS_MINIBUF_P (f
) && !FRAME_MINIBUF_ONLY_P (f
))
440 ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f
)))
442 int new_windows_width
, new_windows_height
;
443 int old_text_width
= FRAME_TEXT_WIDTH (f
);
444 int old_text_height
= FRAME_TEXT_HEIGHT (f
);
445 /* If a size is < 0 use the old value. */
446 int new_text_width
= (new_width
>= 0) ? new_width
: old_text_width
;
447 int new_text_height
= (new_height
>= 0) ? new_height
: old_text_height
;
448 int new_cols
, new_lines
;
449 bool inhibit_horizontal
, inhibit_vertical
;
452 XSETFRAME (frame
, f
);
454 frame_size_history_add
455 (f
, Qadjust_frame_size_1
, new_text_width
, new_text_height
,
456 list2 (parameter
, make_number (inhibit
)));
458 /* The following two values are calculated from the old window body
459 sizes and any "new" settings for scroll bars, dividers, fringes and
460 margins (though the latter should have been processed already). */
462 = frame_windows_min_size (frame
, Qt
, (inhibit
== 5) ? Qt
: Qnil
, Qt
);
464 = frame_windows_min_size (frame
, Qnil
, (inhibit
== 5) ? Qt
: Qnil
, Qt
);
466 if (inhibit
>= 2 && inhibit
<= 4)
467 /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
468 within the limits and either resizing is inhibited or INHIBIT
471 inhibit_horizontal
= (windows_width
>= min_windows_width
473 || frame_inhibit_resize (f
, true, parameter
)));
474 inhibit_vertical
= (windows_height
>= min_windows_height
476 || frame_inhibit_resize (f
, false, parameter
)));
479 /* Otherwise inhibit if INHIBIT equals 5. */
480 inhibit_horizontal
= inhibit_vertical
= inhibit
== 5;
482 new_pixel_width
= ((inhibit_horizontal
&& (inhibit
< 5))
484 : max (FRAME_TEXT_TO_PIXEL_WIDTH (f
, new_text_width
),
486 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)));
487 new_windows_width
= new_pixel_width
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
488 new_text_width
= FRAME_PIXEL_TO_TEXT_WIDTH (f
, new_pixel_width
);
489 new_cols
= new_text_width
/ unit_width
;
491 new_pixel_height
= ((inhibit_vertical
&& (inhibit
< 5))
493 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f
, new_text_height
),
495 + FRAME_TOP_MARGIN_HEIGHT (f
)
496 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f
)));
497 new_windows_height
= (new_pixel_height
498 - FRAME_TOP_MARGIN_HEIGHT (f
)
499 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
500 new_text_height
= FRAME_PIXEL_TO_TEXT_HEIGHT (f
, new_pixel_height
);
501 new_lines
= new_text_height
/ unit_height
;
503 #ifdef HAVE_WINDOW_SYSTEM
504 if (FRAME_WINDOW_P (f
)
505 && f
->can_x_set_window_size
506 && ((!inhibit_horizontal
507 && (new_pixel_width
!= old_pixel_width
508 || inhibit
== 0 || inhibit
== 2))
509 || (!inhibit_vertical
510 && (new_pixel_height
!= old_pixel_height
511 || inhibit
== 0 || inhibit
== 2))))
512 /* We are either allowed to change the frame size or the minimum
513 sizes request such a change. Do not care for fixing minimum
514 sizes here, we do that eventually when we're called from
515 change_frame_size. */
517 /* Make sure we respect fullheight and fullwidth. */
518 if (inhibit_horizontal
)
519 new_text_width
= old_text_width
;
520 else if (inhibit_vertical
)
521 new_text_height
= old_text_height
;
523 frame_size_history_add
524 (f
, Qadjust_frame_size_2
, new_text_width
, new_text_height
,
525 list2 (inhibit_horizontal
? Qt
: Qnil
,
526 inhibit_vertical
? Qt
: Qnil
));
528 x_set_window_size (f
, 0, new_text_width
, new_text_height
, 1);
535 if (new_text_width
== old_text_width
536 && new_text_height
== old_text_height
537 && new_windows_width
== old_windows_width
538 && new_windows_height
== old_windows_height
539 && new_pixel_width
== old_pixel_width
540 && new_pixel_height
== old_pixel_height
541 && new_cols
== old_cols
542 && new_lines
== old_lines
)
543 /* No change. Sanitize window sizes and return. */
545 sanitize_window_sizes (Qt
);
546 sanitize_window_sizes (Qnil
);
554 /* We only can set screen dimensions to certain values supported by
555 our video hardware. Try to find the smallest size greater or
556 equal to the requested dimensions, while accounting for the fact
557 that the menu-bar lines are not counted in the frame height. */
558 int dos_new_lines
= new_lines
+ FRAME_TOP_MARGIN (f
);
559 dos_set_window_size (&dos_new_lines
, &new_cols
);
560 new_lines
= dos_new_lines
- FRAME_TOP_MARGIN (f
);
563 if (new_windows_width
!= old_windows_width
)
565 resize_frame_windows (f
, new_windows_width
, 1, 1);
567 /* MSDOS frames cannot PRETEND, as they change frame size by
568 manipulating video hardware. */
569 if ((FRAME_TERMCAP_P (f
) && !pretend
) || FRAME_MSDOS_P (f
))
570 FrameCols (FRAME_TTY (f
)) = new_cols
;
572 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
573 if (WINDOWP (f
->tool_bar_window
))
575 XWINDOW (f
->tool_bar_window
)->pixel_width
= new_windows_width
;
576 XWINDOW (f
->tool_bar_window
)->total_cols
577 = new_windows_width
/ unit_width
;
581 else if (new_cols
!= old_cols
)
582 call2 (Qwindow__pixel_to_total
, frame
, Qt
);
584 if (new_windows_height
!= old_windows_height
585 /* When the top margin has changed we have to recalculate the top
586 edges of all windows. No such calculation is necessary for the
588 || WINDOW_TOP_PIXEL_EDGE (r
) != FRAME_TOP_MARGIN_HEIGHT (f
))
590 resize_frame_windows (f
, new_windows_height
, 0, 1);
592 /* MSDOS frames cannot PRETEND, as they change frame size by
593 manipulating video hardware. */
594 if ((FRAME_TERMCAP_P (f
) && !pretend
) || FRAME_MSDOS_P (f
))
595 FrameRows (FRAME_TTY (f
)) = new_lines
+ FRAME_TOP_MARGIN (f
);
597 else if (new_lines
!= old_lines
)
598 call2 (Qwindow__pixel_to_total
, frame
, Qnil
);
600 frame_size_history_add
601 (f
, Qadjust_frame_size_3
, new_text_width
, new_text_height
,
602 list4 (make_number (old_pixel_width
), make_number (old_pixel_height
),
603 make_number (new_pixel_width
), make_number (new_pixel_height
)));
605 /* Assign new sizes. */
606 FRAME_TEXT_WIDTH (f
) = new_text_width
;
607 FRAME_TEXT_HEIGHT (f
) = new_text_height
;
608 FRAME_PIXEL_WIDTH (f
) = new_pixel_width
;
609 FRAME_PIXEL_HEIGHT (f
) = new_pixel_height
;
610 SET_FRAME_COLS (f
, new_cols
);
611 SET_FRAME_LINES (f
, new_lines
);
614 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
615 int text_area_x
, text_area_y
, text_area_width
, text_area_height
;
617 window_box (w
, TEXT_AREA
, &text_area_x
, &text_area_y
, &text_area_width
,
619 if (w
->cursor
.x
>= text_area_x
+ text_area_width
)
620 w
->cursor
.hpos
= w
->cursor
.x
= 0;
621 if (w
->cursor
.y
>= text_area_y
+ text_area_height
)
622 w
->cursor
.vpos
= w
->cursor
.y
= 0;
625 /* Sanitize window sizes. */
626 sanitize_window_sizes (Qt
);
627 sanitize_window_sizes (Qnil
);
629 adjust_frame_glyphs (f
);
631 SET_FRAME_GARBAGED (f
);
633 /* A frame was "resized" if one of its pixelsizes changed, even if its
634 X window wasn't resized at all. */
635 f
->resized_p
= (new_pixel_width
!= old_pixel_width
636 || new_pixel_height
!= old_pixel_height
);
641 /* Allocate basically initialized frame. */
643 static struct frame
*
644 allocate_frame (void)
646 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct frame
, face_cache
, PVEC_FRAME
);
650 make_frame (bool mini_p
)
654 struct window
*rw
, *mw UNINIT
;
655 Lisp_Object root_window
;
656 Lisp_Object mini_window
;
658 f
= allocate_frame ();
659 XSETFRAME (frame
, f
);
662 /* Initialize Lisp data. Note that allocate_frame initializes all
663 Lisp data to nil, so do it only for slots which should not be nil. */
664 fset_tool_bar_position (f
, Qtop
);
667 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
668 non-Lisp data, so do it only for slots which should not be zero.
669 To avoid subtle bugs and for the sake of readability, it's better to
670 initialize enum members explicitly even if their values are zero. */
671 f
->wants_modeline
= true;
674 f
->can_x_set_window_size
= false;
675 f
->after_make_frame
= false;
676 f
->inhibit_horizontal_resize
= false;
677 f
->inhibit_vertical_resize
= false;
678 f
->tool_bar_redisplayed
= false;
679 f
->tool_bar_resized
= false;
680 f
->column_width
= 1; /* !FRAME_WINDOW_P value. */
681 f
->line_height
= 1; /* !FRAME_WINDOW_P value. */
682 #ifdef HAVE_WINDOW_SYSTEM
683 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
684 f
->horizontal_scroll_bars
= false;
685 f
->want_fullscreen
= FULLSCREEN_NONE
;
686 f
->undecorated
= false;
688 f
->override_redirect
= false;
690 f
->skip_taskbar
= false;
691 f
->no_focus_on_map
= false;
692 f
->no_accept_focus
= false;
693 f
->z_group
= z_group_none
;
694 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
695 f
->last_tool_bar_item
= -1;
699 root_window
= make_window ();
700 rw
= XWINDOW (root_window
);
703 mini_window
= make_window ();
704 mw
= XWINDOW (mini_window
);
705 wset_next (rw
, mini_window
);
706 wset_prev (mw
, root_window
);
708 wset_frame (mw
, frame
);
709 fset_minibuffer_window (f
, mini_window
);
710 store_frame_param (f
, Qminibuffer
, Qt
);
715 wset_next (rw
, Qnil
);
716 fset_minibuffer_window (f
, Qnil
);
719 wset_frame (rw
, frame
);
722 just so that there is "something there."
723 Correct size will be set up later with adjust_frame_size. */
725 SET_FRAME_COLS (f
, 10);
726 SET_FRAME_LINES (f
, 10);
727 SET_FRAME_WIDTH (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
));
728 SET_FRAME_HEIGHT (f
, FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
));
731 rw
->pixel_width
= rw
->total_cols
* FRAME_COLUMN_WIDTH (f
);
732 rw
->total_lines
= mini_p
? 9 : 10;
733 rw
->pixel_height
= rw
->total_lines
* FRAME_LINE_HEIGHT (f
);
737 mw
->top_line
= rw
->total_lines
;
738 mw
->pixel_top
= rw
->pixel_height
;
739 mw
->total_cols
= rw
->total_cols
;
740 mw
->pixel_width
= rw
->pixel_width
;
742 mw
->pixel_height
= FRAME_LINE_HEIGHT (f
);
745 /* Choose a buffer for the frame's root window. */
747 Lisp_Object buf
= Fcurrent_buffer ();
749 /* If current buffer is hidden, try to find another one. */
750 if (BUFFER_HIDDEN_P (XBUFFER (buf
)))
751 buf
= other_buffer_safely (buf
);
753 /* Use set_window_buffer, not Fset_window_buffer, and don't let
754 hooks be run by it. The reason is that the whole frame/window
755 arrangement is not yet fully initialized at this point. Windows
756 don't have the right size, glyph matrices aren't initialized
757 etc. Running Lisp functions at this point surely ends in a
759 set_window_buffer (root_window
, buf
, 0, 0);
760 fset_buffer_list (f
, list1 (buf
));
765 set_window_buffer (mini_window
,
766 (NILP (Vminibuffer_list
)
768 : Fcar (Vminibuffer_list
)),
770 /* No horizontal scroll bars in minibuffers. */
771 wset_horizontal_scroll_bar (mw
, Qnil
);
774 fset_root_window (f
, root_window
);
775 fset_selected_window (f
, root_window
);
776 /* Make sure this window seems more recently used than
777 a newly-created, never-selected window. */
778 XWINDOW (f
->selected_window
)->use_time
= ++window_select_count
;
783 #ifdef HAVE_WINDOW_SYSTEM
784 /* Make a frame using a separate minibuffer window on another frame.
785 MINI_WINDOW is the minibuffer window to use. nil means use the
786 default (the global minibuffer). */
789 make_frame_without_minibuffer (Lisp_Object mini_window
, KBOARD
*kb
,
794 if (!NILP (mini_window
))
795 CHECK_LIVE_WINDOW (mini_window
);
797 if (!NILP (mini_window
)
798 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window
)->frame
)) != kb
)
799 error ("Frame and minibuffer must be on the same terminal");
801 /* Make a frame containing just a root window. */
804 if (NILP (mini_window
))
806 /* Use default-minibuffer-frame if possible. */
807 if (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
808 || ! FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
))))
810 Lisp_Object frame_dummy
;
812 XSETFRAME (frame_dummy
, f
);
813 /* If there's no minibuffer frame to use, create one. */
814 kset_default_minibuffer_frame
815 (kb
, call1 (intern ("make-initial-minibuffer-frame"), display
));
819 = XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
))->minibuffer_window
;
822 fset_minibuffer_window (f
, mini_window
);
823 store_frame_param (f
, Qminibuffer
, mini_window
);
825 /* Make the chosen minibuffer window display the proper minibuffer,
826 unless it is already showing a minibuffer. */
827 if (NILP (Fmemq (XWINDOW (mini_window
)->contents
, Vminibuffer_list
)))
828 /* Use set_window_buffer instead of Fset_window_buffer (see
829 discussion of bug#11984, bug#12025, bug#12026). */
830 set_window_buffer (mini_window
,
831 (NILP (Vminibuffer_list
)
833 : Fcar (Vminibuffer_list
)), 0, 0);
837 /* Make a frame containing only a minibuffer window. */
840 make_minibuffer_frame (void)
842 /* First make a frame containing just a root window, no minibuffer. */
844 register struct frame
*f
= make_frame (0);
845 register Lisp_Object mini_window
;
846 register Lisp_Object frame
;
848 XSETFRAME (frame
, f
);
853 f
->wants_modeline
= 0;
855 /* Now label the root window as also being the minibuffer.
856 Avoid infinite looping on the window chain by marking next pointer
859 mini_window
= f
->root_window
;
860 fset_minibuffer_window (f
, mini_window
);
861 store_frame_param (f
, Qminibuffer
, Qonly
);
862 XWINDOW (mini_window
)->mini
= 1;
863 wset_next (XWINDOW (mini_window
), Qnil
);
864 wset_prev (XWINDOW (mini_window
), Qnil
);
865 wset_frame (XWINDOW (mini_window
), frame
);
867 /* Put the proper buffer in that window. */
869 /* Use set_window_buffer instead of Fset_window_buffer (see
870 discussion of bug#11984, bug#12025, bug#12026). */
871 set_window_buffer (mini_window
,
872 (NILP (Vminibuffer_list
)
874 : Fcar (Vminibuffer_list
)), 0, 0);
877 #endif /* HAVE_WINDOW_SYSTEM */
879 /* Construct a frame that refers to a terminal. */
881 static printmax_t tty_frame_count
;
884 make_initial_frame (void)
887 struct terminal
*terminal
;
890 eassert (initial_kboard
);
892 /* The first call must initialize Vframe_list. */
893 if (! (NILP (Vframe_list
) || CONSP (Vframe_list
)))
896 terminal
= init_initial_terminal ();
899 XSETFRAME (frame
, f
);
901 Vframe_list
= Fcons (frame
, Vframe_list
);
904 fset_name (f
, build_pure_c_string ("F1"));
906 SET_FRAME_VISIBLE (f
, 1);
908 f
->output_method
= terminal
->type
;
909 f
->terminal
= terminal
;
910 f
->terminal
->reference_count
++;
911 f
->output_data
.nothing
= 0;
913 FRAME_FOREGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_FG_COLOR
;
914 FRAME_BACKGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_BG_COLOR
;
916 #ifdef HAVE_WINDOW_SYSTEM
917 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
918 f
->horizontal_scroll_bars
= false;
921 /* The default value of menu-bar-mode is t. */
922 set_menu_bar_lines (f
, make_number (1), Qnil
);
924 /* Allocate glyph matrices. */
925 adjust_frame_glyphs (f
);
928 init_frame_faces (f
);
930 last_nonminibuf_frame
= f
;
932 f
->can_x_set_window_size
= true;
933 f
->after_make_frame
= true;
939 static struct frame
*
940 make_terminal_frame (struct terminal
*terminal
)
942 register struct frame
*f
;
944 char name
[sizeof "F" + INT_STRLEN_BOUND (printmax_t
)];
947 error ("Terminal is not live, can't create new frames on it");
951 XSETFRAME (frame
, f
);
952 Vframe_list
= Fcons (frame
, Vframe_list
);
954 fset_name (f
, make_formatted_string (name
, "F%"pMd
, ++tty_frame_count
));
956 SET_FRAME_VISIBLE (f
, 1);
958 f
->terminal
= terminal
;
959 f
->terminal
->reference_count
++;
961 f
->output_data
.tty
->display_info
= &the_only_display_info
;
962 if (!inhibit_window_system
963 && (!FRAMEP (selected_frame
) || !FRAME_LIVE_P (XFRAME (selected_frame
))
964 || XFRAME (selected_frame
)->output_method
== output_msdos_raw
))
965 f
->output_method
= output_msdos_raw
;
967 f
->output_method
= output_termcap
;
968 #else /* not MSDOS */
969 f
->output_method
= output_termcap
;
970 create_tty_output (f
);
971 FRAME_FOREGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_FG_COLOR
;
972 FRAME_BACKGROUND_PIXEL (f
) = FACE_TTY_DEFAULT_BG_COLOR
;
973 #endif /* not MSDOS */
975 #ifdef HAVE_WINDOW_SYSTEM
976 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
977 f
->horizontal_scroll_bars
= false;
980 FRAME_MENU_BAR_LINES (f
) = NILP (Vmenu_bar_mode
) ? 0 : 1;
981 FRAME_LINES (f
) = FRAME_LINES (f
) - FRAME_MENU_BAR_LINES (f
);
982 FRAME_MENU_BAR_HEIGHT (f
) = FRAME_MENU_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
);
983 FRAME_TEXT_HEIGHT (f
) = FRAME_TEXT_HEIGHT (f
) - FRAME_MENU_BAR_HEIGHT (f
);
985 /* Set the top frame to the newly created frame. */
986 if (FRAMEP (FRAME_TTY (f
)->top_frame
)
987 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f
)->top_frame
)))
988 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f
)->top_frame
), 2); /* obscured */
990 FRAME_TTY (f
)->top_frame
= frame
;
993 init_frame_faces (f
);
998 /* Get a suitable value for frame parameter PARAMETER for a newly
999 created frame, based on (1) the user-supplied frame parameter
1000 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
1003 get_future_frame_param (Lisp_Object parameter
,
1004 Lisp_Object supplied_parms
,
1005 char *current_value
)
1009 result
= Fassq (parameter
, supplied_parms
);
1011 result
= Fassq (parameter
, XFRAME (selected_frame
)->param_alist
);
1012 if (NILP (result
) && current_value
!= NULL
)
1013 result
= build_string (current_value
);
1014 if (!NILP (result
) && !STRINGP (result
))
1015 result
= XCDR (result
);
1016 if (NILP (result
) || !STRINGP (result
))
1022 DEFUN ("make-terminal-frame", Fmake_terminal_frame
, Smake_terminal_frame
,
1024 doc
: /* Create an additional terminal frame, possibly on another terminal.
1025 This function takes one argument, an alist specifying frame parameters.
1027 You can create multiple frames on a single text terminal, but only one
1028 of them (the selected terminal frame) is actually displayed.
1030 In practice, generally you don't need to specify any parameters,
1031 except when you want to create a new frame on another terminal.
1032 In that case, the `tty' parameter specifies the device file to open,
1033 and the `tty-type' parameter specifies the terminal type. Example:
1035 (make-terminal-frame \\='((tty . "/dev/pts/5") (tty-type . "xterm")))
1037 Note that changing the size of one terminal frame automatically
1038 affects all frames on the same terminal device. */)
1042 struct terminal
*t
= NULL
;
1043 Lisp_Object frame
, tem
;
1044 struct frame
*sf
= SELECTED_FRAME ();
1047 if (sf
->output_method
!= output_msdos_raw
1048 && sf
->output_method
!= output_termcap
)
1050 #else /* not MSDOS */
1052 #ifdef WINDOWSNT /* This should work now! */
1053 if (sf
->output_method
!= output_termcap
)
1054 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
1056 #endif /* not MSDOS */
1059 Lisp_Object terminal
;
1061 terminal
= Fassq (Qterminal
, parms
);
1062 if (CONSP (terminal
))
1064 terminal
= XCDR (terminal
);
1065 t
= decode_live_terminal (terminal
);
1068 if (t
&& t
!= the_only_display_info
.terminal
)
1069 /* msdos.c assumes a single tty_display_info object. */
1070 error ("Multiple terminals are not supported on this platform");
1072 t
= the_only_display_info
.terminal
;
1078 char *name
= 0, *type
= 0;
1079 Lisp_Object tty
, tty_type
;
1082 tty
= get_future_frame_param
1083 (Qtty
, parms
, (FRAME_TERMCAP_P (XFRAME (selected_frame
))
1084 ? FRAME_TTY (XFRAME (selected_frame
))->name
1087 SAFE_ALLOCA_STRING (name
, tty
);
1089 tty_type
= get_future_frame_param
1090 (Qtty_type
, parms
, (FRAME_TERMCAP_P (XFRAME (selected_frame
))
1091 ? FRAME_TTY (XFRAME (selected_frame
))->type
1093 if (!NILP (tty_type
))
1094 SAFE_ALLOCA_STRING (type
, tty_type
);
1096 t
= init_tty (name
, type
, 0); /* Errors are not fatal. */
1100 f
= make_terminal_frame (t
);
1104 get_tty_size (fileno (FRAME_TTY (f
)->input
), &width
, &height
);
1105 adjust_frame_size (f
, width
, height
- FRAME_MENU_BAR_LINES (f
),
1106 5, 0, Qterminal_frame
);
1109 adjust_frame_glyphs (f
);
1110 calculate_costs (f
);
1111 XSETFRAME (frame
, f
);
1113 store_in_alist (&parms
, Qtty_type
, build_string (t
->display_info
.tty
->type
));
1114 store_in_alist (&parms
, Qtty
,
1115 (t
->display_info
.tty
->name
1116 ? build_string (t
->display_info
.tty
->name
)
1118 /* On terminal frames the `minibuffer' frame parameter is always
1119 virtually t. Avoid that a different value in parms causes
1120 complaints, see Bug#24758. */
1121 store_in_alist (&parms
, Qminibuffer
, Qt
);
1122 Fmodify_frame_parameters (frame
, parms
);
1124 /* Make the frame face alist be frame-specific, so that each
1125 frame could change its face definitions independently. */
1126 fset_face_alist (f
, Fcopy_alist (sf
->face_alist
));
1127 /* Simple Fcopy_alist isn't enough, because we need the contents of
1128 the vectors which are the CDRs of associations in face_alist to
1129 be copied as well. */
1130 for (tem
= f
->face_alist
; CONSP (tem
); tem
= XCDR (tem
))
1131 XSETCDR (XCAR (tem
), Fcopy_sequence (XCDR (XCAR (tem
))));
1133 f
->can_x_set_window_size
= true;
1134 f
->after_make_frame
= true;
1140 /* Perform the switch to frame FRAME.
1142 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
1145 If TRACK is non-zero and the frame that currently has the focus
1146 redirects its focus to the selected frame, redirect that focused
1147 frame's focus to FRAME instead.
1149 FOR_DELETION non-zero means that the selected frame is being
1150 deleted, which includes the possibility that the frame's terminal
1153 The value of NORECORD is passed as argument to Fselect_window. */
1156 do_switch_frame (Lisp_Object frame
, int track
, int for_deletion
, Lisp_Object norecord
)
1158 struct frame
*sf
= SELECTED_FRAME (), *f
;
1160 /* If FRAME is a switch-frame event, extract the frame we should
1163 && EQ (XCAR (frame
), Qswitch_frame
)
1164 && CONSP (XCDR (frame
)))
1165 frame
= XCAR (XCDR (frame
));
1167 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
1168 a switch-frame event to arrive after a frame is no longer live,
1169 especially when deleting the initial frame during startup. */
1170 CHECK_FRAME (frame
);
1172 if (!FRAME_LIVE_P (f
))
1177 /* If a frame's focus has been redirected toward the currently
1178 selected frame, we should change the redirection to point to the
1179 newly selected frame. This means that if the focus is redirected
1180 from a minibufferless frame to a surrogate minibuffer frame, we
1181 can use `other-window' to switch between all the frames using
1182 that minibuffer frame, and the focus redirection will follow us
1185 /* This is too greedy; it causes inappropriate focus redirection
1186 that's hard to get rid of. */
1191 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1195 if (!FRAMEP (XCAR (tail
)))
1198 focus
= FRAME_FOCUS_FRAME (XFRAME (XCAR (tail
)));
1200 if (FRAMEP (focus
) && XFRAME (focus
) == SELECTED_FRAME ())
1201 Fredirect_frame_focus (XCAR (tail
), frame
);
1205 /* Instead, apply it only to the frame we're pointing to. */
1206 #ifdef HAVE_WINDOW_SYSTEM
1207 if (track
&& FRAME_WINDOW_P (f
))
1209 Lisp_Object focus
, xfocus
;
1211 xfocus
= x_get_focus_frame (f
);
1212 if (FRAMEP (xfocus
))
1214 focus
= FRAME_FOCUS_FRAME (XFRAME (xfocus
));
1215 if ((FRAMEP (focus
) && XFRAME (focus
) == SELECTED_FRAME ())
1216 /* Redirect frame focus also when FRAME has its minibuffer
1217 window on the selected frame (see Bug#24500). */
1219 && EQ (FRAME_MINIBUF_WINDOW (f
), sf
->selected_window
)))
1220 Fredirect_frame_focus (xfocus
, frame
);
1223 #endif /* HAVE_X_WINDOWS */
1226 if (!for_deletion
&& FRAME_HAS_MINIBUF_P (sf
))
1227 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf
)), 1);
1229 if (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
1231 struct tty_display_info
*tty
= FRAME_TTY (f
);
1232 Lisp_Object top_frame
= tty
->top_frame
;
1234 /* Don't mark the frame garbaged and/or obscured if we are
1235 switching to the frame that is already the top frame of that
1237 if (!EQ (frame
, top_frame
))
1239 if (FRAMEP (top_frame
))
1240 /* Mark previously displayed frame as now obscured. */
1241 SET_FRAME_VISIBLE (XFRAME (top_frame
), 2);
1242 SET_FRAME_VISIBLE (f
, 1);
1243 /* If the new TTY frame changed dimensions, we need to
1244 resync term.c's idea of the frame size with the new
1246 if (FRAME_COLS (f
) != FrameCols (tty
))
1247 FrameCols (tty
) = FRAME_COLS (f
);
1248 if (FRAME_TOTAL_LINES (f
) != FrameRows (tty
))
1249 FrameRows (tty
) = FRAME_TOTAL_LINES (f
);
1251 tty
->top_frame
= frame
;
1254 selected_frame
= frame
;
1255 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame
)))
1256 last_nonminibuf_frame
= XFRAME (selected_frame
);
1258 Fselect_window (f
->selected_window
, norecord
);
1260 /* We want to make sure that the next event generates a frame-switch
1261 event to the appropriate frame. This seems kludgy to me, but
1262 before you take it out, make sure that evaluating something like
1263 (select-window (frame-root-window (new-frame))) doesn't end up
1264 with your typing being interpreted in the new frame instead of
1265 the one you're actually typing in. */
1266 #ifdef HAVE_WINDOW_SYSTEM
1267 if (!frame_ancestor_p (f
, sf
))
1269 internal_last_event_frame
= Qnil
;
1274 DEFUN ("select-frame", Fselect_frame
, Sselect_frame
, 1, 2, "e",
1275 doc
: /* Select FRAME.
1276 Subsequent editing commands apply to its selected window.
1277 Optional argument NORECORD means to neither change the order of
1278 recently selected windows nor the buffer list.
1280 The selection of FRAME lasts until the next time the user does
1281 something to select a different frame, or until the next time
1282 this function is called. If you are using a window system, the
1283 previously selected frame may be restored as the selected frame
1284 when returning to the command loop, because it still may have
1285 the window system's input focus. On a text terminal, the next
1286 redisplay will display FRAME.
1288 This function returns FRAME, or nil if FRAME has been deleted. */)
1289 (Lisp_Object frame
, Lisp_Object norecord
)
1291 return do_switch_frame (frame
, 1, 0, norecord
);
1294 DEFUN ("handle-switch-frame", Fhandle_switch_frame
, Shandle_switch_frame
, 1, 1, "^e",
1295 doc
: /* Handle a switch-frame event EVENT.
1296 Switch-frame events are usually bound to this function.
1297 A switch-frame event tells Emacs that the window manager has requested
1298 that the user's events be directed to the frame mentioned in the event.
1299 This function selects the selected window of the frame of EVENT.
1301 If EVENT is frame object, handle it as if it were a switch-frame event
1307 /* Preserve prefix arg that the command loop just cleared. */
1308 kset_prefix_arg (current_kboard
, Vcurrent_prefix_arg
);
1309 run_hook (Qmouse_leave_buffer_hook
);
1310 /* `switch-frame' implies a focus in. */
1311 value
= do_switch_frame (event
, 0, 0, Qnil
);
1312 call1 (intern ("handle-focus-in"), event
);
1316 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
1317 doc
: /* Return the frame that is now selected. */)
1320 return selected_frame
;
1323 DEFUN ("frame-list", Fframe_list
, Sframe_list
,
1325 doc
: /* Return a list of all live frames. */)
1329 frames
= Fcopy_sequence (Vframe_list
);
1330 #ifdef HAVE_WINDOW_SYSTEM
1331 if (FRAMEP (tip_frame
))
1332 frames
= Fdelq (tip_frame
, frames
);
1337 DEFUN ("frame-parent", Fframe_parent
, Sframe_parent
,
1339 doc
: /* Return the parent frame of FRAME.
1340 The parent frame of FRAME is the Emacs frame whose window-system window
1341 is the parent window of FRAME's window-system window. When such a frame
1342 exists, FRAME is considered a child frame of that frame.
1344 Return nil if FRAME has no parent frame. This means that FRAME's
1345 window-system window is either a "top-level" window (a window whose
1346 parent window is the window-system's root window) or an embedded window
1347 \(a window whose parent window is owned by some other application). */)
1350 struct frame
*f
= decode_live_frame (frame
);
1351 struct frame
*p
= FRAME_PARENT_FRAME (f
);
1354 /* Can't return f->parent_frame directly since it might not be defined
1355 for this platform. */
1358 XSETFRAME (parent
, p
);
1366 #ifdef HAVE_WINDOW_SYSTEM
1368 frame_ancestor_p (struct frame
*af
, struct frame
*df
)
1370 struct frame
*pf
= FRAME_PARENT_FRAME (df
);
1377 pf
= FRAME_PARENT_FRAME (pf
);
1384 DEFUN ("frame-ancestor-p", Fframe_ancestor_p
, Sframe_ancestor_p
,
1386 doc
: /* Return non-nil if ANCESTOR is an ancestor of DESCENDANT.
1387 ANCESTOR is an ancestor of DESCENDANT when it is either DESCENDANT's
1388 parent frame or it is an ancestor of DESCENDANT's parent frame. Both,
1389 ANCESTOR and DESCENDANT must be live frames and default to the selected
1391 (Lisp_Object ancestor
, Lisp_Object descendant
)
1393 #ifdef HAVE_WINDOW_SYSTEM
1394 struct frame
*af
= decode_live_frame (ancestor
);
1395 struct frame
*df
= decode_live_frame (descendant
);
1397 return frame_ancestor_p (af
, df
) ? Qt
: Qnil
;
1403 /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1404 same tty (for tty frames) or among frames which uses FRAME's keyboard.
1405 If MINIBUF is nil, do not consider minibuffer-only candidate.
1406 If MINIBUF is `visible', do not consider an invisible candidate.
1407 If MINIBUF is a window, consider only its own frame and candidate now
1408 using that window as the minibuffer.
1409 If MINIBUF is 0, consider candidate if it is visible or iconified.
1410 Otherwise consider any candidate and return nil if CANDIDATE is not
1414 candidate_frame (Lisp_Object candidate
, Lisp_Object frame
, Lisp_Object minibuf
)
1416 struct frame
*c
= XFRAME (candidate
), *f
= XFRAME (frame
);
1418 if ((!FRAME_TERMCAP_P (c
) && !FRAME_TERMCAP_P (f
)
1419 && FRAME_KBOARD (c
) == FRAME_KBOARD (f
))
1420 || (FRAME_TERMCAP_P (c
) && FRAME_TERMCAP_P (f
)
1421 && FRAME_TTY (c
) == FRAME_TTY (f
)))
1423 if (!NILP (get_frame_param (c
, Qno_other_frame
)))
1425 else if (NILP (minibuf
))
1427 if (!FRAME_MINIBUF_ONLY_P (c
))
1430 else if (EQ (minibuf
, Qvisible
))
1432 if (FRAME_VISIBLE_P (c
))
1435 else if (WINDOWP (minibuf
))
1437 if (EQ (FRAME_MINIBUF_WINDOW (c
), minibuf
)
1438 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)), candidate
)
1439 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
1440 FRAME_FOCUS_FRAME (c
)))
1443 else if (INTEGERP (minibuf
) && XINT (minibuf
) == 0)
1445 if (FRAME_VISIBLE_P (c
) || FRAME_ICONIFIED_P (c
))
1454 /* Return the next frame in the frame list after FRAME. */
1457 next_frame (Lisp_Object frame
, Lisp_Object minibuf
)
1459 Lisp_Object f
, tail
;
1463 FOR_EACH_FRAME (tail
, f
)
1467 f
= candidate_frame (f
, frame
, minibuf
);
1477 /* Return the previous frame in the frame list before FRAME. */
1480 prev_frame (Lisp_Object frame
, Lisp_Object minibuf
)
1482 Lisp_Object f
, tail
, prev
= Qnil
;
1484 FOR_EACH_FRAME (tail
, f
)
1486 if (EQ (frame
, f
) && !NILP (prev
))
1488 f
= candidate_frame (f
, frame
, minibuf
);
1493 /* We've scanned the entire list. */
1495 /* We went through the whole frame list without finding a single
1496 acceptable frame. Return the original frame. */
1499 /* There were no acceptable frames in the list before FRAME; otherwise,
1500 we would have returned directly from the loop. Since PREV is the last
1501 acceptable frame in the list, return it. */
1506 DEFUN ("next-frame", Fnext_frame
, Snext_frame
, 0, 2, 0,
1507 doc
: /* Return the next frame in the frame list after FRAME.
1508 It considers only frames on the same terminal as FRAME.
1509 By default, skip minibuffer-only frames.
1510 If omitted, FRAME defaults to the selected frame.
1511 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1512 If MINIFRAME is a window, include only its own frame
1513 and any frame now using that window as the minibuffer.
1514 If MINIFRAME is `visible', include all visible frames.
1515 If MINIFRAME is 0, include all visible and iconified frames.
1516 Otherwise, include all frames. */)
1517 (Lisp_Object frame
, Lisp_Object miniframe
)
1520 frame
= selected_frame
;
1521 CHECK_LIVE_FRAME (frame
);
1522 return next_frame (frame
, miniframe
);
1525 DEFUN ("previous-frame", Fprevious_frame
, Sprevious_frame
, 0, 2, 0,
1526 doc
: /* Return the previous frame in the frame list before FRAME.
1527 It considers only frames on the same terminal as FRAME.
1528 By default, skip minibuffer-only frames.
1529 If omitted, FRAME defaults to the selected frame.
1530 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1531 If MINIFRAME is a window, include only its own frame
1532 and any frame now using that window as the minibuffer.
1533 If MINIFRAME is `visible', include all visible frames.
1534 If MINIFRAME is 0, include all visible and iconified frames.
1535 Otherwise, include all frames. */)
1536 (Lisp_Object frame
, Lisp_Object miniframe
)
1539 frame
= selected_frame
;
1540 CHECK_LIVE_FRAME (frame
);
1541 return prev_frame (frame
, miniframe
);
1544 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame
,
1545 Slast_nonminibuf_frame
, 0, 0, 0,
1546 doc
: /* Return last non-minibuffer frame selected. */)
1549 Lisp_Object frame
= Qnil
;
1551 if (last_nonminibuf_frame
)
1552 XSETFRAME (frame
, last_nonminibuf_frame
);
1560 * Return true if there exists at least one visible or iconified frame
1561 * but F. Return false otherwise.
1563 * INVISIBLE true means we are called from make_frame_invisible where
1564 * such a frame must be visible or iconified. INVISIBLE nil means we
1565 * are called from delete_frame. In that case FORCE true means that the
1566 * visibility status of such a frame can be ignored.
1568 * If F is the terminal frame and we are using X, return true if at
1569 * least one X frame exists.
1572 other_frames (struct frame
*f
, bool invisible
, bool force
)
1574 Lisp_Object frames
, frame
, frame1
;
1576 Lisp_Object minibuffer_window
= FRAME_MINIBUF_WINDOW (f
);
1578 XSETFRAME (frame
, f
);
1579 if (WINDOWP (minibuffer_window
)
1580 && !EQ (frame
, WINDOW_FRAME (XWINDOW (minibuffer_window
))))
1581 minibuffer_window
= Qnil
;
1583 FOR_EACH_FRAME (frames
, frame1
)
1585 f1
= XFRAME (frame1
);
1588 /* Verify that we can still talk to the frame's X window, and
1589 note any recent change in visibility. */
1590 #ifdef HAVE_X_WINDOWS
1591 if (FRAME_WINDOW_P (f1
))
1594 if (NILP (Fframe_parameter (frame1
, Qtooltip
))
1595 /* Tooltips and child frames count neither for
1596 invisibility nor for deletions. */
1597 && !FRAME_PARENT_FRAME (f1
)
1598 /* Frames with a non-nil `delete-before' parameter don't
1599 count for deletions. */
1600 && (invisible
|| NILP (get_frame_param (f1
, Qdelete_before
)))
1601 /* For invisibility and normal deletions, at least one
1602 visible or iconified frame must remain (Bug#26682). */
1603 && (FRAME_VISIBLE_P (f1
) || FRAME_ICONIFIED_P (f1
)
1606 /* Allow deleting the terminal frame when at
1607 least one X frame exists. */
1608 || (FRAME_WINDOW_P (f1
) && !FRAME_WINDOW_P (f
))))))
1616 /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1617 window. Preferably use the selected frame's minibuffer window
1618 instead. If the selected frame doesn't have one, get some other
1619 frame's minibuffer window. SELECT non-zero means select the new
1620 minibuffer window. */
1622 check_minibuf_window (Lisp_Object frame
, int select
)
1624 struct frame
*f
= decode_live_frame (frame
);
1626 XSETFRAME (frame
, f
);
1628 if (WINDOWP (minibuf_window
) && EQ (f
->minibuffer_window
, minibuf_window
))
1630 Lisp_Object frames
, this, window
= make_number (0);
1632 if (!EQ (frame
, selected_frame
)
1633 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame
)))
1634 window
= FRAME_MINIBUF_WINDOW (XFRAME (selected_frame
));
1636 FOR_EACH_FRAME (frames
, this)
1638 if (!EQ (this, frame
) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1640 window
= FRAME_MINIBUF_WINDOW (XFRAME (this));
1645 /* Don't abort if no window was found (Bug#15247). */
1646 if (WINDOWP (window
))
1648 /* Use set_window_buffer instead of Fset_window_buffer (see
1649 discussion of bug#11984, bug#12025, bug#12026). */
1650 set_window_buffer (window
, XWINDOW (minibuf_window
)->contents
, 0, 0);
1651 minibuf_window
= window
;
1653 /* SELECT non-zero usually means that FRAME's minibuffer
1654 window was selected; select the new one. */
1656 Fselect_window (minibuf_window
, Qnil
);
1665 * Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1666 * unconditionally. x_connection_closed and delete_terminal use this.
1667 * Any other value of FORCE implements the semantics described for
1670 delete_frame (Lisp_Object frame
, Lisp_Object force
)
1672 struct frame
*f
= decode_any_frame (frame
);
1675 Lisp_Object frames
, frame1
;
1676 int minibuffer_selected
, is_tooltip_frame
;
1677 bool nochild
= !FRAME_PARENT_FRAME (f
);
1679 if (!FRAME_LIVE_P (f
))
1681 else if (!EQ (force
, Qnoelisp
) && !other_frames (f
, false, !NILP (force
)))
1684 error ("Attempt to delete the sole visible or iconified frame");
1686 error ("Attempt to delete the only frame");
1689 XSETFRAME (frame
, f
);
1691 /* Softly delete all frames with this frame as their parent frame or
1692 as their `delete-before' frame parameter value. */
1693 FOR_EACH_FRAME (frames
, frame1
)
1694 if (FRAME_PARENT_FRAME (XFRAME (frame1
)) == f
1695 /* Process `delete-before' parameter iff FRAME is not a child
1696 frame. This avoids that we enter an infinite chain of mixed
1699 && EQ (get_frame_param (XFRAME (frame1
), Qdelete_before
), frame
)))
1700 delete_frame (frame1
, Qnil
);
1702 /* Does this frame have a minibuffer, and is it the surrogate
1703 minibuffer for any other frame? */
1704 if (FRAME_HAS_MINIBUF_P (f
))
1706 FOR_EACH_FRAME (frames
, frame1
)
1710 if (EQ (frame1
, frame
))
1713 fminiw
= FRAME_MINIBUF_WINDOW (XFRAME (frame1
));
1715 if (WINDOWP (fminiw
) && EQ (frame
, WINDOW_FRAME (XWINDOW (fminiw
))))
1717 /* If we MUST delete this frame, delete the other first.
1718 But do this only if FORCE equals `noelisp'. */
1719 if (EQ (force
, Qnoelisp
))
1720 delete_frame (frame1
, Qnoelisp
);
1722 error ("Attempt to delete a surrogate minibuffer frame");
1727 is_tooltip_frame
= !NILP (Fframe_parameter (frame
, Qtooltip
));
1729 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1730 frame is a tooltip. FORCE is set to `noelisp' when handling
1731 a disconnect from the terminal, so we don't dare call Lisp
1733 if (NILP (Vrun_hooks
) || is_tooltip_frame
)
1735 else if (EQ (force
, Qnoelisp
))
1737 = Fcons (list3 (Qrun_hook_with_args
, Qdelete_frame_functions
, frame
),
1741 #ifdef HAVE_X_WINDOWS
1742 /* Also, save clipboard to the clipboard manager. */
1743 x_clipboard_manager_save_frame (frame
);
1746 safe_call2 (Qrun_hook_with_args
, Qdelete_frame_functions
, frame
);
1749 /* delete_frame_functions may have deleted any frame, including this
1751 if (!FRAME_LIVE_P (f
))
1753 else if (!EQ (force
, Qnoelisp
) && !other_frames (f
, false, !NILP (force
)))
1756 error ("Attempt to delete the sole visible or iconified frame");
1758 error ("Attempt to delete the only frame");
1761 /* At this point, we are committed to deleting the frame.
1762 There is no more chance for errors to prevent it. */
1763 minibuffer_selected
= EQ (minibuf_window
, selected_window
);
1764 sf
= SELECTED_FRAME ();
1765 /* Don't let the frame remain selected. */
1770 /* Look for another visible frame on the same terminal.
1771 Do not call next_frame here because it may loop forever.
1772 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1773 FOR_EACH_FRAME (tail
, frame1
)
1774 if (!EQ (frame
, frame1
)
1775 && (FRAME_TERMINAL (XFRAME (frame
))
1776 == FRAME_TERMINAL (XFRAME (frame1
)))
1777 && FRAME_VISIBLE_P (XFRAME (frame1
)))
1780 /* If there is none, find *some* other frame. */
1781 if (NILP (frame1
) || EQ (frame1
, frame
))
1783 FOR_EACH_FRAME (tail
, frame1
)
1785 if (! EQ (frame
, frame1
) && FRAME_LIVE_P (XFRAME (frame1
)))
1787 /* Do not change a text terminal's top-frame. */
1788 struct frame
*f1
= XFRAME (frame1
);
1789 if (FRAME_TERMCAP_P (f1
) || FRAME_MSDOS_P (f1
))
1791 Lisp_Object top_frame
= FRAME_TTY (f1
)->top_frame
;
1792 if (!EQ (top_frame
, frame
))
1799 #ifdef NS_IMPL_COCOA
1801 /* Under NS, there is no system mechanism for choosing a new
1802 window to get focus -- it is left to application code.
1803 So the portion of THIS application interfacing with NS
1804 needs to know about it. We call Fraise_frame, but the
1805 purpose is really to transfer focus. */
1806 Fraise_frame (frame1
);
1809 do_switch_frame (frame1
, 0, 1, Qnil
);
1810 sf
= SELECTED_FRAME ();
1813 /* Don't allow minibuf_window to remain on a deleted frame. */
1814 check_minibuf_window (frame
, minibuffer_selected
);
1816 /* Don't let echo_area_window to remain on a deleted frame. */
1817 if (EQ (f
->minibuffer_window
, echo_area_window
))
1818 echo_area_window
= sf
->minibuffer_window
;
1820 /* Clear any X selections for this frame. */
1821 #ifdef HAVE_X_WINDOWS
1823 x_clear_frame_selections (f
);
1827 This function must be called before the window tree of the
1828 frame is deleted because windows contain dynamically allocated
1832 #ifdef HAVE_WINDOW_SYSTEM
1833 /* Give chance to each font driver to free a frame specific data. */
1834 font_update_drivers (f
, Qnil
);
1837 /* Mark all the windows that used to be on FRAME as deleted, and then
1838 remove the reference to them. */
1839 delete_all_child_windows (f
->root_window
);
1840 fset_root_window (f
, Qnil
);
1842 Vframe_list
= Fdelq (frame
, Vframe_list
);
1843 SET_FRAME_VISIBLE (f
, 0);
1845 /* Allow the vector of menu bar contents to be freed in the next
1846 garbage collection. The frame object itself may not be garbage
1847 collected until much later, because recent_keys and other data
1848 structures can still refer to it. */
1849 fset_menu_bar_vector (f
, Qnil
);
1851 /* If FRAME's buffer lists contains killed
1852 buffers, this helps GC to reclaim them. */
1853 fset_buffer_list (f
, Qnil
);
1854 fset_buried_buffer_list (f
, Qnil
);
1856 free_font_driver_list (f
);
1857 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1860 xfree (f
->decode_mode_spec_buffer
);
1861 xfree (FRAME_INSERT_COST (f
));
1862 xfree (FRAME_DELETEN_COST (f
));
1863 xfree (FRAME_INSERTN_COST (f
));
1864 xfree (FRAME_DELETE_COST (f
));
1866 /* Since some events are handled at the interrupt level, we may get
1867 an event for f at any time; if we zero out the frame's terminal
1868 now, then we may trip up the event-handling code. Instead, we'll
1869 promise that the terminal of the frame must be valid until we
1870 have called the window-system-dependent frame destruction
1873 struct terminal
*terminal
;
1875 if (FRAME_TERMINAL (f
)->delete_frame_hook
)
1876 (*FRAME_TERMINAL (f
)->delete_frame_hook
) (f
);
1877 terminal
= FRAME_TERMINAL (f
);
1878 f
->output_data
.nothing
= 0;
1879 f
->terminal
= 0; /* Now the frame is dead. */
1882 /* If needed, delete the terminal that this frame was on.
1883 (This must be done after the frame is killed.) */
1884 terminal
->reference_count
--;
1886 /* FIXME: Deleting the terminal crashes emacs because of a GTK
1888 http://lists.gnu.org/archive/html/emacs-devel/2011-10/msg00363.html */
1889 if (terminal
->reference_count
== 0 && terminal
->type
== output_x_window
)
1890 terminal
->reference_count
= 1;
1891 #endif /* USE_GTK */
1892 if (terminal
->reference_count
== 0)
1895 XSETTERMINAL (tmp
, terminal
);
1898 Fdelete_terminal (tmp
, NILP (force
) ? Qt
: force
);
1901 kb
= terminal
->kboard
;
1904 /* If we've deleted the last_nonminibuf_frame, then try to find
1906 if (f
== last_nonminibuf_frame
)
1908 last_nonminibuf_frame
= 0;
1910 FOR_EACH_FRAME (frames
, frame1
)
1912 struct frame
*f1
= XFRAME (frame1
);
1914 if (!FRAME_MINIBUF_ONLY_P (f1
))
1916 last_nonminibuf_frame
= f1
;
1922 /* If there's no other frame on the same kboard, get out of
1923 single-kboard state if we're in it for this kboard. */
1926 /* Some frame we found on the same kboard, or nil if there are none. */
1927 Lisp_Object frame_on_same_kboard
= Qnil
;
1929 FOR_EACH_FRAME (frames
, frame1
)
1930 if (kb
== FRAME_KBOARD (XFRAME (frame1
)))
1931 frame_on_same_kboard
= frame1
;
1933 if (NILP (frame_on_same_kboard
))
1934 not_single_kboard_state (kb
);
1938 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1939 find another one. Prefer minibuffer-only frames, but also notice
1940 frames with other windows. */
1941 if (kb
!= NULL
&& EQ (frame
, KVAR (kb
, Vdefault_minibuffer_frame
)))
1943 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1944 Lisp_Object frame_with_minibuf
= Qnil
;
1945 /* Some frame we found on the same kboard, or nil if there are none. */
1946 Lisp_Object frame_on_same_kboard
= Qnil
;
1948 FOR_EACH_FRAME (frames
, frame1
)
1950 struct frame
*f1
= XFRAME (frame1
);
1952 /* Consider only frames on the same kboard
1953 and only those with minibuffers. */
1954 if (kb
== FRAME_KBOARD (f1
)
1955 && FRAME_HAS_MINIBUF_P (f1
))
1957 frame_with_minibuf
= frame1
;
1958 if (FRAME_MINIBUF_ONLY_P (f1
))
1962 if (kb
== FRAME_KBOARD (f1
))
1963 frame_on_same_kboard
= frame1
;
1966 if (!NILP (frame_on_same_kboard
))
1968 /* We know that there must be some frame with a minibuffer out
1969 there. If this were not true, all of the frames present
1970 would have to be minibufferless, which implies that at some
1971 point their minibuffer frames must have been deleted, but
1972 that is prohibited at the top; you can't delete surrogate
1973 minibuffer frames. */
1974 if (NILP (frame_with_minibuf
))
1977 kset_default_minibuffer_frame (kb
, frame_with_minibuf
);
1980 /* No frames left on this kboard--say no minibuffer either. */
1981 kset_default_minibuffer_frame (kb
, Qnil
);
1984 /* Cause frame titles to update--necessary if we now have just one frame. */
1985 if (!is_tooltip_frame
)
1986 update_mode_lines
= 15;
1991 DEFUN ("delete-frame", Fdelete_frame
, Sdelete_frame
, 0, 2, "",
1992 doc
: /* Delete FRAME, permanently eliminating it from use.
1993 FRAME must be a live frame and defaults to the selected one.
1995 A frame may not be deleted if its minibuffer serves as surrogate
1996 minibuffer for another frame. Normally, you may not delete a frame if
1997 all other frames are invisible, but if the second optional argument
1998 FORCE is non-nil, you may do so.
2000 This function runs `delete-frame-functions' before actually
2001 deleting the frame, unless the frame is a tooltip.
2002 The functions are run with one argument, the frame to be deleted. */)
2003 (Lisp_Object frame
, Lisp_Object force
)
2005 return delete_frame (frame
, !NILP (force
) ? Qt
: Qnil
);
2009 /* Return mouse position in character cell units. */
2011 DEFUN ("mouse-position", Fmouse_position
, Smouse_position
, 0, 0, 0,
2012 doc
: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
2013 The position is given in canonical character cells, where (0, 0) is the
2014 upper-left corner of the frame, X is the horizontal offset, and Y is the
2015 vertical offset, measured in units of the frame's default character size.
2016 If Emacs is running on a mouseless terminal or hasn't been programmed
2017 to read the mouse position, it returns the selected frame for FRAME
2018 and nil for X and Y.
2019 If `mouse-position-function' is non-nil, `mouse-position' calls it,
2020 passing the normal return value to that function as an argument,
2021 and returns whatever that function returns. */)
2025 Lisp_Object lispy_dummy
;
2026 Lisp_Object x
, y
, retval
;
2028 f
= SELECTED_FRAME ();
2031 /* It's okay for the hook to refrain from storing anything. */
2032 if (FRAME_TERMINAL (f
)->mouse_position_hook
)
2034 enum scroll_bar_part party_dummy
;
2036 (*FRAME_TERMINAL (f
)->mouse_position_hook
) (&f
, -1,
2037 &lispy_dummy
, &party_dummy
,
2046 pixel_to_glyph_coords (f
, col
, row
, &col
, &row
, NULL
, 1);
2050 XSETFRAME (lispy_dummy
, f
);
2051 retval
= Fcons (lispy_dummy
, Fcons (x
, y
));
2052 if (!NILP (Vmouse_position_function
))
2053 retval
= call1 (Vmouse_position_function
, retval
);
2057 DEFUN ("mouse-pixel-position", Fmouse_pixel_position
,
2058 Smouse_pixel_position
, 0, 0, 0,
2059 doc
: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
2060 The position is given in pixel units, where (0, 0) is the
2061 upper-left corner of the frame, X is the horizontal offset, and Y is
2062 the vertical offset.
2063 If Emacs is running on a mouseless terminal or hasn't been programmed
2064 to read the mouse position, it returns the selected frame for FRAME
2065 and nil for X and Y. */)
2069 Lisp_Object lispy_dummy
;
2070 Lisp_Object x
, y
, retval
;
2072 f
= SELECTED_FRAME ();
2075 /* It's okay for the hook to refrain from storing anything. */
2076 if (FRAME_TERMINAL (f
)->mouse_position_hook
)
2078 enum scroll_bar_part party_dummy
;
2080 (*FRAME_TERMINAL (f
)->mouse_position_hook
) (&f
, -1,
2081 &lispy_dummy
, &party_dummy
,
2086 XSETFRAME (lispy_dummy
, f
);
2087 retval
= Fcons (lispy_dummy
, Fcons (x
, y
));
2088 if (!NILP (Vmouse_position_function
))
2089 retval
= call1 (Vmouse_position_function
, retval
);
2093 #ifdef HAVE_WINDOW_SYSTEM
2095 /* On frame F, convert character coordinates X and Y to pixel
2096 coordinates *PIX_X and *PIX_Y. */
2099 frame_char_to_pixel_position (struct frame
*f
, int x
, int y
,
2100 int *pix_x
, int *pix_y
)
2102 *pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
2103 *pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
2107 if (*pix_x
> FRAME_PIXEL_WIDTH (f
))
2108 *pix_x
= FRAME_PIXEL_WIDTH (f
);
2112 if (*pix_y
> FRAME_PIXEL_HEIGHT (f
))
2113 *pix_y
= FRAME_PIXEL_HEIGHT (f
);
2116 /* On frame F, reposition mouse pointer to character coordinates X and Y. */
2119 frame_set_mouse_position (struct frame
*f
, int x
, int y
)
2123 frame_char_to_pixel_position (f
, x
, y
, &pix_x
, &pix_y
);
2124 frame_set_mouse_pixel_position (f
, pix_x
, pix_y
);
2127 #endif /* HAVE_WINDOW_SYSTEM */
2129 DEFUN ("set-mouse-position", Fset_mouse_position
, Sset_mouse_position
, 3, 3, 0,
2130 doc
: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
2131 Coordinates are relative to the frame, not a window,
2132 so the coordinates of the top left character in the frame
2133 may be nonzero due to left-hand scroll bars or the menu bar.
2135 The position is given in canonical character cells, where (0, 0) is
2136 the upper-left corner of the frame, X is the horizontal offset, and
2137 Y is the vertical offset, measured in units of the frame's default
2140 This function is a no-op for an X frame that is not visible.
2141 If you have just created a frame, you must wait for it to become visible
2142 before calling this function on it, like this.
2143 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
2144 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
2146 CHECK_LIVE_FRAME (frame
);
2147 CHECK_TYPE_RANGED_INTEGER (int, x
);
2148 CHECK_TYPE_RANGED_INTEGER (int, y
);
2150 /* I think this should be done with a hook. */
2151 #ifdef HAVE_WINDOW_SYSTEM
2152 if (FRAME_WINDOW_P (XFRAME (frame
)))
2153 /* Warping the mouse will cause enternotify and focus events. */
2154 frame_set_mouse_position (XFRAME (frame
), XINT (x
), XINT (y
));
2157 if (FRAME_MSDOS_P (XFRAME (frame
)))
2159 Fselect_frame (frame
, Qnil
);
2160 mouse_moveto (XINT (x
), XINT (y
));
2165 Fselect_frame (frame
, Qnil
);
2166 term_mouse_moveto (XINT (x
), XINT (y
));
2175 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position
,
2176 Sset_mouse_pixel_position
, 3, 3, 0,
2177 doc
: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
2178 The position is given in pixels, where (0, 0) is the upper-left corner
2179 of the frame, X is the horizontal offset, and Y is the vertical offset.
2181 Note, this is a no-op for an X frame that is not visible.
2182 If you have just created a frame, you must wait for it to become visible
2183 before calling this function on it, like this.
2184 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
2185 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
2187 CHECK_LIVE_FRAME (frame
);
2188 CHECK_TYPE_RANGED_INTEGER (int, x
);
2189 CHECK_TYPE_RANGED_INTEGER (int, y
);
2191 /* I think this should be done with a hook. */
2192 #ifdef HAVE_WINDOW_SYSTEM
2193 if (FRAME_WINDOW_P (XFRAME (frame
)))
2194 /* Warping the mouse will cause enternotify and focus events. */
2195 frame_set_mouse_pixel_position (XFRAME (frame
), XINT (x
), XINT (y
));
2198 if (FRAME_MSDOS_P (XFRAME (frame
)))
2200 Fselect_frame (frame
, Qnil
);
2201 mouse_moveto (XINT (x
), XINT (y
));
2206 Fselect_frame (frame
, Qnil
);
2207 term_mouse_moveto (XINT (x
), XINT (y
));
2216 static void make_frame_visible_1 (Lisp_Object
);
2218 DEFUN ("make-frame-visible", Fmake_frame_visible
, Smake_frame_visible
,
2220 doc
: /* Make the frame FRAME visible (assuming it is an X window).
2221 If omitted, FRAME defaults to the currently selected frame. */)
2224 struct frame
*f
= decode_live_frame (frame
);
2226 /* I think this should be done with a hook. */
2227 #ifdef HAVE_WINDOW_SYSTEM
2228 if (FRAME_WINDOW_P (f
))
2229 x_make_frame_visible (f
);
2232 make_frame_visible_1 (f
->root_window
);
2234 /* Make menu bar update for the Buffers and Frames menus. */
2235 /* windows_or_buffers_changed = 15; FIXME: Why? */
2237 XSETFRAME (frame
, f
);
2241 /* Update the display_time slot of the buffers shown in WINDOW
2242 and all its descendants. */
2245 make_frame_visible_1 (Lisp_Object window
)
2249 for (; !NILP (window
); window
= w
->next
)
2251 w
= XWINDOW (window
);
2252 if (WINDOWP (w
->contents
))
2253 make_frame_visible_1 (w
->contents
);
2255 bset_display_time (XBUFFER (w
->contents
), Fcurrent_time ());
2259 DEFUN ("make-frame-invisible", Fmake_frame_invisible
, Smake_frame_invisible
,
2261 doc
: /* Make the frame FRAME invisible.
2262 If omitted, FRAME defaults to the currently selected frame.
2263 On graphical displays, invisible frames are not updated and are
2264 usually not displayed at all, even in a window system's \"taskbar\".
2266 Normally you may not make FRAME invisible if all other frames are invisible,
2267 but if the second optional argument FORCE is non-nil, you may do so.
2269 This function has no effect on text terminal frames. Such frames are
2270 always considered visible, whether or not they are currently being
2271 displayed in the terminal. */)
2272 (Lisp_Object frame
, Lisp_Object force
)
2274 struct frame
*f
= decode_live_frame (frame
);
2276 if (NILP (force
) && !other_frames (f
, true, false))
2277 error ("Attempt to make invisible the sole visible or iconified frame");
2279 /* Don't allow minibuf_window to remain on an invisible frame. */
2280 check_minibuf_window (frame
, EQ (minibuf_window
, selected_window
));
2282 /* I think this should be done with a hook. */
2283 #ifdef HAVE_WINDOW_SYSTEM
2284 if (FRAME_WINDOW_P (f
))
2285 x_make_frame_invisible (f
);
2288 /* Make menu bar update for the Buffers and Frames menus. */
2289 windows_or_buffers_changed
= 16;
2294 DEFUN ("iconify-frame", Ficonify_frame
, Siconify_frame
,
2296 doc
: /* Make the frame FRAME into an icon.
2297 If omitted, FRAME defaults to the currently selected frame. */)
2300 struct frame
*f
= decode_live_frame (frame
);
2302 /* Don't allow minibuf_window to remain on an iconified frame. */
2303 check_minibuf_window (frame
, EQ (minibuf_window
, selected_window
));
2305 /* I think this should be done with a hook. */
2306 if (FRAME_WINDOW_P (f
))
2308 #ifdef HAVE_WINDOW_SYSTEM
2309 x_iconify_frame (f
);
2316 DEFUN ("frame-visible-p", Fframe_visible_p
, Sframe_visible_p
,
2318 doc
: /* Return t if FRAME is \"visible\" (actually in use for display).
2319 Return the symbol `icon' if FRAME is iconified or \"minimized\".
2320 Return nil if FRAME was made invisible, via `make-frame-invisible'.
2321 On graphical displays, invisible frames are not updated and are
2322 usually not displayed at all, even in a window system's \"taskbar\".
2324 If FRAME is a text terminal frame, this always returns t.
2325 Such frames are always considered visible, whether or not they are
2326 currently being displayed on the terminal. */)
2329 CHECK_LIVE_FRAME (frame
);
2331 if (FRAME_VISIBLE_P (XFRAME (frame
)))
2333 if (FRAME_ICONIFIED_P (XFRAME (frame
)))
2338 DEFUN ("visible-frame-list", Fvisible_frame_list
, Svisible_frame_list
,
2340 doc
: /* Return a list of all frames now \"visible\" (being updated). */)
2343 Lisp_Object tail
, frame
, value
= Qnil
;
2345 FOR_EACH_FRAME (tail
, frame
)
2346 if (FRAME_VISIBLE_P (XFRAME (frame
)))
2347 value
= Fcons (frame
, value
);
2353 DEFUN ("raise-frame", Fraise_frame
, Sraise_frame
, 0, 1, "",
2354 doc
: /* Bring FRAME to the front, so it occludes any frames it overlaps.
2355 If FRAME is invisible or iconified, make it visible.
2356 If you don't specify a frame, the selected frame is used.
2357 If Emacs is displaying on an ordinary terminal or some other device which
2358 doesn't support multiple overlapping frames, this function selects FRAME. */)
2361 struct frame
*f
= decode_live_frame (frame
);
2363 XSETFRAME (frame
, f
);
2365 if (FRAME_TERMCAP_P (f
))
2366 /* On a text terminal select FRAME. */
2367 Fselect_frame (frame
, Qnil
);
2369 /* Do like the documentation says. */
2370 Fmake_frame_visible (frame
);
2372 if (FRAME_TERMINAL (f
)->frame_raise_lower_hook
)
2373 (*FRAME_TERMINAL (f
)->frame_raise_lower_hook
) (f
, 1);
2378 /* Should we have a corresponding function called Flower_Power? */
2379 DEFUN ("lower-frame", Flower_frame
, Slower_frame
, 0, 1, "",
2380 doc
: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2381 If you don't specify a frame, the selected frame is used.
2382 If Emacs is displaying on an ordinary terminal or some other device which
2383 doesn't support multiple overlapping frames, this function does nothing. */)
2386 struct frame
*f
= decode_live_frame (frame
);
2388 if (FRAME_TERMINAL (f
)->frame_raise_lower_hook
)
2389 (*FRAME_TERMINAL (f
)->frame_raise_lower_hook
) (f
, 0);
2395 DEFUN ("redirect-frame-focus", Fredirect_frame_focus
, Sredirect_frame_focus
,
2397 doc
: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2398 In other words, switch-frame events caused by events in FRAME will
2399 request a switch to FOCUS-FRAME, and `last-event-frame' will be
2400 FOCUS-FRAME after reading an event typed at FRAME.
2402 If FOCUS-FRAME is nil, any existing redirection is canceled, and the
2403 frame again receives its own keystrokes.
2405 Focus redirection is useful for temporarily redirecting keystrokes to
2406 a surrogate minibuffer frame when a frame doesn't have its own
2409 A frame's focus redirection can be changed by `select-frame'. If frame
2410 FOO is selected, and then a different frame BAR is selected, any
2411 frames redirecting their focus to FOO are shifted to redirect their
2412 focus to BAR. This allows focus redirection to work properly when the
2413 user switches from one frame to another using `select-window'.
2415 This means that a frame whose focus is redirected to itself is treated
2416 differently from a frame whose focus is redirected to nil; the former
2417 is affected by `select-frame', while the latter is not.
2419 The redirection lasts until `redirect-frame-focus' is called to change it. */)
2420 (Lisp_Object frame
, Lisp_Object focus_frame
)
2422 /* Note that we don't check for a live frame here. It's reasonable
2423 to redirect the focus of a frame you're about to delete, if you
2424 know what other frame should receive those keystrokes. */
2425 struct frame
*f
= decode_any_frame (frame
);
2427 if (! NILP (focus_frame
))
2428 CHECK_LIVE_FRAME (focus_frame
);
2430 fset_focus_frame (f
, focus_frame
);
2432 if (FRAME_TERMINAL (f
)->frame_rehighlight_hook
)
2433 (*FRAME_TERMINAL (f
)->frame_rehighlight_hook
) (f
);
2439 DEFUN ("frame-focus", Fframe_focus
, Sframe_focus
, 0, 1, 0,
2440 doc
: /* Return the frame to which FRAME's keystrokes are currently being sent.
2441 If FRAME is omitted or nil, the selected frame is used.
2442 Return nil if FRAME's focus is not redirected.
2443 See `redirect-frame-focus'. */)
2446 return FRAME_FOCUS_FRAME (decode_live_frame (frame
));
2449 DEFUN ("x-focus-frame", Fx_focus_frame
, Sx_focus_frame
, 1, 2, 0,
2450 doc
: /* Set the input focus to FRAME.
2451 FRAME nil means use the selected frame. Optional argument NOACTIVATE
2452 means do not activate FRAME.
2454 If there is no window system support, this function does nothing. */)
2455 (Lisp_Object frame
, Lisp_Object noactivate
)
2457 #ifdef HAVE_WINDOW_SYSTEM
2458 x_focus_frame (decode_window_system_frame (frame
), !NILP (noactivate
));
2463 DEFUN ("frame-after-make-frame",
2464 Fframe_after_make_frame
,
2465 Sframe_after_make_frame
, 2, 2, 0,
2466 doc
: /* Mark FRAME as made.
2467 FRAME nil means use the selected frame. Second argument MADE non-nil
2468 means functions on `window-configuration-change-hook' are called
2469 whenever the window configuration of FRAME changes. MADE nil means
2470 these functions are not called.
2472 This function is currently called by `make-frame' only and should be
2473 otherwise used with utter care to avoid that running functions on
2474 `window-configuration-change-hook' is impeded forever. */)
2475 (Lisp_Object frame
, Lisp_Object made
)
2477 struct frame
*f
= decode_live_frame (frame
);
2478 f
->after_make_frame
= !NILP (made
);
2479 f
->inhibit_horizontal_resize
= false;
2480 f
->inhibit_vertical_resize
= false;
2485 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2488 frames_discard_buffer (Lisp_Object buffer
)
2490 Lisp_Object frame
, tail
;
2492 FOR_EACH_FRAME (tail
, frame
)
2495 (XFRAME (frame
), Fdelq (buffer
, XFRAME (frame
)->buffer_list
));
2496 fset_buried_buffer_list
2497 (XFRAME (frame
), Fdelq (buffer
, XFRAME (frame
)->buried_buffer_list
));
2501 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2502 If the alist already has an element for PROP, we change it. */
2505 store_in_alist (Lisp_Object
*alistptr
, Lisp_Object prop
, Lisp_Object val
)
2507 register Lisp_Object tem
;
2509 tem
= Fassq (prop
, *alistptr
);
2511 *alistptr
= Fcons (Fcons (prop
, val
), *alistptr
);
2517 frame_name_fnn_p (char *str
, ptrdiff_t len
)
2519 if (len
> 1 && str
[0] == 'F' && '0' <= str
[1] && str
[1] <= '9')
2522 while ('0' <= *p
&& *p
<= '9')
2530 /* Set the name of the terminal frame. Also used by MSDOS frames.
2531 Modeled after x_set_name which is used for WINDOW frames. */
2534 set_term_frame_name (struct frame
*f
, Lisp_Object name
)
2536 f
->explicit_name
= ! NILP (name
);
2538 /* If NAME is nil, set the name to F<num>. */
2541 char namebuf
[sizeof "F" + INT_STRLEN_BOUND (printmax_t
)];
2543 /* Check for no change needed in this very common case
2544 before we do any consing. */
2545 if (frame_name_fnn_p (SSDATA (f
->name
), SBYTES (f
->name
)))
2548 name
= make_formatted_string (namebuf
, "F%"pMd
, ++tty_frame_count
);
2552 CHECK_STRING (name
);
2554 /* Don't change the name if it's already NAME. */
2555 if (! NILP (Fstring_equal (name
, f
->name
)))
2558 /* Don't allow the user to set the frame name to F<num>, so it
2559 doesn't clash with the names we generate for terminal frames. */
2560 if (frame_name_fnn_p (SSDATA (name
), SBYTES (name
)))
2561 error ("Frame names of the form F<num> are usurped by Emacs");
2564 fset_name (f
, name
);
2565 update_mode_lines
= 16;
2569 store_frame_param (struct frame
*f
, Lisp_Object prop
, Lisp_Object val
)
2571 register Lisp_Object old_alist_elt
;
2573 if (EQ (prop
, Qminibuffer
))
2577 if (!MINI_WINDOW_P (XWINDOW (val
)))
2578 error ("The `minibuffer' parameter does not specify a valid minibuffer window");
2579 else if (FRAME_MINIBUF_ONLY_P (f
))
2581 if (EQ (val
, FRAME_MINIBUF_WINDOW (f
)))
2584 error ("Can't change the minibuffer window of a minibuffer-only frame");
2586 else if (FRAME_HAS_MINIBUF_P (f
))
2588 if (EQ (val
, FRAME_MINIBUF_WINDOW (f
)))
2591 error ("Can't change the minibuffer window of a frame with its own minibuffer");
2594 /* Store the chosen minibuffer window. */
2595 fset_minibuffer_window (f
, val
);
2599 Lisp_Object old_val
= Fcdr (Fassq (Qminibuffer
, f
->param_alist
));
2601 if (!NILP (old_val
))
2603 if (WINDOWP (old_val
) && NILP (val
))
2604 /* Don't change the value for a minibuffer-less frame if
2605 only nil was specified as new value. */
2607 else if (!EQ (old_val
, val
))
2608 error ("Can't change the `minibuffer' parameter of this frame");
2613 /* Check each parent-frame and delete-before parameter for a
2614 circular dependency. Do not check between parameters, so you can
2615 still create circular dependencies with different properties, for
2616 example a chain of frames F1->F2->...Fn such that F1 is an ancestor
2617 frame of Fn and thus cannot be deleted before Fn and a second chain
2618 Fn->Fn-1->...F1 such that Fn cannot be deleted before F1. */
2619 else if (EQ (prop
, Qparent_frame
) || EQ (prop
, Qdelete_before
))
2621 Lisp_Object oldval
= Fcdr (Fassq (prop
, f
->param_alist
));
2623 if (!EQ (oldval
, val
) && !NILP (val
))
2626 Lisp_Object frame1
= val
;
2628 if (!FRAMEP (frame1
) || !FRAME_LIVE_P (XFRAME (frame1
)))
2629 error ("Invalid `%s' frame parameter",
2630 SSDATA (SYMBOL_NAME (prop
)));
2632 XSETFRAME (frame
, f
);
2634 while (FRAMEP (frame1
) && FRAME_LIVE_P (XFRAME (frame1
)))
2635 if (EQ (frame1
, frame
))
2636 error ("Circular specification of `%s' frame parameter",
2637 SSDATA (SYMBOL_NAME (prop
)));
2639 frame1
= get_frame_param (XFRAME (frame1
), prop
);
2643 /* The buffer-list parameters are stored in a special place and not
2644 in the alist. All buffers must be live. */
2645 else if (EQ (prop
, Qbuffer_list
))
2647 Lisp_Object list
= Qnil
;
2648 for (; CONSP (val
); val
= XCDR (val
))
2649 if (!NILP (Fbuffer_live_p (XCAR (val
))))
2650 list
= Fcons (XCAR (val
), list
);
2651 fset_buffer_list (f
, Fnreverse (list
));
2654 else if (EQ (prop
, Qburied_buffer_list
))
2656 Lisp_Object list
= Qnil
;
2657 for (; CONSP (val
); val
= XCDR (val
))
2658 if (!NILP (Fbuffer_live_p (XCAR (val
))))
2659 list
= Fcons (XCAR (val
), list
);
2660 fset_buried_buffer_list (f
, Fnreverse (list
));
2664 /* The tty color needed to be set before the frame's parameter
2665 alist was updated with the new value. This is not true any more,
2666 but we still do this test early on. */
2667 if (FRAME_TERMCAP_P (f
) && EQ (prop
, Qtty_color_mode
)
2668 && f
== FRAME_TTY (f
)->previous_frame
)
2669 /* Force redisplay of this tty. */
2670 FRAME_TTY (f
)->previous_frame
= NULL
;
2672 /* Update the frame parameter alist. */
2673 old_alist_elt
= Fassq (prop
, f
->param_alist
);
2674 if (EQ (old_alist_elt
, Qnil
))
2675 fset_param_alist (f
, Fcons (Fcons (prop
, val
), f
->param_alist
));
2677 Fsetcdr (old_alist_elt
, val
);
2679 /* Update some other special parameters in their special places
2680 in addition to the alist. */
2682 if (EQ (prop
, Qbuffer_predicate
))
2683 fset_buffer_predicate (f
, val
);
2685 if (! FRAME_WINDOW_P (f
))
2687 if (EQ (prop
, Qmenu_bar_lines
))
2688 set_menu_bar_lines (f
, val
, make_number (FRAME_MENU_BAR_LINES (f
)));
2689 else if (EQ (prop
, Qname
))
2690 set_term_frame_name (f
, val
);
2694 /* Return color matches UNSPEC on frame F or nil if UNSPEC
2695 is not an unspecified foreground or background color. */
2698 frame_unspecified_color (struct frame
*f
, Lisp_Object unspec
)
2700 return (!strncmp (SSDATA (unspec
), unspecified_bg
, SBYTES (unspec
))
2701 ? tty_color_name (f
, FRAME_BACKGROUND_PIXEL (f
))
2702 : (!strncmp (SSDATA (unspec
), unspecified_fg
, SBYTES (unspec
))
2703 ? tty_color_name (f
, FRAME_FOREGROUND_PIXEL (f
)) : Qnil
));
2706 DEFUN ("frame-parameters", Fframe_parameters
, Sframe_parameters
, 0, 1, 0,
2707 doc
: /* Return the parameters-alist of frame FRAME.
2708 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2709 The meaningful PARMs depend on the kind of frame.
2710 If FRAME is omitted or nil, return information on the currently selected frame. */)
2714 struct frame
*f
= decode_any_frame (frame
);
2717 if (!FRAME_LIVE_P (f
))
2720 alist
= Fcopy_alist (f
->param_alist
);
2722 if (!FRAME_WINDOW_P (f
))
2726 /* If the frame's parameter alist says the colors are
2727 unspecified and reversed, take the frame's background pixel
2728 for foreground and vice versa. */
2729 elt
= Fassq (Qforeground_color
, alist
);
2730 if (CONSP (elt
) && STRINGP (XCDR (elt
)))
2732 elt
= frame_unspecified_color (f
, XCDR (elt
));
2734 store_in_alist (&alist
, Qforeground_color
, elt
);
2737 store_in_alist (&alist
, Qforeground_color
,
2738 tty_color_name (f
, FRAME_FOREGROUND_PIXEL (f
)));
2739 elt
= Fassq (Qbackground_color
, alist
);
2740 if (CONSP (elt
) && STRINGP (XCDR (elt
)))
2742 elt
= frame_unspecified_color (f
, XCDR (elt
));
2744 store_in_alist (&alist
, Qbackground_color
, elt
);
2747 store_in_alist (&alist
, Qbackground_color
,
2748 tty_color_name (f
, FRAME_BACKGROUND_PIXEL (f
)));
2749 store_in_alist (&alist
, Qfont
,
2750 build_string (FRAME_MSDOS_P (f
)
2752 : FRAME_W32_P (f
) ? "w32term"
2755 store_in_alist (&alist
, Qname
, f
->name
);
2756 height
= (f
->new_height
2758 ? (f
->new_height
/ FRAME_LINE_HEIGHT (f
))
2761 store_in_alist (&alist
, Qheight
, make_number (height
));
2762 width
= (f
->new_width
2764 ? (f
->new_width
/ FRAME_COLUMN_WIDTH (f
))
2767 store_in_alist (&alist
, Qwidth
, make_number (width
));
2768 store_in_alist (&alist
, Qmodeline
, (FRAME_WANTS_MODELINE_P (f
) ? Qt
: Qnil
));
2769 store_in_alist (&alist
, Qunsplittable
, (FRAME_NO_SPLIT_P (f
) ? Qt
: Qnil
));
2770 store_in_alist (&alist
, Qbuffer_list
, f
->buffer_list
);
2771 store_in_alist (&alist
, Qburied_buffer_list
, f
->buried_buffer_list
);
2773 /* I think this should be done with a hook. */
2774 #ifdef HAVE_WINDOW_SYSTEM
2775 if (FRAME_WINDOW_P (f
))
2776 x_report_frame_params (f
, &alist
);
2780 /* This ought to be correct in f->param_alist for an X frame. */
2782 XSETFASTINT (lines
, FRAME_MENU_BAR_LINES (f
));
2783 store_in_alist (&alist
, Qmenu_bar_lines
, lines
);
2790 DEFUN ("frame-parameter", Fframe_parameter
, Sframe_parameter
, 2, 2, 0,
2791 doc
: /* Return FRAME's value for parameter PARAMETER.
2792 If FRAME is nil, describe the currently selected frame. */)
2793 (Lisp_Object frame
, Lisp_Object parameter
)
2795 struct frame
*f
= decode_any_frame (frame
);
2796 Lisp_Object value
= Qnil
;
2798 CHECK_SYMBOL (parameter
);
2800 XSETFRAME (frame
, f
);
2802 if (FRAME_LIVE_P (f
))
2804 /* Avoid consing in frequent cases. */
2805 if (EQ (parameter
, Qname
))
2807 #ifdef HAVE_WINDOW_SYSTEM
2808 /* These are used by vertical motion commands. */
2809 else if (EQ (parameter
, Qvertical_scroll_bars
))
2810 value
= (f
->vertical_scroll_bar_type
== vertical_scroll_bar_none
2812 : (f
->vertical_scroll_bar_type
== vertical_scroll_bar_left
2814 else if (EQ (parameter
, Qhorizontal_scroll_bars
))
2815 value
= f
->horizontal_scroll_bars
? Qt
: Qnil
;
2816 else if (EQ (parameter
, Qline_spacing
) && f
->extra_line_spacing
== 0)
2817 /* If this is non-zero, we can't determine whether the user specified
2818 an integer or float value without looking through 'param_alist'. */
2819 value
= make_number (0);
2820 else if (EQ (parameter
, Qfont
) && FRAME_X_P (f
))
2821 value
= FRAME_FONT (f
)->props
[FONT_NAME_INDEX
];
2822 #endif /* HAVE_WINDOW_SYSTEM */
2823 #ifdef HAVE_X_WINDOWS
2824 else if (EQ (parameter
, Qdisplay
) && FRAME_X_P (f
))
2825 value
= XCAR (FRAME_DISPLAY_INFO (f
)->name_list_element
);
2826 #endif /* HAVE_X_WINDOWS */
2827 else if (EQ (parameter
, Qbackground_color
)
2828 || EQ (parameter
, Qforeground_color
))
2830 value
= Fassq (parameter
, f
->param_alist
);
2833 value
= XCDR (value
);
2834 /* Fframe_parameters puts the actual fg/bg color names,
2835 even if f->param_alist says otherwise. This is
2836 important when param_alist's notion of colors is
2837 "unspecified". We need to do the same here. */
2838 if (STRINGP (value
) && !FRAME_WINDOW_P (f
))
2840 Lisp_Object tem
= frame_unspecified_color (f
, value
);
2847 value
= Fcdr (Fassq (parameter
, Fframe_parameters (frame
)));
2849 else if (EQ (parameter
, Qdisplay_type
)
2850 || EQ (parameter
, Qbackground_mode
))
2851 value
= Fcdr (Fassq (parameter
, f
->param_alist
));
2853 /* FIXME: Avoid this code path at all (as well as code duplication)
2854 by sharing more code with Fframe_parameters. */
2855 value
= Fcdr (Fassq (parameter
, Fframe_parameters (frame
)));
2862 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters
,
2863 Smodify_frame_parameters
, 2, 2, 0,
2864 doc
: /* Modify FRAME according to new values of its parameters in ALIST.
2865 If FRAME is nil, it defaults to the selected frame.
2866 ALIST is an alist of parameters to change and their new values.
2867 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2868 Which PARMs are meaningful depends on the kind of frame.
2869 The meaningful parameters are acted upon, i.e. the frame is changed
2870 according to their new values, and are also stored in the frame's
2871 parameter list so that `frame-parameters' will return them.
2872 PARMs that are not meaningful are still stored in the frame's parameter
2873 list, but are otherwise ignored. */)
2874 (Lisp_Object frame
, Lisp_Object alist
)
2876 struct frame
*f
= decode_live_frame (frame
);
2877 Lisp_Object prop
, val
;
2879 /* I think this should be done with a hook. */
2880 #ifdef HAVE_WINDOW_SYSTEM
2881 if (FRAME_WINDOW_P (f
))
2882 x_set_frame_parameters (f
, alist
);
2886 if (FRAME_MSDOS_P (f
))
2887 IT_set_frame_parameters (f
, alist
);
2892 EMACS_INT length
= XFASTINT (Flength (alist
));
2895 Lisp_Object
*values
;
2897 SAFE_ALLOCA_LISP (parms
, 2 * length
);
2898 values
= parms
+ length
;
2900 /* Extract parm names and values into those vectors. */
2902 for (i
= 0; CONSP (alist
); alist
= XCDR (alist
))
2907 parms
[i
] = Fcar (elt
);
2908 values
[i
] = Fcdr (elt
);
2912 /* Now process them in reverse of specified order. */
2917 store_frame_param (f
, prop
, val
);
2919 if (EQ (prop
, Qforeground_color
)
2920 || EQ (prop
, Qbackground_color
))
2921 update_face_from_frame_parameter (f
, prop
, val
);
2929 DEFUN ("frame-char-height", Fframe_char_height
, Sframe_char_height
,
2931 doc
: /* Height in pixels of a line in the font in frame FRAME.
2932 If FRAME is omitted or nil, the selected frame is used.
2933 For a terminal frame, the value is always 1. */)
2936 #ifdef HAVE_WINDOW_SYSTEM
2937 struct frame
*f
= decode_any_frame (frame
);
2939 if (FRAME_WINDOW_P (f
))
2940 return make_number (FRAME_LINE_HEIGHT (f
));
2943 return make_number (1);
2947 DEFUN ("frame-char-width", Fframe_char_width
, Sframe_char_width
,
2949 doc
: /* Width in pixels of characters in the font in frame FRAME.
2950 If FRAME is omitted or nil, the selected frame is used.
2951 On a graphical screen, the width is the standard width of the default font.
2952 For a terminal screen, the value is always 1. */)
2955 #ifdef HAVE_WINDOW_SYSTEM
2956 struct frame
*f
= decode_any_frame (frame
);
2958 if (FRAME_WINDOW_P (f
))
2959 return make_number (FRAME_COLUMN_WIDTH (f
));
2962 return make_number (1);
2965 DEFUN ("frame-pixel-height", Fframe_pixel_height
,
2966 Sframe_pixel_height
, 0, 1, 0,
2967 doc
: /* Return a FRAME's height in pixels.
2968 If FRAME is omitted or nil, the selected frame is used. The exact value
2969 of the result depends on the window-system and toolkit in use:
2971 In the Gtk+ version of Emacs, it includes only any window (including
2972 the minibuffer or echo area), mode line, and header line. It does not
2973 include the tool bar or menu bar.
2975 With other graphical versions, it also includes the tool bar and the
2978 For a text terminal, it includes the menu bar. In this case, the
2979 result is really in characters rather than pixels (i.e., is identical
2980 to `frame-height'). */)
2983 struct frame
*f
= decode_any_frame (frame
);
2985 #ifdef HAVE_WINDOW_SYSTEM
2986 if (FRAME_WINDOW_P (f
))
2987 return make_number (FRAME_PIXEL_HEIGHT (f
));
2990 return make_number (FRAME_TOTAL_LINES (f
));
2993 DEFUN ("frame-pixel-width", Fframe_pixel_width
,
2994 Sframe_pixel_width
, 0, 1, 0,
2995 doc
: /* Return FRAME's width in pixels.
2996 For a terminal frame, the result really gives the width in characters.
2997 If FRAME is omitted or nil, the selected frame is used. */)
3000 struct frame
*f
= decode_any_frame (frame
);
3002 #ifdef HAVE_WINDOW_SYSTEM
3003 if (FRAME_WINDOW_P (f
))
3004 return make_number (FRAME_PIXEL_WIDTH (f
));
3007 return make_number (FRAME_TOTAL_COLS (f
));
3010 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width
,
3011 Stool_bar_pixel_width
, 0, 1, 0,
3012 doc
: /* Return width in pixels of FRAME's tool bar.
3013 The result is greater than zero only when the tool bar is on the left
3014 or right side of FRAME. If FRAME is omitted or nil, the selected frame
3018 #ifdef FRAME_TOOLBAR_WIDTH
3019 struct frame
*f
= decode_any_frame (frame
);
3021 if (FRAME_WINDOW_P (f
))
3022 return make_number (FRAME_TOOLBAR_WIDTH (f
));
3024 return make_number (0);
3027 DEFUN ("frame-text-cols", Fframe_text_cols
, Sframe_text_cols
, 0, 1, 0,
3028 doc
: /* Return width in columns of FRAME's text area. */)
3031 return make_number (FRAME_COLS (decode_any_frame (frame
)));
3034 DEFUN ("frame-text-lines", Fframe_text_lines
, Sframe_text_lines
, 0, 1, 0,
3035 doc
: /* Return height in lines of FRAME's text area. */)
3038 return make_number (FRAME_LINES (decode_any_frame (frame
)));
3041 DEFUN ("frame-total-cols", Fframe_total_cols
, Sframe_total_cols
, 0, 1, 0,
3042 doc
: /* Return number of total columns of FRAME. */)
3045 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame
)));
3048 DEFUN ("frame-total-lines", Fframe_total_lines
, Sframe_total_lines
, 0, 1, 0,
3049 doc
: /* Return number of total lines of FRAME. */)
3052 return make_number (FRAME_TOTAL_LINES (decode_any_frame (frame
)));
3055 DEFUN ("frame-text-width", Fframe_text_width
, Sframe_text_width
, 0, 1, 0,
3056 doc
: /* Return text area width of FRAME in pixels. */)
3059 return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame
)));
3062 DEFUN ("frame-text-height", Fframe_text_height
, Sframe_text_height
, 0, 1, 0,
3063 doc
: /* Return text area height of FRAME in pixels. */)
3066 return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame
)));
3069 DEFUN ("frame-scroll-bar-width", Fscroll_bar_width
, Sscroll_bar_width
, 0, 1, 0,
3070 doc
: /* Return scroll bar width of FRAME in pixels. */)
3073 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame
)));
3076 DEFUN ("frame-scroll-bar-height", Fscroll_bar_height
, Sscroll_bar_height
, 0, 1, 0,
3077 doc
: /* Return scroll bar height of FRAME in pixels. */)
3080 return make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (decode_any_frame (frame
)));
3083 DEFUN ("frame-fringe-width", Ffringe_width
, Sfringe_width
, 0, 1, 0,
3084 doc
: /* Return fringe width of FRAME in pixels. */)
3087 return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame
)));
3090 DEFUN ("frame-border-width", Fborder_width
, Sborder_width
, 0, 1, 0,
3091 doc
: /* Return border width of FRAME in pixels. */)
3094 return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame
)));
3097 DEFUN ("frame-right-divider-width", Fright_divider_width
, Sright_divider_width
, 0, 1, 0,
3098 doc
: /* Return width (in pixels) of vertical window dividers on FRAME. */)
3101 return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame
)));
3104 DEFUN ("frame-bottom-divider-width", Fbottom_divider_width
, Sbottom_divider_width
, 0, 1, 0,
3105 doc
: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
3108 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame
)));
3111 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 4, 0,
3112 doc
: /* Set text height of frame FRAME to HEIGHT lines.
3113 Optional third arg PRETEND non-nil means that redisplay should use
3114 HEIGHT lines but that the idea of the actual height of the frame should
3117 Optional fourth argument PIXELWISE non-nil means that FRAME should be
3118 HEIGHT pixels high. Note: When `frame-resize-pixelwise' is nil, some
3119 window managers may refuse to honor a HEIGHT that is not an integer
3120 multiple of the default frame font height. */)
3121 (Lisp_Object frame
, Lisp_Object height
, Lisp_Object pretend
, Lisp_Object pixelwise
)
3123 struct frame
*f
= decode_live_frame (frame
);
3126 CHECK_TYPE_RANGED_INTEGER (int, height
);
3128 pixel_height
= (!NILP (pixelwise
)
3130 : XINT (height
) * FRAME_LINE_HEIGHT (f
));
3131 adjust_frame_size (f
, -1, pixel_height
, 1, !NILP (pretend
), Qheight
);
3136 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 4, 0,
3137 doc
: /* Set text width of frame FRAME to WIDTH columns.
3138 Optional third arg PRETEND non-nil means that redisplay should use WIDTH
3139 columns but that the idea of the actual width of the frame should not
3142 Optional fourth argument PIXELWISE non-nil means that FRAME should be
3143 WIDTH pixels wide. Note: When `frame-resize-pixelwise' is nil, some
3144 window managers may refuse to honor a WIDTH that is not an integer
3145 multiple of the default frame font width. */)
3146 (Lisp_Object frame
, Lisp_Object width
, Lisp_Object pretend
, Lisp_Object pixelwise
)
3148 struct frame
*f
= decode_live_frame (frame
);
3151 CHECK_TYPE_RANGED_INTEGER (int, width
);
3153 pixel_width
= (!NILP (pixelwise
)
3155 : XINT (width
) * FRAME_COLUMN_WIDTH (f
));
3156 adjust_frame_size (f
, pixel_width
, -1, 1, !NILP (pretend
), Qwidth
);
3161 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 4, 0,
3162 doc
: /* Set text size of FRAME to WIDTH by HEIGHT, measured in characters.
3163 Optional argument PIXELWISE non-nil means to measure in pixels. Note:
3164 When `frame-resize-pixelwise' is nil, some window managers may refuse to
3165 honor a WIDTH that is not an integer multiple of the default frame font
3166 width or a HEIGHT that is not an integer multiple of the default frame
3168 (Lisp_Object frame
, Lisp_Object width
, Lisp_Object height
, Lisp_Object pixelwise
)
3170 struct frame
*f
= decode_live_frame (frame
);
3171 int pixel_width
, pixel_height
;
3173 CHECK_TYPE_RANGED_INTEGER (int, width
);
3174 CHECK_TYPE_RANGED_INTEGER (int, height
);
3176 pixel_width
= (!NILP (pixelwise
)
3178 : XINT (width
) * FRAME_COLUMN_WIDTH (f
));
3179 pixel_height
= (!NILP (pixelwise
)
3181 : XINT (height
) * FRAME_LINE_HEIGHT (f
));
3182 adjust_frame_size (f
, pixel_width
, pixel_height
, 1, 0, Qsize
);
3187 DEFUN ("frame-position", Fframe_position
,
3188 Sframe_position
, 0, 1, 0,
3189 doc
: /* Return top left corner of FRAME in pixels.
3190 FRAME must be a live frame and defaults to the selected one. The return
3191 value is a cons (x, y) of the coordinates of the top left corner of
3192 FRAME's outer frame, in pixels relative to an origin (0, 0) of FRAME's
3196 register struct frame
*f
= decode_live_frame (frame
);
3198 return Fcons (make_number (f
->left_pos
), make_number (f
->top_pos
));
3201 DEFUN ("set-frame-position", Fset_frame_position
,
3202 Sset_frame_position
, 3, 3, 0,
3203 doc
: /* Set position of FRAME to (X, Y).
3204 FRAME must be a live frame and defaults to the selected one. X and Y,
3205 if positive, specify the coordinate of the left and top edge of FRAME's
3206 outer frame in pixels relative to an origin (0, 0) of FRAME's display.
3207 If any of X or Y is negative, it specifies the coordinates of the right
3208 or bottom edge of the outer frame of FRAME relative to the right or
3209 bottom edge of FRAME's display. */)
3210 (Lisp_Object frame
, Lisp_Object x
, Lisp_Object y
)
3212 struct frame
*f
= decode_live_frame (frame
);
3214 CHECK_TYPE_RANGED_INTEGER (int, x
);
3215 CHECK_TYPE_RANGED_INTEGER (int, y
);
3217 /* I think this should be done with a hook. */
3218 if (FRAME_WINDOW_P (f
))
3220 #ifdef HAVE_WINDOW_SYSTEM
3221 x_set_offset (f
, XINT (x
), XINT (y
), 1);
3229 /***********************************************************************
3231 ***********************************************************************/
3233 /* Connect the frame-parameter names for X frames
3234 to the ways of passing the parameter values to the window system.
3236 The name of a parameter, as a Lisp symbol,
3237 has an `x-frame-parameter' property which is an integer in Lisp
3238 that is an index in this table. */
3240 struct frame_parm_table
{
3245 static const struct frame_parm_table frame_parms
[] =
3247 {"auto-raise", SYMBOL_INDEX (Qauto_raise
)},
3248 {"auto-lower", SYMBOL_INDEX (Qauto_lower
)},
3249 {"background-color", -1},
3250 {"border-color", SYMBOL_INDEX (Qborder_color
)},
3251 {"border-width", SYMBOL_INDEX (Qborder_width
)},
3252 {"cursor-color", SYMBOL_INDEX (Qcursor_color
)},
3253 {"cursor-type", SYMBOL_INDEX (Qcursor_type
)},
3255 {"foreground-color", -1},
3256 {"icon-name", SYMBOL_INDEX (Qicon_name
)},
3257 {"icon-type", SYMBOL_INDEX (Qicon_type
)},
3258 {"internal-border-width", SYMBOL_INDEX (Qinternal_border_width
)},
3259 {"right-divider-width", SYMBOL_INDEX (Qright_divider_width
)},
3260 {"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width
)},
3261 {"menu-bar-lines", SYMBOL_INDEX (Qmenu_bar_lines
)},
3262 {"mouse-color", SYMBOL_INDEX (Qmouse_color
)},
3263 {"name", SYMBOL_INDEX (Qname
)},
3264 {"scroll-bar-width", SYMBOL_INDEX (Qscroll_bar_width
)},
3265 {"scroll-bar-height", SYMBOL_INDEX (Qscroll_bar_height
)},
3266 {"title", SYMBOL_INDEX (Qtitle
)},
3267 {"unsplittable", SYMBOL_INDEX (Qunsplittable
)},
3268 {"vertical-scroll-bars", SYMBOL_INDEX (Qvertical_scroll_bars
)},
3269 {"horizontal-scroll-bars", SYMBOL_INDEX (Qhorizontal_scroll_bars
)},
3270 {"visibility", SYMBOL_INDEX (Qvisibility
)},
3271 {"tool-bar-lines", SYMBOL_INDEX (Qtool_bar_lines
)},
3272 {"scroll-bar-foreground", SYMBOL_INDEX (Qscroll_bar_foreground
)},
3273 {"scroll-bar-background", SYMBOL_INDEX (Qscroll_bar_background
)},
3274 {"screen-gamma", SYMBOL_INDEX (Qscreen_gamma
)},
3275 {"line-spacing", SYMBOL_INDEX (Qline_spacing
)},
3276 {"left-fringe", SYMBOL_INDEX (Qleft_fringe
)},
3277 {"right-fringe", SYMBOL_INDEX (Qright_fringe
)},
3278 {"wait-for-wm", SYMBOL_INDEX (Qwait_for_wm
)},
3279 {"fullscreen", SYMBOL_INDEX (Qfullscreen
)},
3280 {"font-backend", SYMBOL_INDEX (Qfont_backend
)},
3281 {"alpha", SYMBOL_INDEX (Qalpha
)},
3282 {"sticky", SYMBOL_INDEX (Qsticky
)},
3283 {"tool-bar-position", SYMBOL_INDEX (Qtool_bar_position
)},
3284 {"inhibit-double-buffering", SYMBOL_INDEX (Qinhibit_double_buffering
)},
3285 {"undecorated", SYMBOL_INDEX (Qundecorated
)},
3286 {"parent-frame", SYMBOL_INDEX (Qparent_frame
)},
3287 {"skip-taskbar", SYMBOL_INDEX (Qskip_taskbar
)},
3288 {"no-focus-on-map", SYMBOL_INDEX (Qno_focus_on_map
)},
3289 {"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus
)},
3290 {"z-group", SYMBOL_INDEX (Qz_group
)},
3291 {"override-redirect", SYMBOL_INDEX (Qoverride_redirect
)},
3294 #ifdef HAVE_WINDOW_SYSTEM
3296 /* Change the parameters of frame F as specified by ALIST.
3297 If a parameter is not specially recognized, do nothing special;
3298 otherwise call the `x_set_...' function for that parameter.
3299 Except for certain geometry properties, always call store_frame_param
3300 to store the new value in the parameter alist. */
3303 x_set_frame_parameters (struct frame
*f
, Lisp_Object alist
)
3307 /* If both of these parameters are present, it's more efficient to
3308 set them both at once. So we wait until we've looked at the
3309 entire list before we set them. */
3310 int width
= -1, height
= -1; /* -1 denotes they were not changed. */
3313 Lisp_Object left
, top
;
3315 /* Same with these. */
3316 Lisp_Object icon_left
, icon_top
;
3318 /* And with this. */
3319 Lisp_Object fullscreen
;
3320 bool fullscreen_change
= false;
3322 /* Record in these vectors all the parms specified. */
3324 Lisp_Object
*values
;
3325 ptrdiff_t i
, j
, size
;
3326 bool left_no_change
= 0, top_no_change
= 0;
3327 #ifdef HAVE_X_WINDOWS
3328 bool icon_left_no_change
= 0, icon_top_no_change
= 0;
3331 for (size
= 0, tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
3333 CHECK_LIST_END (tail
, alist
);
3336 SAFE_ALLOCA_LISP (parms
, 2 * size
);
3337 values
= parms
+ size
;
3339 /* Extract parm names and values into those vectors. */
3341 i
= 0, j
= size
- 1;
3342 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
3344 Lisp_Object elt
= XCAR (tail
), prop
= Fcar (elt
), val
= Fcdr (elt
);
3346 /* Some properties are independent of other properties, but other
3347 properties are dependent upon them. These special properties
3348 are foreground_color, background_color (affects cursor_color)
3349 and font (affects fringe widths); they're recorded starting
3350 from the end of PARMS and VALUES to process them first by using
3351 reverse iteration. */
3353 if (EQ (prop
, Qforeground_color
)
3354 || EQ (prop
, Qbackground_color
)
3355 || EQ (prop
, Qfont
))
3369 /* TAIL and ALIST are not used again below here. */
3370 alist
= tail
= Qnil
;
3372 top
= left
= Qunbound
;
3373 icon_left
= icon_top
= Qunbound
;
3375 /* Reverse order is used to make sure that special
3376 properties noticed above are processed first. */
3377 for (i
= size
- 1; i
>= 0; i
--)
3379 Lisp_Object prop
, val
;
3384 if (EQ (prop
, Qwidth
))
3386 if (RANGED_INTEGERP (0, val
, INT_MAX
))
3387 width
= XFASTINT (val
) * FRAME_COLUMN_WIDTH (f
) ;
3388 else if (CONSP (val
) && EQ (XCAR (val
), Qtext_pixels
)
3389 && RANGED_INTEGERP (0, XCDR (val
), INT_MAX
))
3390 width
= XFASTINT (XCDR (val
));
3392 else if (EQ (prop
, Qheight
))
3394 if (RANGED_INTEGERP (0, val
, INT_MAX
))
3395 height
= XFASTINT (val
) * FRAME_LINE_HEIGHT (f
);
3396 else if (CONSP (val
) && EQ (XCAR (val
), Qtext_pixels
)
3397 && RANGED_INTEGERP (0, XCDR (val
), INT_MAX
))
3398 height
= XFASTINT (XCDR (val
));
3400 else if (EQ (prop
, Qtop
))
3402 else if (EQ (prop
, Qleft
))
3404 else if (EQ (prop
, Qicon_top
))
3406 else if (EQ (prop
, Qicon_left
))
3408 else if (EQ (prop
, Qfullscreen
))
3411 fullscreen_change
= true;
3415 register Lisp_Object param_index
, old_value
;
3417 old_value
= get_frame_param (f
, prop
);
3419 store_frame_param (f
, prop
, val
);
3421 param_index
= Fget (prop
, Qx_frame_parameter
);
3422 if (NATNUMP (param_index
)
3423 && XFASTINT (param_index
) < ARRAYELTS (frame_parms
)
3424 && FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])
3425 (*(FRAME_RIF (f
)->frame_parm_handlers
[XINT (param_index
)])) (f
, val
, old_value
);
3429 /* Don't die if just one of these was set. */
3430 if (EQ (left
, Qunbound
))
3433 if (f
->left_pos
< 0)
3434 left
= list2 (Qplus
, make_number (f
->left_pos
));
3436 XSETINT (left
, f
->left_pos
);
3438 if (EQ (top
, Qunbound
))
3442 top
= list2 (Qplus
, make_number (f
->top_pos
));
3444 XSETINT (top
, f
->top_pos
);
3447 /* If one of the icon positions was not set, preserve or default it. */
3448 if (! TYPE_RANGED_INTEGERP (int, icon_left
))
3450 #ifdef HAVE_X_WINDOWS
3451 icon_left_no_change
= 1;
3453 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
3454 if (NILP (icon_left
))
3455 XSETINT (icon_left
, 0);
3457 if (! TYPE_RANGED_INTEGERP (int, icon_top
))
3459 #ifdef HAVE_X_WINDOWS
3460 icon_top_no_change
= 1;
3462 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
3463 if (NILP (icon_top
))
3464 XSETINT (icon_top
, 0);
3467 /* Don't set these parameters unless they've been explicitly
3468 specified. The window might be mapped or resized while we're in
3469 this function, and we don't want to override that unless the lisp
3470 code has asked for it.
3472 Don't set these parameters unless they actually differ from the
3473 window's current parameters; the window may not actually exist
3478 XSETFRAME (frame
, f
);
3480 if ((width
!= -1 && width
!= FRAME_TEXT_WIDTH (f
))
3481 || (height
!= -1 && height
!= FRAME_TEXT_HEIGHT (f
)))
3482 /* We could consider checking f->after_make_frame here, but I
3483 don't have the faintest idea why the following is needed at
3484 all. With the old setting it can get a Heisenbug when
3485 EmacsFrameResize intermittently provokes a delayed
3486 change_frame_size in the middle of adjust_frame_size. */
3487 /** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/
3488 adjust_frame_size (f
, width
, height
, 1, 0, Qx_set_frame_parameters
);
3490 if ((!NILP (left
) || !NILP (top
))
3491 && ! (left_no_change
&& top_no_change
)
3492 && ! (NUMBERP (left
) && XINT (left
) == f
->left_pos
3493 && NUMBERP (top
) && XINT (top
) == f
->top_pos
))
3498 /* Record the signs. */
3499 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
3500 if (EQ (left
, Qminus
))
3501 f
->size_hint_flags
|= XNegative
;
3502 else if (TYPE_RANGED_INTEGERP (int, left
))
3504 leftpos
= XINT (left
);
3506 f
->size_hint_flags
|= XNegative
;
3508 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
3509 && CONSP (XCDR (left
))
3510 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (left
)), INT_MAX
))
3512 leftpos
= - XINT (XCAR (XCDR (left
)));
3513 f
->size_hint_flags
|= XNegative
;
3515 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
3516 && CONSP (XCDR (left
))
3517 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left
))))
3519 leftpos
= XINT (XCAR (XCDR (left
)));
3522 if (EQ (top
, Qminus
))
3523 f
->size_hint_flags
|= YNegative
;
3524 else if (TYPE_RANGED_INTEGERP (int, top
))
3526 toppos
= XINT (top
);
3528 f
->size_hint_flags
|= YNegative
;
3530 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
3531 && CONSP (XCDR (top
))
3532 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (top
)), INT_MAX
))
3534 toppos
= - XINT (XCAR (XCDR (top
)));
3535 f
->size_hint_flags
|= YNegative
;
3537 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
3538 && CONSP (XCDR (top
))
3539 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top
))))
3541 toppos
= XINT (XCAR (XCDR (top
)));
3545 /* Store the numeric value of the position. */
3546 f
->top_pos
= toppos
;
3547 f
->left_pos
= leftpos
;
3549 f
->win_gravity
= NorthWestGravity
;
3551 /* Actually set that position, and convert to absolute. */
3552 x_set_offset (f
, leftpos
, toppos
, -1);
3555 if (fullscreen_change
)
3557 Lisp_Object old_value
= get_frame_param (f
, Qfullscreen
);
3559 frame_size_history_add
3560 (f
, Qx_set_fullscreen
, 0, 0, list2 (old_value
, fullscreen
));
3562 store_frame_param (f
, Qfullscreen
, fullscreen
);
3563 if (!EQ (fullscreen
, old_value
))
3564 x_set_fullscreen (f
, fullscreen
, old_value
);
3568 #ifdef HAVE_X_WINDOWS
3569 if ((!NILP (icon_left
) || !NILP (icon_top
))
3570 && ! (icon_left_no_change
&& icon_top_no_change
))
3571 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
3572 #endif /* HAVE_X_WINDOWS */
3579 /* Insert a description of internally-recorded parameters of frame X
3580 into the parameter alist *ALISTPTR that is to be given to the user.
3581 Only parameters that are specific to the X window system
3582 and whose values are not correctly recorded in the frame's
3583 param_alist need to be considered here. */
3586 x_report_frame_params (struct frame
*f
, Lisp_Object
*alistptr
)
3590 char buf
[INT_BUFSIZE_BOUND (w
)];
3592 /* Represent negative positions (off the top or left screen edge)
3593 in a way that Fmodify_frame_parameters will understand correctly. */
3594 XSETINT (tem
, f
->left_pos
);
3595 if (f
->left_pos
>= 0)
3596 store_in_alist (alistptr
, Qleft
, tem
);
3598 store_in_alist (alistptr
, Qleft
, list2 (Qplus
, tem
));
3600 XSETINT (tem
, f
->top_pos
);
3601 if (f
->top_pos
>= 0)
3602 store_in_alist (alistptr
, Qtop
, tem
);
3604 store_in_alist (alistptr
, Qtop
, list2 (Qplus
, tem
));
3606 store_in_alist (alistptr
, Qborder_width
,
3607 make_number (f
->border_width
));
3608 store_in_alist (alistptr
, Qinternal_border_width
,
3609 make_number (FRAME_INTERNAL_BORDER_WIDTH (f
)));
3610 store_in_alist (alistptr
, Qright_divider_width
,
3611 make_number (FRAME_RIGHT_DIVIDER_WIDTH (f
)));
3612 store_in_alist (alistptr
, Qbottom_divider_width
,
3613 make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f
)));
3614 store_in_alist (alistptr
, Qleft_fringe
,
3615 make_number (FRAME_LEFT_FRINGE_WIDTH (f
)));
3616 store_in_alist (alistptr
, Qright_fringe
,
3617 make_number (FRAME_RIGHT_FRINGE_WIDTH (f
)));
3618 store_in_alist (alistptr
, Qscroll_bar_width
,
3619 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
3621 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0
3622 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
))
3623 /* nil means "use default width"
3624 for non-toolkit scroll bar.
3625 ruler-mode.el depends on this. */
3627 store_in_alist (alistptr
, Qscroll_bar_height
,
3628 (! FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
)
3630 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) > 0
3631 ? make_number (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
))
3632 /* nil means "use default height"
3633 for non-toolkit scroll bar. */
3635 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
3636 MS-Windows it returns a value whose type is HANDLE, which is
3637 actually a pointer. Explicit casting avoids compiler
3639 w
= (uintptr_t) FRAME_X_WINDOW (f
);
3640 store_in_alist (alistptr
, Qwindow_id
,
3641 make_formatted_string (buf
, "%"pMu
, w
));
3642 #ifdef HAVE_X_WINDOWS
3643 #ifdef USE_X_TOOLKIT
3644 /* Tooltip frame may not have this widget. */
3645 if (FRAME_X_OUTPUT (f
)->widget
)
3647 w
= (uintptr_t) FRAME_OUTER_WINDOW (f
);
3648 store_in_alist (alistptr
, Qouter_window_id
,
3649 make_formatted_string (buf
, "%"pMu
, w
));
3651 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
3652 store_in_alist (alistptr
, Qvisibility
,
3653 (FRAME_VISIBLE_P (f
) ? Qt
3654 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
3655 store_in_alist (alistptr
, Qdisplay
,
3656 XCAR (FRAME_DISPLAY_INFO (f
)->name_list_element
));
3658 if (FRAME_X_OUTPUT (f
)->parent_desc
== FRAME_DISPLAY_INFO (f
)->root_window
)
3661 tem
= make_natnum ((uintptr_t) FRAME_X_OUTPUT (f
)->parent_desc
);
3662 store_in_alist (alistptr
, Qexplicit_name
, (f
->explicit_name
? Qt
: Qnil
));
3663 store_in_alist (alistptr
, Qparent_id
, tem
);
3664 store_in_alist (alistptr
, Qtool_bar_position
, FRAME_TOOL_BAR_POSITION (f
));
3668 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3669 the previous value of that parameter, NEW_VALUE is the new value. */
3672 x_set_fullscreen (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3674 if (NILP (new_value
))
3675 f
->want_fullscreen
= FULLSCREEN_NONE
;
3676 else if (EQ (new_value
, Qfullboth
) || EQ (new_value
, Qfullscreen
))
3677 f
->want_fullscreen
= FULLSCREEN_BOTH
;
3678 else if (EQ (new_value
, Qfullwidth
))
3679 f
->want_fullscreen
= FULLSCREEN_WIDTH
;
3680 else if (EQ (new_value
, Qfullheight
))
3681 f
->want_fullscreen
= FULLSCREEN_HEIGHT
;
3682 else if (EQ (new_value
, Qmaximized
))
3683 f
->want_fullscreen
= FULLSCREEN_MAXIMIZED
;
3685 if (FRAME_TERMINAL (f
)->fullscreen_hook
!= NULL
)
3686 FRAME_TERMINAL (f
)->fullscreen_hook (f
);
3690 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3691 the previous value of that parameter, NEW_VALUE is the new value. */
3694 x_set_line_spacing (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3696 if (NILP (new_value
))
3697 f
->extra_line_spacing
= 0;
3698 else if (RANGED_INTEGERP (0, new_value
, INT_MAX
))
3699 f
->extra_line_spacing
= XFASTINT (new_value
);
3700 else if (FLOATP (new_value
))
3702 int new_spacing
= XFLOAT_DATA (new_value
) * FRAME_LINE_HEIGHT (f
) + 0.5;
3704 if (new_spacing
>= 0)
3705 f
->extra_line_spacing
= new_spacing
;
3707 signal_error ("Invalid line-spacing", new_value
);
3710 signal_error ("Invalid line-spacing", new_value
);
3711 if (FRAME_VISIBLE_P (f
))
3716 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3717 the previous value of that parameter, NEW_VALUE is the new value. */
3720 x_set_screen_gamma (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3722 Lisp_Object bgcolor
;
3724 if (NILP (new_value
))
3726 else if (NUMBERP (new_value
) && XFLOATINT (new_value
) > 0)
3727 /* The value 0.4545 is the normal viewing gamma. */
3728 f
->gamma
= 1.0 / (0.4545 * XFLOATINT (new_value
));
3730 signal_error ("Invalid screen-gamma", new_value
);
3732 /* Apply the new gamma value to the frame background. */
3733 bgcolor
= Fassq (Qbackground_color
, f
->param_alist
);
3734 if (CONSP (bgcolor
) && (bgcolor
= XCDR (bgcolor
), STRINGP (bgcolor
)))
3736 Lisp_Object parm_index
= Fget (Qbackground_color
, Qx_frame_parameter
);
3737 if (NATNUMP (parm_index
)
3738 && XFASTINT (parm_index
) < ARRAYELTS (frame_parms
)
3739 && FRAME_RIF (f
)->frame_parm_handlers
[XFASTINT (parm_index
)])
3740 (*FRAME_RIF (f
)->frame_parm_handlers
[XFASTINT (parm_index
)])
3744 clear_face_cache (true); /* FIXME: Why of all frames? */
3750 x_set_font (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3752 Lisp_Object font_object
;
3754 #ifdef HAVE_X_WINDOWS
3755 Lisp_Object font_param
= arg
;
3758 /* Set the frame parameter back to the old value because we may
3759 fail to use ARG as the new parameter value. */
3760 store_frame_param (f
, Qfont
, oldval
);
3762 /* ARG is a fontset name, a font name, a cons of fontset name and a
3763 font object, or a font object. In the last case, this function
3767 fontset
= fs_query_fontset (arg
, 0);
3770 font_object
= font_open_by_name (f
, arg
);
3771 if (NILP (font_object
))
3772 error ("Font `%s' is not defined", SSDATA (arg
));
3773 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3775 else if (fontset
> 0)
3777 font_object
= font_open_by_name (f
, fontset_ascii (fontset
));
3778 if (NILP (font_object
))
3779 error ("Font `%s' is not defined", SDATA (arg
));
3780 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3783 error ("The default fontset can't be used for a frame font");
3785 else if (CONSP (arg
) && STRINGP (XCAR (arg
)) && FONT_OBJECT_P (XCDR (arg
)))
3787 /* This is the case that the ASCII font of F's fontset XCAR
3788 (arg) is changed to the font XCDR (arg) by
3789 `set-fontset-font'. */
3790 fontset
= fs_query_fontset (XCAR (arg
), 0);
3792 error ("Unknown fontset: %s", SDATA (XCAR (arg
)));
3793 font_object
= XCDR (arg
);
3794 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3795 #ifdef HAVE_X_WINDOWS
3796 font_param
= Ffont_get (font_object
, QCname
);
3799 else if (FONT_OBJECT_P (arg
))
3802 #ifdef HAVE_X_WINDOWS
3803 font_param
= Ffont_get (font_object
, QCname
);
3805 /* This is to store the XLFD font name in the frame parameter for
3806 backward compatibility. We should store the font-object
3807 itself in the future. */
3808 arg
= AREF (font_object
, FONT_NAME_INDEX
);
3809 fontset
= FRAME_FONTSET (f
);
3810 /* Check if we can use the current fontset. If not, set FONTSET
3811 to -1 to generate a new fontset from FONT-OBJECT. */
3814 Lisp_Object ascii_font
= fontset_ascii (fontset
);
3815 Lisp_Object spec
= font_spec_from_name (ascii_font
);
3817 /* SPEC might be nil because ASCII_FONT's name doesn't parse
3818 according to stupid XLFD rules, which, for example,
3819 disallow font names that include a dash followed by a
3820 number. So in those cases we simply request x_new_font
3821 below to generate a new fontset. */
3822 if (NILP (spec
) || ! font_match_p (spec
, font_object
))
3827 signal_error ("Invalid font", arg
);
3829 if (! NILP (Fequal (font_object
, oldval
)))
3832 x_new_font (f
, font_object
, fontset
);
3833 store_frame_param (f
, Qfont
, arg
);
3834 #ifdef HAVE_X_WINDOWS
3835 store_frame_param (f
, Qfont_parameter
, font_param
);
3837 /* Recalculate toolbar height. */
3838 f
->n_tool_bar_rows
= 0;
3840 /* Ensure we redraw it. */
3841 clear_current_matrices (f
);
3843 /* Attempt to hunt down bug#16028. */
3844 SET_FRAME_GARBAGED (f
);
3846 /* This is important if we are called by some Lisp as part of
3847 redisplaying the frame, see redisplay_internal. */
3848 f
->fonts_changed
= true;
3850 recompute_basic_faces (f
);
3852 do_pending_window_change (0);
3854 /* We used to call face-set-after-frame-default here, but it leads to
3855 recursive calls (since that function can set the `default' face's
3856 font which in turns changes the frame's `font' parameter).
3857 Also I don't know what this call is meant to do, but it seems the
3858 wrong way to do it anyway (it does a lot more work than what seems
3859 reasonable in response to a change to `font'). */
3864 x_set_font_backend (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3866 if (! NILP (new_value
)
3867 && !CONSP (new_value
))
3871 CHECK_STRING (new_value
);
3872 p0
= p1
= SSDATA (new_value
);
3876 while (*p1
&& ! c_isspace (*p1
) && *p1
!= ',') p1
++;
3878 new_value
= Fcons (Fintern (make_string (p0
, p1
- p0
), Qnil
),
3884 while ((c
= *++p1
) && c_isspace (c
));
3888 new_value
= Fnreverse (new_value
);
3891 if (! NILP (old_value
) && ! NILP (Fequal (old_value
, new_value
)))
3895 free_all_realized_faces (Qnil
);
3897 new_value
= font_update_drivers (f
, NILP (new_value
) ? Qt
: new_value
);
3898 if (NILP (new_value
))
3900 if (NILP (old_value
))
3901 error ("No font backend available");
3902 font_update_drivers (f
, old_value
);
3903 error ("None of specified font backends are available");
3905 store_frame_param (f
, Qfont_backend
, new_value
);
3911 XSETFRAME (frame
, f
);
3912 x_set_font (f
, Fframe_parameter (frame
, Qfont
), Qnil
);
3914 windows_or_buffers_changed
= 18;
3919 x_set_left_fringe (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3921 int unit
= FRAME_COLUMN_WIDTH (f
);
3922 int old_width
= FRAME_LEFT_FRINGE_WIDTH (f
);
3925 new_width
= (RANGED_INTEGERP (-INT_MAX
, new_value
, INT_MAX
)
3926 ? eabs (XINT (new_value
)) : 8);
3928 if (new_width
!= old_width
)
3930 f
->left_fringe_width
= new_width
;
3931 f
->fringe_cols
/* Round up. */
3932 = (new_width
+ FRAME_RIGHT_FRINGE_WIDTH (f
) + unit
- 1) / unit
;
3934 if (FRAME_X_WINDOW (f
) != 0)
3935 adjust_frame_size (f
, -1, -1, 3, 0, Qleft_fringe
);
3937 SET_FRAME_GARBAGED (f
);
3943 x_set_right_fringe (struct frame
*f
, Lisp_Object new_value
, Lisp_Object old_value
)
3945 int unit
= FRAME_COLUMN_WIDTH (f
);
3946 int old_width
= FRAME_RIGHT_FRINGE_WIDTH (f
);
3949 new_width
= (RANGED_INTEGERP (-INT_MAX
, new_value
, INT_MAX
)
3950 ? eabs (XINT (new_value
)) : 8);
3952 if (new_width
!= old_width
)
3954 f
->right_fringe_width
= new_width
;
3955 f
->fringe_cols
/* Round up. */
3956 = (new_width
+ FRAME_LEFT_FRINGE_WIDTH (f
) + unit
- 1) / unit
;
3958 if (FRAME_X_WINDOW (f
) != 0)
3959 adjust_frame_size (f
, -1, -1, 3, 0, Qright_fringe
);
3961 SET_FRAME_GARBAGED (f
);
3967 x_set_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3969 CHECK_TYPE_RANGED_INTEGER (int, arg
);
3971 if (XINT (arg
) == f
->border_width
)
3974 if (FRAME_X_WINDOW (f
) != 0)
3975 error ("Cannot change the border width of a frame");
3977 f
->border_width
= XINT (arg
);
3981 x_set_right_divider_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3983 int old
= FRAME_RIGHT_DIVIDER_WIDTH (f
);
3984 CHECK_TYPE_RANGED_INTEGER (int, arg
);
3985 int new = max (0, XINT (arg
));
3988 f
->right_divider_width
= new;
3989 adjust_frame_size (f
, -1, -1, 4, 0, Qright_divider_width
);
3990 adjust_frame_glyphs (f
);
3991 SET_FRAME_GARBAGED (f
);
3997 x_set_bottom_divider_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
3999 int old
= FRAME_BOTTOM_DIVIDER_WIDTH (f
);
4000 CHECK_TYPE_RANGED_INTEGER (int, arg
);
4001 int new = max (0, XINT (arg
));
4004 f
->bottom_divider_width
= new;
4005 adjust_frame_size (f
, -1, -1, 4, 0, Qbottom_divider_width
);
4006 adjust_frame_glyphs (f
);
4007 SET_FRAME_GARBAGED (f
);
4012 x_set_visibility (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
4015 XSETFRAME (frame
, f
);
4018 Fmake_frame_invisible (frame
, Qt
);
4019 else if (EQ (value
, Qicon
))
4020 Ficonify_frame (frame
);
4022 Fmake_frame_visible (frame
);
4026 x_set_autoraise (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4028 f
->auto_raise
= !EQ (Qnil
, arg
);
4032 x_set_autolower (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4034 f
->auto_lower
= !EQ (Qnil
, arg
);
4038 x_set_unsplittable (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4040 f
->no_split
= !NILP (arg
);
4044 x_set_vertical_scroll_bars (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4046 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4047 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
4048 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4049 || (!NILP (arg
) && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
4051 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
)
4053 ? vertical_scroll_bar_none
4055 ? vertical_scroll_bar_left
4057 ? vertical_scroll_bar_right
4058 : EQ (Qleft
, Vdefault_frame_scroll_bars
)
4059 ? vertical_scroll_bar_left
4060 : EQ (Qright
, Vdefault_frame_scroll_bars
)
4061 ? vertical_scroll_bar_right
4062 : vertical_scroll_bar_none
);
4064 /* We set this parameter before creating the X window for the
4065 frame, so we can get the geometry right from the start.
4066 However, if the window hasn't been created yet, we shouldn't
4067 call x_set_window_size. */
4068 if (FRAME_X_WINDOW (f
))
4069 adjust_frame_size (f
, -1, -1, 3, 0, Qvertical_scroll_bars
);
4071 SET_FRAME_GARBAGED (f
);
4076 x_set_horizontal_scroll_bars (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4078 #if USE_HORIZONTAL_SCROLL_BARS
4079 if ((NILP (arg
) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
))
4080 || (!NILP (arg
) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f
)))
4082 f
->horizontal_scroll_bars
= NILP (arg
) ? false : true;
4084 /* We set this parameter before creating the X window for the
4085 frame, so we can get the geometry right from the start.
4086 However, if the window hasn't been created yet, we shouldn't
4087 call x_set_window_size. */
4088 if (FRAME_X_WINDOW (f
))
4089 adjust_frame_size (f
, -1, -1, 3, 0, Qhorizontal_scroll_bars
);
4091 SET_FRAME_GARBAGED (f
);
4097 x_set_scroll_bar_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4099 int unit
= FRAME_COLUMN_WIDTH (f
);
4103 x_set_scroll_bar_default_width (f
);
4105 if (FRAME_X_WINDOW (f
))
4106 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_width
);
4108 SET_FRAME_GARBAGED (f
);
4110 else if (RANGED_INTEGERP (1, arg
, INT_MAX
)
4111 && XFASTINT (arg
) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f
))
4113 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = XFASTINT (arg
);
4114 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + unit
- 1) / unit
;
4115 if (FRAME_X_WINDOW (f
))
4116 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_width
);
4118 SET_FRAME_GARBAGED (f
);
4121 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.hpos
= 0;
4122 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.x
= 0;
4126 x_set_scroll_bar_height (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4128 #if USE_HORIZONTAL_SCROLL_BARS
4129 int unit
= FRAME_LINE_HEIGHT (f
);
4133 x_set_scroll_bar_default_height (f
);
4135 if (FRAME_X_WINDOW (f
))
4136 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_height
);
4138 SET_FRAME_GARBAGED (f
);
4140 else if (RANGED_INTEGERP (1, arg
, INT_MAX
)
4141 && XFASTINT (arg
) != FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
))
4143 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = XFASTINT (arg
);
4144 FRAME_CONFIG_SCROLL_BAR_LINES (f
) = (XFASTINT (arg
) + unit
- 1) / unit
;
4145 if (FRAME_X_WINDOW (f
))
4146 adjust_frame_size (f
, -1, -1, 3, 0, Qscroll_bar_height
);
4148 SET_FRAME_GARBAGED (f
);
4151 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.vpos
= 0;
4152 XWINDOW (FRAME_SELECTED_WINDOW (f
))->cursor
.y
= 0;
4157 x_set_alpha (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
4164 for (i
= 0; i
< 2; i
++)
4177 else if (FLOATP (item
))
4179 alpha
= XFLOAT_DATA (item
);
4180 if (! (0 <= alpha
&& alpha
<= 1.0))
4181 args_out_of_range (make_float (0.0), make_float (1.0));
4183 else if (INTEGERP (item
))
4185 EMACS_INT ialpha
= XINT (item
);
4186 if (! (0 <= ialpha
&& ialpha
<= 100))
4187 args_out_of_range (make_number (0), make_number (100));
4188 alpha
= ialpha
/ 100.0;
4191 wrong_type_argument (Qnumberp
, item
);
4195 for (i
= 0; i
< 2; i
++)
4196 f
->alpha
[i
] = newval
[i
];
4198 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
4200 x_set_frame_alpha (f
);
4209 /* Non-zero if mouse is grabbed on DPYINFO
4210 and we know the frame where it is. */
4212 bool x_mouse_grabbed (Display_Info
*dpyinfo
)
4214 return (dpyinfo
->grabbed
4215 && dpyinfo
->last_mouse_frame
4216 && FRAME_LIVE_P (dpyinfo
->last_mouse_frame
));
4219 /* Re-highlight something with mouse-face properties
4220 on DPYINFO using saved frame and mouse position. */
4223 x_redo_mouse_highlight (Display_Info
*dpyinfo
)
4225 if (dpyinfo
->last_mouse_motion_frame
4226 && FRAME_LIVE_P (dpyinfo
->last_mouse_motion_frame
))
4227 note_mouse_highlight (dpyinfo
->last_mouse_motion_frame
,
4228 dpyinfo
->last_mouse_motion_x
,
4229 dpyinfo
->last_mouse_motion_y
);
4232 #endif /* HAVE_NS */
4234 /* Subroutines of creating an X frame. */
4236 /* Make sure that Vx_resource_name is set to a reasonable value.
4237 Fix it up, or set it to `emacs' if it is too hopeless. */
4240 validate_x_resource_name (void)
4243 /* Number of valid characters in the resource name. */
4244 ptrdiff_t good_count
= 0;
4245 /* Number of invalid characters in the resource name. */
4246 ptrdiff_t bad_count
= 0;
4250 if (!STRINGP (Vx_resource_class
))
4251 Vx_resource_class
= build_string (EMACS_CLASS
);
4253 if (STRINGP (Vx_resource_name
))
4255 unsigned char *p
= SDATA (Vx_resource_name
);
4257 len
= SBYTES (Vx_resource_name
);
4259 /* Only letters, digits, - and _ are valid in resource names.
4260 Count the valid characters and count the invalid ones. */
4261 for (i
= 0; i
< len
; i
++)
4264 if (! ((c
>= 'a' && c
<= 'z')
4265 || (c
>= 'A' && c
<= 'Z')
4266 || (c
>= '0' && c
<= '9')
4267 || c
== '-' || c
== '_'))
4274 /* Not a string => completely invalid. */
4275 bad_count
= 5, good_count
= 0;
4277 /* If name is valid already, return. */
4281 /* If name is entirely invalid, or nearly so, or is so implausibly
4282 large that alloca might not work, use `emacs'. */
4283 if (good_count
< 2 || MAX_ALLOCA
- sizeof ".customization" < len
)
4285 Vx_resource_name
= build_string ("emacs");
4289 /* Name is partly valid. Copy it and replace the invalid characters
4290 with underscores. */
4292 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
4294 for (i
= 0; i
< len
; i
++)
4296 int c
= SREF (new, i
);
4297 if (! ((c
>= 'a' && c
<= 'z')
4298 || (c
>= 'A' && c
<= 'Z')
4299 || (c
>= '0' && c
<= '9')
4300 || c
== '-' || c
== '_'))
4305 /* Get specified attribute from resource database RDB.
4306 See Fx_get_resource below for other parameters. */
4309 xrdb_get_resource (XrmDatabase rdb
, Lisp_Object attribute
, Lisp_Object
class, Lisp_Object component
, Lisp_Object subclass
)
4311 CHECK_STRING (attribute
);
4312 CHECK_STRING (class);
4314 if (!NILP (component
))
4315 CHECK_STRING (component
);
4316 if (!NILP (subclass
))
4317 CHECK_STRING (subclass
);
4318 if (NILP (component
) != NILP (subclass
))
4319 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
4321 validate_x_resource_name ();
4323 /* Allocate space for the components, the dots which separate them,
4324 and the final '\0'. Make them big enough for the worst case. */
4325 ptrdiff_t name_keysize
= (SBYTES (Vx_resource_name
)
4326 + (STRINGP (component
)
4327 ? SBYTES (component
) : 0)
4328 + SBYTES (attribute
)
4331 ptrdiff_t class_keysize
= (SBYTES (Vx_resource_class
)
4333 + (STRINGP (subclass
)
4334 ? SBYTES (subclass
) : 0)
4337 char *name_key
= SAFE_ALLOCA (name_keysize
+ class_keysize
);
4338 char *class_key
= name_key
+ name_keysize
;
4340 /* Start with emacs.FRAMENAME for the name (the specific one)
4341 and with `Emacs' for the class key (the general one). */
4342 char *nz
= lispstpcpy (name_key
, Vx_resource_name
);
4343 char *cz
= lispstpcpy (class_key
, Vx_resource_class
);
4346 cz
= lispstpcpy (cz
, class);
4348 if (!NILP (component
))
4351 lispstpcpy (cz
, subclass
);
4354 nz
= lispstpcpy (nz
, component
);
4358 lispstpcpy (nz
, attribute
);
4360 char *value
= x_get_string_resource (rdb
, name_key
, class_key
);
4363 if (value
&& *value
)
4364 return build_string (value
);
4370 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
4371 doc
: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
4372 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
4373 class, where INSTANCE is the name under which Emacs was invoked, or
4374 the name specified by the `-name' or `-rn' command-line arguments.
4376 The optional arguments COMPONENT and SUBCLASS add to the key and the
4377 class, respectively. You must specify both of them or neither.
4378 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
4379 and the class is `Emacs.CLASS.SUBCLASS'. */)
4380 (Lisp_Object attribute
, Lisp_Object
class, Lisp_Object component
,
4381 Lisp_Object subclass
)
4383 check_window_system (NULL
);
4385 return xrdb_get_resource (check_x_display_info (Qnil
)->xrdb
,
4386 attribute
, class, component
, subclass
);
4389 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
4392 display_x_get_resource (Display_Info
*dpyinfo
, Lisp_Object attribute
,
4393 Lisp_Object
class, Lisp_Object component
,
4394 Lisp_Object subclass
)
4396 return xrdb_get_resource (dpyinfo
->xrdb
,
4397 attribute
, class, component
, subclass
);
4400 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT && !defined USE_GTK
4401 /* Used when C code wants a resource value. */
4402 /* Called from oldXMenu/Create.c. */
4404 x_get_resource_string (const char *attribute
, const char *class)
4407 struct frame
*sf
= SELECTED_FRAME ();
4408 ptrdiff_t invocation_namelen
= SBYTES (Vinvocation_name
);
4411 /* Allocate space for the components, the dots which separate them,
4412 and the final '\0'. */
4413 ptrdiff_t name_keysize
= invocation_namelen
+ strlen (attribute
) + 2;
4414 ptrdiff_t class_keysize
= sizeof (EMACS_CLASS
) - 1 + strlen (class) + 2;
4415 char *name_key
= SAFE_ALLOCA (name_keysize
+ class_keysize
);
4416 char *class_key
= name_key
+ name_keysize
;
4418 esprintf (name_key
, "%s.%s", SSDATA (Vinvocation_name
), attribute
);
4419 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
4421 result
= x_get_string_resource (FRAME_DISPLAY_INFO (sf
)->xrdb
,
4422 name_key
, class_key
);
4428 /* Return the value of parameter PARAM.
4430 First search ALIST, then Vdefault_frame_alist, then the X defaults
4431 database, using ATTRIBUTE as the attribute name and CLASS as its class.
4433 Convert the resource to the type specified by desired_type.
4435 If no default is specified, return Qunbound. If you call
4436 x_get_arg, make sure you deal with Qunbound in a reasonable way,
4437 and don't let it get stored in any Lisp-visible variables! */
4440 x_get_arg (Display_Info
*dpyinfo
, Lisp_Object alist
, Lisp_Object param
,
4441 const char *attribute
, const char *class, enum resource_types type
)
4445 tem
= Fassq (param
, alist
);
4449 /* If we find this parm in ALIST, clear it out
4450 so that it won't be "left over" at the end. */
4452 XSETCAR (tem
, Qnil
);
4453 /* In case the parameter appears more than once in the alist,
4455 for (tail
= alist
; CONSP (tail
); tail
= XCDR (tail
))
4456 if (CONSP (XCAR (tail
))
4457 && EQ (XCAR (XCAR (tail
)), param
))
4458 XSETCAR (XCAR (tail
), Qnil
);
4461 tem
= Fassq (param
, Vdefault_frame_alist
);
4463 /* If it wasn't specified in ALIST or the Lisp-level defaults,
4464 look in the X resources. */
4467 if (attribute
&& dpyinfo
)
4469 AUTO_STRING (at
, attribute
);
4470 AUTO_STRING (cl
, class);
4471 tem
= display_x_get_resource (dpyinfo
, at
, cl
, Qnil
, Qnil
);
4478 case RES_TYPE_NUMBER
:
4479 return make_number (atoi (SSDATA (tem
)));
4481 case RES_TYPE_BOOLEAN_NUMBER
:
4482 if (!strcmp (SSDATA (tem
), "on")
4483 || !strcmp (SSDATA (tem
), "true"))
4484 return make_number (1);
4485 return make_number (atoi (SSDATA (tem
)));
4488 case RES_TYPE_FLOAT
:
4489 return make_float (atof (SSDATA (tem
)));
4491 case RES_TYPE_BOOLEAN
:
4492 tem
= Fdowncase (tem
);
4493 if (!strcmp (SSDATA (tem
), "on")
4495 || !strcmp (SSDATA (tem
), "yes")
4497 || !strcmp (SSDATA (tem
), "true"))
4502 case RES_TYPE_STRING
:
4505 case RES_TYPE_SYMBOL
:
4506 /* As a special case, we map the values `true' and `on'
4507 to Qt, and `false' and `off' to Qnil. */
4510 lower
= Fdowncase (tem
);
4511 if (!strcmp (SSDATA (lower
), "on")
4513 || !strcmp (SSDATA (lower
), "yes")
4515 || !strcmp (SSDATA (lower
), "true"))
4517 else if (!strcmp (SSDATA (lower
), "off")
4519 || !strcmp (SSDATA (lower
), "no")
4521 || !strcmp (SSDATA (lower
), "false"))
4524 return Fintern (tem
, Qnil
);
4538 x_frame_get_arg (struct frame
*f
, Lisp_Object alist
, Lisp_Object param
,
4539 const char *attribute
, const char *class,
4540 enum resource_types type
)
4542 return x_get_arg (FRAME_DISPLAY_INFO (f
),
4543 alist
, param
, attribute
, class, type
);
4546 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
4549 x_frame_get_and_record_arg (struct frame
*f
, Lisp_Object alist
,
4551 const char *attribute
, const char *class,
4552 enum resource_types type
)
4556 value
= x_get_arg (FRAME_DISPLAY_INFO (f
), alist
, param
,
4557 attribute
, class, type
);
4558 if (! NILP (value
) && ! EQ (value
, Qunbound
))
4559 store_frame_param (f
, param
, value
);
4565 /* Record in frame F the specified or default value according to ALIST
4566 of the parameter named PROP (a Lisp symbol).
4567 If no value is specified for PROP, look for an X default for XPROP
4568 on the frame named NAME.
4569 If that is not found either, use the value DEFLT. */
4572 x_default_parameter (struct frame
*f
, Lisp_Object alist
, Lisp_Object prop
,
4573 Lisp_Object deflt
, const char *xprop
, const char *xclass
,
4574 enum resource_types type
)
4578 tem
= x_frame_get_arg (f
, alist
, prop
, xprop
, xclass
, type
);
4579 if (EQ (tem
, Qunbound
))
4581 AUTO_FRAME_ARG (arg
, prop
, tem
);
4582 x_set_frame_parameters (f
, arg
);
4587 #if !defined (HAVE_X_WINDOWS) && defined (NoValue)
4590 * XParseGeometry parses strings of the form
4591 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
4592 * width, height, xoffset, and yoffset are unsigned integers.
4593 * Example: "=80x24+300-49"
4594 * The equal sign is optional.
4595 * It returns a bitmask that indicates which of the four values
4596 * were actually found in the string. For each value found,
4597 * the corresponding argument is updated; for each value
4598 * not found, the corresponding argument is left unchanged.
4602 XParseGeometry (char *string
,
4604 unsigned int *width
, unsigned int *height
)
4608 unsigned long tempWidth UNINIT
, tempHeight UNINIT
;
4609 long int tempX UNINIT
, tempY UNINIT
;
4610 char *nextCharacter
;
4612 if (string
== NULL
|| *string
== '\0')
4615 string
++; /* ignore possible '=' at beg of geometry spec */
4618 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
4620 tempWidth
= strtoul (strind
, &nextCharacter
, 10);
4621 if (strind
== nextCharacter
)
4623 strind
= nextCharacter
;
4627 if (*strind
== 'x' || *strind
== 'X')
4630 tempHeight
= strtoul (strind
, &nextCharacter
, 10);
4631 if (strind
== nextCharacter
)
4633 strind
= nextCharacter
;
4634 mask
|= HeightValue
;
4637 if (*strind
== '+' || *strind
== '-')
4641 tempX
= strtol (strind
, &nextCharacter
, 10);
4642 if (strind
== nextCharacter
)
4644 strind
= nextCharacter
;
4646 if (*strind
== '+' || *strind
== '-')
4650 tempY
= strtol (strind
, &nextCharacter
, 10);
4651 if (strind
== nextCharacter
)
4653 strind
= nextCharacter
;
4658 /* If strind isn't at the end of the string then it's an invalid
4659 geometry specification. */
4661 if (*strind
!= '\0')
4665 *x
= clip_to_bounds (INT_MIN
, tempX
, INT_MAX
);
4667 *y
= clip_to_bounds (INT_MIN
, tempY
, INT_MAX
);
4668 if (mask
& WidthValue
)
4669 *width
= min (tempWidth
, UINT_MAX
);
4670 if (mask
& HeightValue
)
4671 *height
= min (tempHeight
, UINT_MAX
);
4675 #endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
4678 /* NS used to define x-parse-geometry in ns-win.el, but that confused
4679 make-docfile: the documentation string in ns-win.el was used for
4680 x-parse-geometry even in non-NS builds.
4682 With two definitions of x-parse-geometry in this file, various
4683 things still get confused (eg M-x apropos documentation), so that
4684 it is best if the two definitions just share the same doc-string.
4686 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
4687 doc
: /* Parse a display geometry string STRING.
4688 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4689 The properties returned may include `top', `left', `height', and `width'.
4690 For X, the value of `left' or `top' may be an integer,
4691 or a list (+ N) meaning N pixels relative to top/left corner,
4692 or a list (- N) meaning -N pixels relative to bottom/right corner.
4693 On Nextstep, this just calls `ns-parse-geometry'. */)
4694 (Lisp_Object string
)
4697 unsigned int width
, height
;
4700 CHECK_STRING (string
);
4703 if (strchr (SSDATA (string
), ' ') != NULL
)
4704 return call1 (Qns_parse_geometry
, string
);
4706 geometry
= XParseGeometry (SSDATA (string
),
4707 &x
, &y
, &width
, &height
);
4709 if (geometry
& XValue
)
4711 Lisp_Object element
;
4713 if (x
>= 0 && (geometry
& XNegative
))
4714 element
= list3 (Qleft
, Qminus
, make_number (-x
));
4715 else if (x
< 0 && ! (geometry
& XNegative
))
4716 element
= list3 (Qleft
, Qplus
, make_number (x
));
4718 element
= Fcons (Qleft
, make_number (x
));
4719 result
= Fcons (element
, result
);
4722 if (geometry
& YValue
)
4724 Lisp_Object element
;
4726 if (y
>= 0 && (geometry
& YNegative
))
4727 element
= list3 (Qtop
, Qminus
, make_number (-y
));
4728 else if (y
< 0 && ! (geometry
& YNegative
))
4729 element
= list3 (Qtop
, Qplus
, make_number (y
));
4731 element
= Fcons (Qtop
, make_number (y
));
4732 result
= Fcons (element
, result
);
4735 if (geometry
& WidthValue
)
4736 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
4737 if (geometry
& HeightValue
)
4738 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
4744 /* Calculate the desired size and position of frame F.
4745 Return the flags saying which aspects were specified.
4747 Also set the win_gravity and size_hint_flags of F.
4749 Adjust height for toolbar if TOOLBAR_P is 1.
4751 This function does not make the coordinates positive. */
4753 #define DEFAULT_ROWS 36
4754 #define DEFAULT_COLS 80
4757 x_figure_window_size (struct frame
*f
, Lisp_Object parms
, bool toolbar_p
, int *x_width
, int *x_height
)
4759 Lisp_Object height
, width
, user_size
, top
, left
, user_position
;
4760 long window_prompting
= 0;
4761 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
4763 /* Default values if we fall through.
4764 Actually, if that happens we should get
4765 window manager prompting. */
4766 SET_FRAME_WIDTH (f
, DEFAULT_COLS
* FRAME_COLUMN_WIDTH (f
));
4767 SET_FRAME_COLS (f
, DEFAULT_COLS
);
4768 SET_FRAME_HEIGHT (f
, DEFAULT_ROWS
* FRAME_LINE_HEIGHT (f
));
4769 SET_FRAME_LINES (f
, DEFAULT_ROWS
);
4771 /* Window managers expect that if program-specified
4772 positions are not (0,0), they're intentional, not defaults. */
4776 /* Calculate a tool bar height so that the user gets a text display
4777 area of the size he specified with -g or via .Xdefaults. Later
4778 changes of the tool bar height don't change the frame size. This
4779 is done so that users can create tall Emacs frames without having
4780 to guess how tall the tool bar will get. */
4781 if (toolbar_p
&& FRAME_TOOL_BAR_LINES (f
))
4783 if (frame_default_tool_bar_height
)
4784 FRAME_TOOL_BAR_HEIGHT (f
) = frame_default_tool_bar_height
;
4789 relief
= (tool_bar_button_relief
>= 0
4790 ? tool_bar_button_relief
4791 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
4793 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
, INT_MAX
))
4794 margin
= XFASTINT (Vtool_bar_button_margin
);
4795 else if (CONSP (Vtool_bar_button_margin
)
4796 && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
), INT_MAX
))
4797 margin
= XFASTINT (XCDR (Vtool_bar_button_margin
));
4801 FRAME_TOOL_BAR_HEIGHT (f
)
4802 = DEFAULT_TOOL_BAR_IMAGE_HEIGHT
+ 2 * margin
+ 2 * relief
;
4806 /* Ensure that earlier new_width and new_height settings won't
4807 override what we specify below. */
4808 f
->new_width
= f
->new_height
= 0;
4810 height
= x_get_arg (dpyinfo
, parms
, Qheight
, 0, 0, RES_TYPE_NUMBER
);
4811 width
= x_get_arg (dpyinfo
, parms
, Qwidth
, 0, 0, RES_TYPE_NUMBER
);
4812 if (!EQ (width
, Qunbound
) || !EQ (height
, Qunbound
))
4814 if (!EQ (width
, Qunbound
))
4816 if (CONSP (width
) && EQ (XCAR (width
), Qtext_pixels
))
4818 CHECK_NUMBER (XCDR (width
));
4819 if ((XINT (XCDR (width
)) < 0 || XINT (XCDR (width
)) > INT_MAX
))
4820 xsignal1 (Qargs_out_of_range
, XCDR (width
));
4822 SET_FRAME_WIDTH (f
, XINT (XCDR (width
)));
4823 f
->inhibit_horizontal_resize
= true;
4824 *x_width
= XINT (XCDR (width
));
4828 CHECK_NUMBER (width
);
4829 if ((XINT (width
) < 0 || XINT (width
) > INT_MAX
))
4830 xsignal1 (Qargs_out_of_range
, width
);
4832 SET_FRAME_WIDTH (f
, XINT (width
) * FRAME_COLUMN_WIDTH (f
));
4836 if (!EQ (height
, Qunbound
))
4838 if (CONSP (height
) && EQ (XCAR (height
), Qtext_pixels
))
4840 CHECK_NUMBER (XCDR (height
));
4841 if ((XINT (XCDR (height
)) < 0 || XINT (XCDR (height
)) > INT_MAX
))
4842 xsignal1 (Qargs_out_of_range
, XCDR (height
));
4844 SET_FRAME_HEIGHT (f
, XINT (XCDR (height
)));
4845 f
->inhibit_vertical_resize
= true;
4846 *x_height
= XINT (XCDR (height
));
4850 CHECK_NUMBER (height
);
4851 if ((XINT (height
) < 0) || (XINT (height
) > INT_MAX
))
4852 xsignal1 (Qargs_out_of_range
, height
);
4854 SET_FRAME_HEIGHT (f
, XINT (height
) * FRAME_LINE_HEIGHT (f
));
4858 user_size
= x_get_arg (dpyinfo
, parms
, Quser_size
, 0, 0, RES_TYPE_NUMBER
);
4859 if (!NILP (user_size
) && !EQ (user_size
, Qunbound
))
4860 window_prompting
|= USSize
;
4862 window_prompting
|= PSize
;
4865 top
= x_get_arg (dpyinfo
, parms
, Qtop
, 0, 0, RES_TYPE_NUMBER
);
4866 left
= x_get_arg (dpyinfo
, parms
, Qleft
, 0, 0, RES_TYPE_NUMBER
);
4867 user_position
= x_get_arg (dpyinfo
, parms
, Quser_position
, 0, 0, RES_TYPE_NUMBER
);
4868 if (! EQ (top
, Qunbound
) || ! EQ (left
, Qunbound
))
4870 if (EQ (top
, Qminus
))
4873 window_prompting
|= YNegative
;
4875 else if (CONSP (top
) && EQ (XCAR (top
), Qminus
)
4876 && CONSP (XCDR (top
))
4877 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (top
)), INT_MAX
))
4879 f
->top_pos
= - XINT (XCAR (XCDR (top
)));
4880 window_prompting
|= YNegative
;
4882 else if (CONSP (top
) && EQ (XCAR (top
), Qplus
)
4883 && CONSP (XCDR (top
))
4884 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top
))))
4886 f
->top_pos
= XINT (XCAR (XCDR (top
)));
4888 else if (EQ (top
, Qunbound
))
4892 CHECK_TYPE_RANGED_INTEGER (int, top
);
4893 f
->top_pos
= XINT (top
);
4895 window_prompting
|= YNegative
;
4898 if (EQ (left
, Qminus
))
4901 window_prompting
|= XNegative
;
4903 else if (CONSP (left
) && EQ (XCAR (left
), Qminus
)
4904 && CONSP (XCDR (left
))
4905 && RANGED_INTEGERP (-INT_MAX
, XCAR (XCDR (left
)), INT_MAX
))
4907 f
->left_pos
= - XINT (XCAR (XCDR (left
)));
4908 window_prompting
|= XNegative
;
4910 else if (CONSP (left
) && EQ (XCAR (left
), Qplus
)
4911 && CONSP (XCDR (left
))
4912 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left
))))
4914 f
->left_pos
= XINT (XCAR (XCDR (left
)));
4916 else if (EQ (left
, Qunbound
))
4920 CHECK_TYPE_RANGED_INTEGER (int, left
);
4921 f
->left_pos
= XINT (left
);
4922 if (f
->left_pos
< 0)
4923 window_prompting
|= XNegative
;
4926 if (!NILP (user_position
) && ! EQ (user_position
, Qunbound
))
4927 window_prompting
|= USPosition
;
4929 window_prompting
|= PPosition
;
4932 if (window_prompting
& XNegative
)
4934 if (window_prompting
& YNegative
)
4935 f
->win_gravity
= SouthEastGravity
;
4937 f
->win_gravity
= NorthEastGravity
;
4941 if (window_prompting
& YNegative
)
4942 f
->win_gravity
= SouthWestGravity
;
4944 f
->win_gravity
= NorthWestGravity
;
4947 f
->size_hint_flags
= window_prompting
;
4949 return window_prompting
;
4954 #endif /* HAVE_WINDOW_SYSTEM */
4957 frame_make_pointer_invisible (struct frame
*f
)
4959 if (! NILP (Vmake_pointer_invisible
))
4961 if (f
&& FRAME_LIVE_P (f
) && !f
->pointer_invisible
4962 && FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook
)
4965 FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook (f
, 1);
4966 f
->pointer_invisible
= 1;
4972 frame_make_pointer_visible (struct frame
*f
)
4974 /* We don't check Vmake_pointer_invisible here in case the
4975 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4976 if (f
&& FRAME_LIVE_P (f
) && f
->pointer_invisible
&& f
->mouse_moved
4977 && FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook
)
4979 FRAME_TERMINAL (f
)->toggle_invisible_pointer_hook (f
, 0);
4980 f
->pointer_invisible
= 0;
4984 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p
,
4985 Sframe_pointer_visible_p
, 0, 1, 0,
4986 doc
: /* Return t if the mouse pointer displayed on FRAME is visible.
4987 Otherwise it returns nil. FRAME omitted or nil means the
4988 selected frame. This is useful when `make-pointer-invisible' is set. */)
4991 return decode_any_frame (frame
)->pointer_invisible
? Qnil
: Qt
;
4996 /***********************************************************************
4998 ***********************************************************************/
5000 #ifdef HAVE_WINDOW_SYSTEM
5002 # if (defined HAVE_NS \
5003 || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR)))
5005 free_monitors (struct MonitorInfo
*monitors
, int n_monitors
)
5008 for (i
= 0; i
< n_monitors
; ++i
)
5009 xfree (monitors
[i
].name
);
5015 make_monitor_attribute_list (struct MonitorInfo
*monitors
,
5017 int primary_monitor
,
5018 Lisp_Object monitor_frames
,
5021 Lisp_Object attributes_list
= Qnil
;
5022 Lisp_Object primary_monitor_attributes
= Qnil
;
5025 for (i
= 0; i
< n_monitors
; ++i
)
5027 Lisp_Object geometry
, workarea
, attributes
= Qnil
;
5028 struct MonitorInfo
*mi
= &monitors
[i
];
5030 if (mi
->geom
.width
== 0) continue;
5032 workarea
= list4i (mi
->work
.x
, mi
->work
.y
,
5033 mi
->work
.width
, mi
->work
.height
);
5034 geometry
= list4i (mi
->geom
.x
, mi
->geom
.y
,
5035 mi
->geom
.width
, mi
->geom
.height
);
5036 attributes
= Fcons (Fcons (Qsource
, build_string (source
)),
5038 attributes
= Fcons (Fcons (Qframes
, AREF (monitor_frames
, i
)),
5040 attributes
= Fcons (Fcons (Qmm_size
,
5041 list2i (mi
->mm_width
, mi
->mm_height
)),
5043 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
5044 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
5046 attributes
= Fcons (Fcons (Qname
, make_string (mi
->name
,
5047 strlen (mi
->name
))),
5050 if (i
== primary_monitor
)
5051 primary_monitor_attributes
= attributes
;
5053 attributes_list
= Fcons (attributes
, attributes_list
);
5056 if (!NILP (primary_monitor_attributes
))
5057 attributes_list
= Fcons (primary_monitor_attributes
, attributes_list
);
5058 return attributes_list
;
5061 #endif /* HAVE_WINDOW_SYSTEM */
5064 /***********************************************************************
5066 ***********************************************************************/
5069 syms_of_frame (void)
5071 DEFSYM (Qframep
, "framep");
5072 DEFSYM (Qframe_live_p
, "frame-live-p");
5073 DEFSYM (Qframe_windows_min_size
, "frame-windows-min-size");
5074 DEFSYM (Qwindow__pixel_to_total
, "window--pixel-to-total");
5075 DEFSYM (Qexplicit_name
, "explicit-name");
5076 DEFSYM (Qheight
, "height");
5077 DEFSYM (Qicon
, "icon");
5078 DEFSYM (Qminibuffer
, "minibuffer");
5079 DEFSYM (Qundecorated
, "undecorated");
5080 DEFSYM (Qparent_frame
, "parent-frame");
5081 DEFSYM (Qskip_taskbar
, "skip-taskbar");
5082 DEFSYM (Qno_focus_on_map
, "no-focus-on-map");
5083 DEFSYM (Qno_accept_focus
, "no-accept-focus");
5084 DEFSYM (Qz_group
, "z-group");
5085 DEFSYM (Qoverride_redirect
, "override-redirect");
5086 DEFSYM (Qdelete_before
, "delete-before");
5087 DEFSYM (Qmodeline
, "modeline");
5088 DEFSYM (Qonly
, "only");
5089 DEFSYM (Qnone
, "none");
5090 DEFSYM (Qwidth
, "width");
5091 DEFSYM (Qtext_pixels
, "text-pixels");
5092 DEFSYM (Qgeometry
, "geometry");
5093 DEFSYM (Qicon_left
, "icon-left");
5094 DEFSYM (Qicon_top
, "icon-top");
5095 DEFSYM (Qtooltip
, "tooltip");
5096 DEFSYM (Quser_position
, "user-position");
5097 DEFSYM (Quser_size
, "user-size");
5098 DEFSYM (Qwindow_id
, "window-id");
5099 #ifdef HAVE_X_WINDOWS
5100 DEFSYM (Qouter_window_id
, "outer-window-id");
5102 DEFSYM (Qparent_id
, "parent-id");
5104 DEFSYM (Qw32
, "w32");
5107 DEFSYM (Qvisible
, "visible");
5108 DEFSYM (Qbuffer_predicate
, "buffer-predicate");
5109 DEFSYM (Qbuffer_list
, "buffer-list");
5110 DEFSYM (Qburied_buffer_list
, "buried-buffer-list");
5111 DEFSYM (Qdisplay_type
, "display-type");
5112 DEFSYM (Qbackground_mode
, "background-mode");
5113 DEFSYM (Qnoelisp
, "noelisp");
5114 DEFSYM (Qtty_color_mode
, "tty-color-mode");
5115 DEFSYM (Qtty
, "tty");
5116 DEFSYM (Qtty_type
, "tty-type");
5118 DEFSYM (Qface_set_after_frame_default
, "face-set-after-frame-default");
5120 DEFSYM (Qfullwidth
, "fullwidth");
5121 DEFSYM (Qfullheight
, "fullheight");
5122 DEFSYM (Qfullboth
, "fullboth");
5123 DEFSYM (Qmaximized
, "maximized");
5124 DEFSYM (Qx_resource_name
, "x-resource-name");
5125 DEFSYM (Qx_frame_parameter
, "x-frame-parameter");
5127 DEFSYM (Qworkarea
, "workarea");
5128 DEFSYM (Qmm_size
, "mm-size");
5129 DEFSYM (Qframes
, "frames");
5130 DEFSYM (Qsource
, "source");
5132 DEFSYM (Qouter_edges
, "outer-edges");
5133 DEFSYM (Qouter_position
, "outer-position");
5134 DEFSYM (Qouter_size
, "outer-size");
5135 DEFSYM (Qnative_edges
, "native-edges");
5136 DEFSYM (Qinner_edges
, "inner-edges");
5137 DEFSYM (Qexternal_border_size
, "external-border-size");
5138 DEFSYM (Qtitle_bar_size
, "title-bar-size");
5139 DEFSYM (Qmenu_bar_external
, "menu-bar-external");
5140 DEFSYM (Qmenu_bar_size
, "menu-bar-size");
5141 DEFSYM (Qtool_bar_external
, "tool-bar-external");
5142 DEFSYM (Qtool_bar_size
, "tool-bar-size");
5143 /* The following are used for frame_size_history. */
5144 DEFSYM (Qadjust_frame_size_1
, "adjust-frame-size-1");
5145 DEFSYM (Qadjust_frame_size_2
, "adjust-frame-size-2");
5146 DEFSYM (Qadjust_frame_size_3
, "adjust-frame-size-3");
5147 DEFSYM (Qx_set_frame_parameters
, "x-set-frame-parameters");
5148 DEFSYM (QEmacsFrameResize
, "EmacsFrameResize");
5149 DEFSYM (Qset_frame_size
, "set-frame-size");
5150 DEFSYM (Qframe_inhibit_resize
, "frame-inhibit-resize");
5151 DEFSYM (Qx_set_fullscreen
, "x-set-fullscreen");
5152 DEFSYM (Qx_check_fullscreen
, "x-check-fullscreen");
5153 DEFSYM (Qxg_frame_resized
, "xg-frame-resized");
5154 DEFSYM (Qxg_frame_set_char_size_1
, "xg-frame-set-char-size-1");
5155 DEFSYM (Qxg_frame_set_char_size_2
, "xg-frame-set-char-size-2");
5156 DEFSYM (Qxg_frame_set_char_size_3
, "xg-frame-set-char-size-3");
5157 DEFSYM (Qx_set_window_size_1
, "x-set-window-size-1");
5158 DEFSYM (Qx_set_window_size_2
, "x-set-window-size-2");
5159 DEFSYM (Qx_set_window_size_3
, "x-set-window-size-3");
5160 DEFSYM (Qxg_change_toolbar_position
, "xg-change-toolbar-position");
5161 DEFSYM (Qx_net_wm_state
, "x-net-wm-state");
5162 DEFSYM (Qx_handle_net_wm_state
, "x-handle-net-wm-state");
5163 DEFSYM (Qtb_size_cb
, "tb-size-cb");
5164 DEFSYM (Qupdate_frame_tool_bar
, "update-frame-tool-bar");
5165 DEFSYM (Qfree_frame_tool_bar
, "free-frame-tool-bar");
5166 DEFSYM (Qx_set_menu_bar_lines
, "x-set-menu-bar-lines");
5167 DEFSYM (Qchange_frame_size
, "change-frame-size");
5168 DEFSYM (Qxg_frame_set_char_size
, "xg-frame-set-char-size");
5169 DEFSYM (Qset_window_configuration
, "set-window-configuration");
5170 DEFSYM (Qx_create_frame_1
, "x-create-frame-1");
5171 DEFSYM (Qx_create_frame_2
, "x-create-frame-2");
5172 DEFSYM (Qterminal_frame
, "terminal-frame");
5175 DEFSYM (Qns_parse_geometry
, "ns-parse-geometry");
5178 DEFSYM (Qalpha
, "alpha");
5179 DEFSYM (Qauto_lower
, "auto-lower");
5180 DEFSYM (Qauto_raise
, "auto-raise");
5181 DEFSYM (Qborder_color
, "border-color");
5182 DEFSYM (Qborder_width
, "border-width");
5183 DEFSYM (Qouter_border_width
, "outer-border-width");
5184 DEFSYM (Qbottom_divider_width
, "bottom-divider-width");
5185 DEFSYM (Qcursor_color
, "cursor-color");
5186 DEFSYM (Qcursor_type
, "cursor-type");
5187 DEFSYM (Qfont_backend
, "font-backend");
5188 DEFSYM (Qfullscreen
, "fullscreen");
5189 DEFSYM (Qhorizontal_scroll_bars
, "horizontal-scroll-bars");
5190 DEFSYM (Qicon_name
, "icon-name");
5191 DEFSYM (Qicon_type
, "icon-type");
5192 DEFSYM (Qinternal_border_width
, "internal-border-width");
5193 DEFSYM (Qleft_fringe
, "left-fringe");
5194 DEFSYM (Qline_spacing
, "line-spacing");
5195 DEFSYM (Qmenu_bar_lines
, "menu-bar-lines");
5196 DEFSYM (Qupdate_frame_menubar
, "update-frame-menubar");
5197 DEFSYM (Qfree_frame_menubar_1
, "free-frame-menubar-1");
5198 DEFSYM (Qfree_frame_menubar_2
, "free-frame-menubar-2");
5199 DEFSYM (Qmouse_color
, "mouse-color");
5200 DEFSYM (Qname
, "name");
5201 DEFSYM (Qright_divider_width
, "right-divider-width");
5202 DEFSYM (Qright_fringe
, "right-fringe");
5203 DEFSYM (Qscreen_gamma
, "screen-gamma");
5204 DEFSYM (Qscroll_bar_background
, "scroll-bar-background");
5205 DEFSYM (Qscroll_bar_foreground
, "scroll-bar-foreground");
5206 DEFSYM (Qscroll_bar_height
, "scroll-bar-height");
5207 DEFSYM (Qscroll_bar_width
, "scroll-bar-width");
5208 DEFSYM (Qsticky
, "sticky");
5209 DEFSYM (Qtitle
, "title");
5210 DEFSYM (Qtool_bar_lines
, "tool-bar-lines");
5211 DEFSYM (Qtool_bar_position
, "tool-bar-position");
5212 DEFSYM (Qunsplittable
, "unsplittable");
5213 DEFSYM (Qvertical_scroll_bars
, "vertical-scroll-bars");
5214 DEFSYM (Qvisibility
, "visibility");
5215 DEFSYM (Qwait_for_wm
, "wait-for-wm");
5216 DEFSYM (Qinhibit_double_buffering
, "inhibit-double-buffering");
5217 DEFSYM (Qno_other_frame
, "no-other-frame");
5218 DEFSYM (Qbelow
, "below");
5219 DEFSYM (Qabove_suspended
, "above-suspended");
5220 DEFSYM (Qmin_width
, "min-width");
5221 DEFSYM (Qmin_height
, "min-height");
5222 DEFSYM (Qmouse_wheel_frame
, "mouse-wheel-frame");
5227 for (i
= 0; i
< ARRAYELTS (frame_parms
); i
++)
5229 Lisp_Object v
= (frame_parms
[i
].sym
< 0
5230 ? intern_c_string (frame_parms
[i
].name
)
5231 : builtin_lisp_symbol (frame_parms
[i
].sym
));
5232 Fput (v
, Qx_frame_parameter
, make_number (i
));
5236 #ifdef HAVE_WINDOW_SYSTEM
5237 DEFVAR_LISP ("x-resource-name", Vx_resource_name
,
5238 doc
: /* The name Emacs uses to look up X resources.
5239 `x-get-resource' uses this as the first component of the instance name
5240 when requesting resource values.
5241 Emacs initially sets `x-resource-name' to the name under which Emacs
5242 was invoked, or to the value specified with the `-name' or `-rn'
5243 switches, if present.
5245 It may be useful to bind this variable locally around a call
5246 to `x-get-resource'. See also the variable `x-resource-class'. */);
5247 Vx_resource_name
= Qnil
;
5249 DEFVAR_LISP ("x-resource-class", Vx_resource_class
,
5250 doc
: /* The class Emacs uses to look up X resources.
5251 `x-get-resource' uses this as the first component of the instance class
5252 when requesting resource values.
5254 Emacs initially sets `x-resource-class' to "Emacs".
5256 Setting this variable permanently is not a reasonable thing to do,
5257 but binding this variable locally around a call to `x-get-resource'
5258 is a reasonable practice. See also the variable `x-resource-name'. */);
5259 Vx_resource_class
= build_string (EMACS_CLASS
);
5261 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit
,
5262 doc
: /* The lower limit of the frame opacity (alpha transparency).
5263 The value should range from 0 (invisible) to 100 (completely opaque).
5264 You can also use a floating number between 0.0 and 1.0. */);
5265 Vframe_alpha_lower_limit
= make_number (20);
5268 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist
,
5269 doc
: /* Alist of default values for frame creation.
5270 These may be set in your init file, like this:
5271 (setq default-frame-alist \\='((width . 80) (height . 55) (menu-bar-lines . 1)))
5272 These override values given in window system configuration data,
5273 including X Windows' defaults database.
5274 For values specific to the first Emacs frame, see `initial-frame-alist'.
5275 For window-system specific values, see `window-system-default-frame-alist'.
5276 For values specific to the separate minibuffer frame, see
5277 `minibuffer-frame-alist'.
5278 The `menu-bar-lines' element of the list controls whether new frames
5279 have menu bars; `menu-bar-mode' works by altering this element.
5280 Setting this variable does not affect existing frames, only new ones. */);
5281 Vdefault_frame_alist
= Qnil
;
5283 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars
,
5284 doc
: /* Default position of vertical scroll bars on this window-system. */);
5285 #ifdef HAVE_WINDOW_SYSTEM
5286 #if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
5287 /* MS-Windows, macOS, and GTK have scroll bars on the right by
5289 Vdefault_frame_scroll_bars
= Qright
;
5291 Vdefault_frame_scroll_bars
= Qleft
;
5294 Vdefault_frame_scroll_bars
= Qnil
;
5297 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
5298 scroll_bar_adjust_thumb_portion_p
,
5299 doc
: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
5300 Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards
5301 even if the end of the buffer is shown (i.e. overscrolling).
5302 Set to nil if you want the thumb to be at the bottom when the end of the buffer
5303 is shown. Also, the thumb fills the whole scroll bar when the entire buffer
5304 is visible. In this case you can not overscroll. */);
5305 scroll_bar_adjust_thumb_portion_p
= 1;
5307 DEFVAR_LISP ("terminal-frame", Vterminal_frame
,
5308 doc
: /* The initial frame-object, which represents Emacs's stdout. */);
5310 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function
,
5311 doc
: /* If non-nil, function to transform normal value of `mouse-position'.
5312 `mouse-position' and `mouse-pixel-position' call this function, passing their
5313 usual return value as argument, and return whatever this function returns.
5314 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
5315 which need to do mouse handling at the Lisp level. */);
5316 Vmouse_position_function
= Qnil
;
5318 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight
,
5319 doc
: /* If non-nil, clickable text is highlighted when mouse is over it.
5320 If the value is an integer, highlighting is only shown after moving the
5321 mouse, while keyboard input turns off the highlight even when the mouse
5322 is over the clickable text. However, the mouse shape still indicates
5323 when the mouse is over clickable text. */);
5324 Vmouse_highlight
= Qt
;
5326 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible
,
5327 doc
: /* If non-nil, make pointer invisible while typing.
5328 The pointer becomes visible again when the mouse is moved. */);
5329 Vmake_pointer_invisible
= Qt
;
5331 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook
,
5332 doc
: /* Normal hook run when a frame gains input focus.
5333 The frame gaining focus is selected at the time this hook is run. */);
5334 Vfocus_in_hook
= Qnil
;
5336 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook
,
5337 doc
: /* Normal hook run when all frames lost input focus. */);
5338 Vfocus_out_hook
= Qnil
;
5340 DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions
,
5341 doc
: /* Functions run after a frame was moved.
5342 The functions are run with one arg, the frame that moved. */);
5343 Vmove_frame_functions
= Qnil
;
5345 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions
,
5346 doc
: /* Functions run before deleting a frame.
5347 The functions are run with one arg, the frame to be deleted.
5350 Note that functions in this list may be called just before the frame is
5351 actually deleted, or some time later (or even both when an earlier function
5352 in `delete-frame-functions' (indirectly) calls `delete-frame'
5354 Vdelete_frame_functions
= Qnil
;
5355 DEFSYM (Qdelete_frame_functions
, "delete-frame-functions");
5357 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode
,
5358 doc
: /* Non-nil if Menu-Bar mode is enabled.
5359 See the command `menu-bar-mode' for a description of this minor mode.
5360 Setting this variable directly does not take effect;
5361 either customize it (see the info node `Easy Customization')
5362 or call the function `menu-bar-mode'. */);
5363 Vmenu_bar_mode
= Qt
;
5365 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode
,
5366 doc
: /* Non-nil if Tool-Bar mode is enabled.
5367 See the command `tool-bar-mode' for a description of this minor mode.
5368 Setting this variable directly does not take effect;
5369 either customize it (see the info node `Easy Customization')
5370 or call the function `tool-bar-mode'. */);
5371 #ifdef HAVE_WINDOW_SYSTEM
5372 Vtool_bar_mode
= Qt
;
5374 Vtool_bar_mode
= Qnil
;
5377 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame
,
5378 doc
: /* Minibufferless frames use this frame's minibuffer.
5379 Emacs cannot create minibufferless frames unless this is set to an
5380 appropriate surrogate.
5382 Emacs consults this variable only when creating minibufferless
5383 frames; once the frame is created, it sticks with its assigned
5384 minibuffer, no matter what this variable is set to. This means that
5385 this variable doesn't necessarily say anything meaningful about the
5386 current set of frames, or where the minibuffer is currently being
5389 This variable is local to the current terminal and cannot be buffer-local. */);
5391 DEFVAR_LISP ("focus-follows-mouse", focus_follows_mouse
,
5392 doc
: /* Non-nil if window system changes focus when you move the mouse.
5393 You should set this variable to tell Emacs how your window manager
5394 handles focus, since there is no way in general for Emacs to find out
5397 There are three meaningful values:
5399 - The default nil should be used when your window manager follows a
5400 "click-to-focus" policy where you have to click the mouse inside of a
5401 frame in order for that frame to get focus.
5403 - The value t should be used when your window manager has the focus
5404 automatically follow the position of the mouse pointer but a window
5405 that gains focus is not raised automatically.
5407 - The value `auto-raise' should be used when your window manager has the
5408 focus automatically follow the position of the mouse pointer and a
5409 window that gains focus is raised automatically.
5411 If this option is non-nil, Emacs moves the mouse pointer to the frame
5412 selected by `select-frame-set-input-focus'. This function is used by a
5413 number of commands like, for example, `other-frame' and `pop-to-buffer'.
5414 If this option is nil and your focus follows mouse window manager does
5415 not autonomously move the mouse pointer to the newly selected frame, the
5416 previously selected window manager window might get reselected instead
5419 The distinction between the values t and `auto-raise' is not needed for
5420 "normal" frames because the window manager takes care of raising them.
5421 Setting this to `auto-raise' will, however, override the standard
5422 behavior of a window manager that does not automatically raise the frame
5423 that gets focus. Setting this to `auto-raise' is also necessary to
5424 automatically raise child frames which are usually left alone by the
5427 Note that this option does not distinguish "sloppy" focus (where the
5428 frame that previously had focus retains focus as long as the mouse
5429 pointer does not move into another window manager window) from "strict"
5430 focus (where a frame immediately loses focus when it's left by the mouse
5433 In order to extend a "focus follows mouse" policy to individual Emacs
5434 windows, customize the variable `mouse-autoselect-window'. */);
5435 focus_follows_mouse
= Qnil
;
5437 DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise
,
5438 doc
: /* Non-nil means resize frames pixelwise.
5439 If this option is nil, resizing a frame rounds its sizes to the frame's
5440 current values of `frame-char-height' and `frame-char-width'. If this
5441 is non-nil, no rounding occurs, hence frame sizes can increase/decrease
5444 With some window managers you may have to set this to non-nil in order
5445 to set the size of a frame in pixels, to maximize frames or to make them
5446 fullscreen. To resize your initial frame pixelwise, set this option to
5447 a non-nil value in your init file. */);
5448 frame_resize_pixelwise
= 0;
5450 DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize
,
5451 doc
: /* Whether frames should be resized implicitly.
5452 If this option is nil, setting font, menu bar, tool bar, internal
5453 borders, fringes or scroll bars of a specific frame may resize the frame
5454 in order to preserve the number of columns or lines it displays. If
5455 this option is t, no such resizing is done. Note that the size of
5456 fullscreen and maximized frames, the height of fullheight frames and the
5457 width of fullwidth frames never change implicitly.
5459 The value of this option can be also be a list of frame parameters. In
5460 this case, resizing is inhibited when changing a parameter that appears
5461 in that list. The parameters currently handled by this option include
5462 `font', `font-backend', `internal-border-width', `menu-bar-lines' and
5465 Changing any of the parameters `scroll-bar-width', `scroll-bar-height',
5466 `vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and
5467 `right-fringe' is handled as if the frame contained just one live
5468 window. This means, for example, that removing vertical scroll bars on
5469 a frame containing several side by side windows will shrink the frame
5470 width by the width of one scroll bar provided this option is nil and
5471 keep it unchanged if this option is either t or a list containing
5472 `vertical-scroll-bars'.
5474 The default value is \\='(tool-bar-lines) on Lucid, Motif and Windows
5475 \(which means that adding/removing a tool bar does not change the frame
5476 height), nil on all other window systems including GTK+ (which means
5477 that changing any of the parameters listed above may change the size of
5478 the frame), and t otherwise (which means the frame size never changes
5479 implicitly when there's no window system support).
5481 Note that when a frame is not large enough to accommodate a change of
5482 any of the parameters listed above, Emacs may try to enlarge the frame
5483 even if this option is non-nil. */);
5484 #if defined (HAVE_WINDOW_SYSTEM)
5485 #if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI)
5486 frame_inhibit_implied_resize
= list1 (Qtool_bar_lines
);
5488 frame_inhibit_implied_resize
= Qnil
;
5491 frame_inhibit_implied_resize
= Qt
;
5494 DEFVAR_LISP ("frame-size-history", frame_size_history
,
5495 doc
: /* History of frame size adjustments.
5496 If non-nil, list recording frame size adjustment. Adjustments are
5497 recorded only if the first element of this list is a positive number.
5498 Adding an adjustment decrements that number by one.
5500 The remaining elements are the adjustments. Each adjustment is a list
5501 of four elements `frame', `function', `sizes' and `more'. `frame' is
5502 the affected frame and `function' the invoking function. `sizes' is
5503 usually a list of four elements `old-width', `old-height', `new-width'
5504 and `new-height' representing the old and new sizes recorded/requested
5505 by `function'. `more' is a list with additional information.
5507 The function `frame--size-history' displays the value of this variable
5508 in a more readable form. */);
5509 frame_size_history
= Qnil
;
5511 DEFVAR_BOOL ("tooltip-reuse-hidden-frame", tooltip_reuse_hidden_frame
,
5512 doc
: /* Non-nil means reuse hidden tooltip frames.
5513 When this is nil, delete a tooltip frame when hiding the associated
5514 tooltip. When this is non-nil, make the tooltip frame invisible only,
5515 so it can be reused when the next tooltip is shown.
5517 Setting this to non-nil may drastically reduce the consing overhead
5518 incurred by creating new tooltip frames. However, a value of non-nil
5519 means also that intermittent changes of faces or `default-frame-alist'
5520 are not applied when showing a tooltip in a reused frame.
5522 This variable is effective only with the X toolkit (and there only when
5523 Gtk+ tooltips are not used) and on Windows. */);
5524 tooltip_reuse_hidden_frame
= false;
5526 staticpro (&Vframe_list
);
5529 defsubr (&Sframe_live_p
);
5530 defsubr (&Swindow_system
);
5531 defsubr (&Sframe_windows_min_size
);
5532 defsubr (&Smake_terminal_frame
);
5533 defsubr (&Shandle_switch_frame
);
5534 defsubr (&Sselect_frame
);
5535 defsubr (&Sselected_frame
);
5536 defsubr (&Sframe_list
);
5537 defsubr (&Sframe_parent
);
5538 defsubr (&Sframe_ancestor_p
);
5539 defsubr (&Snext_frame
);
5540 defsubr (&Sprevious_frame
);
5541 defsubr (&Slast_nonminibuf_frame
);
5542 defsubr (&Sdelete_frame
);
5543 defsubr (&Smouse_position
);
5544 defsubr (&Smouse_pixel_position
);
5545 defsubr (&Sset_mouse_position
);
5546 defsubr (&Sset_mouse_pixel_position
);
5548 defsubr (&Sframe_configuration
);
5549 defsubr (&Srestore_frame_configuration
);
5551 defsubr (&Smake_frame_visible
);
5552 defsubr (&Smake_frame_invisible
);
5553 defsubr (&Siconify_frame
);
5554 defsubr (&Sframe_visible_p
);
5555 defsubr (&Svisible_frame_list
);
5556 defsubr (&Sraise_frame
);
5557 defsubr (&Slower_frame
);
5558 defsubr (&Sx_focus_frame
);
5559 defsubr (&Sframe_after_make_frame
);
5560 defsubr (&Sredirect_frame_focus
);
5561 defsubr (&Sframe_focus
);
5562 defsubr (&Sframe_parameters
);
5563 defsubr (&Sframe_parameter
);
5564 defsubr (&Smodify_frame_parameters
);
5565 defsubr (&Sframe_char_height
);
5566 defsubr (&Sframe_char_width
);
5567 defsubr (&Sframe_pixel_height
);
5568 defsubr (&Sframe_pixel_width
);
5569 defsubr (&Sframe_text_cols
);
5570 defsubr (&Sframe_text_lines
);
5571 defsubr (&Sframe_total_cols
);
5572 defsubr (&Sframe_total_lines
);
5573 defsubr (&Sframe_text_width
);
5574 defsubr (&Sframe_text_height
);
5575 defsubr (&Sscroll_bar_width
);
5576 defsubr (&Sscroll_bar_height
);
5577 defsubr (&Sfringe_width
);
5578 defsubr (&Sborder_width
);
5579 defsubr (&Sright_divider_width
);
5580 defsubr (&Sbottom_divider_width
);
5581 defsubr (&Stool_bar_pixel_width
);
5582 defsubr (&Sset_frame_height
);
5583 defsubr (&Sset_frame_width
);
5584 defsubr (&Sset_frame_size
);
5585 defsubr (&Sframe_position
);
5586 defsubr (&Sset_frame_position
);
5587 defsubr (&Sframe_pointer_visible_p
);
5589 #ifdef HAVE_WINDOW_SYSTEM
5590 defsubr (&Sx_get_resource
);
5591 defsubr (&Sx_parse_geometry
);