Use AUTO_CONS instead of SCOPED_CONS, etc.
[emacs.git] / src / frame.c
blobd0527bf2a9c9f95c33c38f230122df6181ac7c0a
1 /* Generic frame functions.
3 Copyright (C) 1993-1995, 1997, 1999-2014 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <limits.h>
26 #include <c-ctype.h>
28 #include "lisp.h"
29 #include "character.h"
31 #ifdef HAVE_WINDOW_SYSTEM
32 #include TERM_HEADER
33 #endif /* HAVE_WINDOW_SYSTEM */
35 #include "buffer.h"
36 /* These help us bind and responding to switch-frame events. */
37 #include "commands.h"
38 #include "keyboard.h"
39 #include "frame.h"
40 #include "blockinput.h"
41 #include "termchar.h"
42 #include "termhooks.h"
43 #include "dispextern.h"
44 #include "window.h"
45 #include "font.h"
46 #ifdef HAVE_WINDOW_SYSTEM
47 #include "fontset.h"
48 #endif
49 #include "cm.h"
50 #ifdef MSDOS
51 #include "msdos.h"
52 #include "dosfns.h"
53 #endif
54 #ifdef USE_X_TOOLKIT
55 #include "widget.h"
56 #endif
58 #ifdef HAVE_NS
59 Lisp_Object Qns_parse_geometry;
60 #endif
62 Lisp_Object Qframep, Qframe_live_p;
63 Lisp_Object Qicon, Qmodeline;
64 Lisp_Object Qonly, Qnone;
65 Lisp_Object Qx, Qw32, Qpc, Qns;
66 Lisp_Object Qvisible;
67 Lisp_Object Qdisplay_type;
68 static Lisp_Object Qbackground_mode;
69 Lisp_Object Qnoelisp;
71 static Lisp_Object Qx_frame_parameter;
72 Lisp_Object Qx_resource_name;
73 Lisp_Object Qterminal;
75 /* Frame parameters (set or reported). */
77 Lisp_Object Qauto_raise, Qauto_lower;
78 Lisp_Object Qborder_color, Qborder_width;
79 Lisp_Object Qcursor_color, Qcursor_type;
80 Lisp_Object Qheight, Qwidth;
81 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
82 Lisp_Object Qtooltip;
83 Lisp_Object Qinternal_border_width;
84 Lisp_Object Qright_divider_width, Qbottom_divider_width;
85 Lisp_Object Qmouse_color;
86 Lisp_Object Qminibuffer;
87 Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
88 Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars;
89 Lisp_Object Qvisibility;
90 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
91 Lisp_Object Qscreen_gamma;
92 Lisp_Object Qline_spacing;
93 static Lisp_Object Quser_position, Quser_size;
94 Lisp_Object Qwait_for_wm;
95 static Lisp_Object Qwindow_id;
96 #ifdef HAVE_X_WINDOWS
97 static Lisp_Object Qouter_window_id;
98 #endif
99 Lisp_Object Qparent_id;
100 Lisp_Object Qtitle, Qname;
101 static Lisp_Object Qexplicit_name;
102 Lisp_Object Qunsplittable;
103 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
104 Lisp_Object Qleft_fringe, Qright_fringe;
105 Lisp_Object Qbuffer_predicate;
106 static Lisp_Object Qbuffer_list, Qburied_buffer_list;
107 Lisp_Object Qtty_color_mode;
108 Lisp_Object Qtty, Qtty_type;
110 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
111 Lisp_Object Qsticky;
112 Lisp_Object Qfont_backend;
113 Lisp_Object Qalpha;
115 Lisp_Object Qface_set_after_frame_default;
117 static Lisp_Object Qfocus_in_hook;
118 static Lisp_Object Qfocus_out_hook;
119 static Lisp_Object Qdelete_frame_functions;
120 static Lisp_Object Qframe_windows_min_size;
121 static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
123 /* The currently selected frame. */
125 Lisp_Object selected_frame;
127 /* A frame which is not just a mini-buffer, or NULL if there are no such
128 frames. This is usually the most recent such frame that was selected. */
130 static struct frame *last_nonminibuf_frame;
132 /* False means there are no visible garbaged frames. */
133 bool frame_garbaged;
135 #ifdef HAVE_WINDOW_SYSTEM
136 static void x_report_frame_params (struct frame *, Lisp_Object *);
137 #endif
139 /* These setters are used only in this file, so they can be private. */
140 static void
141 fset_buffer_predicate (struct frame *f, Lisp_Object val)
143 f->buffer_predicate = val;
145 static void
146 fset_minibuffer_window (struct frame *f, Lisp_Object val)
148 f->minibuffer_window = val;
151 struct frame *
152 decode_live_frame (register Lisp_Object frame)
154 if (NILP (frame))
155 frame = selected_frame;
156 CHECK_LIVE_FRAME (frame);
157 return XFRAME (frame);
160 struct frame *
161 decode_any_frame (register Lisp_Object frame)
163 if (NILP (frame))
164 frame = selected_frame;
165 CHECK_FRAME (frame);
166 return XFRAME (frame);
169 #ifdef HAVE_WINDOW_SYSTEM
171 bool
172 window_system_available (struct frame *f)
174 return f ? FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f) : x_display_list != NULL;
177 #endif /* HAVE_WINDOW_SYSTEM */
179 struct frame *
180 decode_window_system_frame (Lisp_Object frame)
182 struct frame *f = decode_live_frame (frame);
184 if (!window_system_available (f))
185 error ("Window system frame should be used");
186 return f;
189 void
190 check_window_system (struct frame *f)
192 if (!window_system_available (f))
193 error (f ? "Window system frame should be used"
194 : "Window system is not in use or not initialized");
197 /* Return the value of frame parameter PROP in frame FRAME. */
199 Lisp_Object
200 get_frame_param (register struct frame *frame, Lisp_Object prop)
202 register Lisp_Object tem;
204 tem = Fassq (prop, frame->param_alist);
205 if (EQ (tem, Qnil))
206 return tem;
207 return Fcdr (tem);
210 /* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
211 state of frame F would be affected by a vertical (horizontal if
212 HORIZONTAL is true) resize. */
213 bool
214 frame_inhibit_resize (struct frame *f, bool horizontal)
217 return (frame_inhibit_implied_resize
218 || !NILP (get_frame_param (f, Qfullscreen))
219 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
222 static void
223 set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
225 int nlines;
226 int olines = FRAME_MENU_BAR_LINES (f);
228 /* Right now, menu bars don't work properly in minibuf-only frames;
229 most of the commands try to apply themselves to the minibuffer
230 frame itself, and get an error because you can't switch buffers
231 in or split the minibuffer window. */
232 if (FRAME_MINIBUF_ONLY_P (f))
233 return;
235 if (TYPE_RANGED_INTEGERP (int, value))
236 nlines = XINT (value);
237 else
238 nlines = 0;
240 if (nlines != olines)
242 windows_or_buffers_changed = 14;
243 FRAME_MENU_BAR_LINES (f) = nlines;
244 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
245 change_frame_size (f, FRAME_COLS (f),
246 FRAME_LINES (f) + olines - nlines,
247 0, 1, 0, 0);
251 Lisp_Object Vframe_list;
254 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
255 doc: /* Return non-nil if OBJECT is a frame.
256 Value is:
257 t for a termcap frame (a character-only terminal),
258 'x' for an Emacs frame that is really an X window,
259 'w32' for an Emacs frame that is a window on MS-Windows display,
260 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
261 'pc' for a direct-write MS-DOS frame.
262 See also `frame-live-p'. */)
263 (Lisp_Object object)
265 if (!FRAMEP (object))
266 return Qnil;
267 switch (XFRAME (object)->output_method)
269 case output_initial: /* The initial frame is like a termcap frame. */
270 case output_termcap:
271 return Qt;
272 case output_x_window:
273 return Qx;
274 case output_w32:
275 return Qw32;
276 case output_msdos_raw:
277 return Qpc;
278 case output_ns:
279 return Qns;
280 default:
281 emacs_abort ();
285 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
286 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
287 Value is nil if OBJECT is not a live frame. If object is a live
288 frame, the return value indicates what sort of terminal device it is
289 displayed on. See the documentation of `framep' for possible
290 return values. */)
291 (Lisp_Object object)
293 return ((FRAMEP (object)
294 && FRAME_LIVE_P (XFRAME (object)))
295 ? Fframep (object)
296 : Qnil);
299 DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
300 doc: /* The name of the window system that FRAME is displaying through.
301 The value is a symbol:
302 nil for a termcap frame (a character-only terminal),
303 'x' for an Emacs frame that is really an X window,
304 'w32' for an Emacs frame that is a window on MS-Windows display,
305 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
306 'pc' for a direct-write MS-DOS frame.
308 FRAME defaults to the currently selected frame.
310 Use of this function as a predicate is deprecated. Instead,
311 use `display-graphic-p' or any of the other `display-*-p'
312 predicates which report frame's specific UI-related capabilities. */)
313 (Lisp_Object frame)
315 Lisp_Object type;
316 if (NILP (frame))
317 frame = selected_frame;
319 type = Fframep (frame);
321 if (NILP (type))
322 wrong_type_argument (Qframep, frame);
324 if (EQ (type, Qt))
325 return Qnil;
326 else
327 return type;
330 static int
331 frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object pixelwise)
333 return XINT (call3 (Qframe_windows_min_size, frame, horizontal, pixelwise));
337 /* Make sure windows sizes of frame F are OK. new_width and new_height
338 are in pixels. A value of -1 means no change is requested for that
339 size (but the frame may still have to be resized to accommodate
340 windows with their minimum sizes.
342 The argument INHIBIT can assume the following values:
344 0 means to unconditionally call x_set_window_size even if sizes
345 apparently do not change. Fx_create_frame uses this to pass the
346 initial size to the window manager.
348 1 means to call x_set_window_size iff the pixel size really changes.
349 Fset_frame_size, Fset_frame_height, ... use this.
351 2 means to unconditionally call x_set_window_size provided
352 frame_inhibit_resize allows it. The menu bar code uses this.
354 3 means call x_set_window_size iff window minimum sizes must be
355 preserved or frame_inhibit_resize allows it, x_set_left_fringe,
356 x_set_scroll_bar_width, ... use this.
358 4 means call x_set_window_size iff window minimum sizes must be
359 preserved. x_set_tool_bar_lines, x_set_right_divider_width, ... use
360 this. BUT maybe the toolbar code shouldn't ....
362 5 means to never call x_set_window_size. change_frame_size uses
363 this.
365 For 2 and 3 note that if frame_inhibit_resize inhibits resizing and
366 minimum sizes are not violated no internal resizing takes place
367 either. For 2, 3, 4 and 5 note that even if no x_set_window_size
368 call is issued, window sizes may have to be adjusted in order to
369 support minimum size constraints for the frame's windows.
371 PRETEND is as for change_frame_size. */
372 void
373 adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, bool pretend)
375 int unit_width = FRAME_COLUMN_WIDTH (f);
376 int unit_height = FRAME_LINE_HEIGHT (f);
377 int old_pixel_width = FRAME_PIXEL_WIDTH (f);
378 int old_pixel_height = FRAME_PIXEL_HEIGHT (f);
379 int new_pixel_width, new_pixel_height;
380 /* The following two values are calculated from the old frame pixel
381 sizes and any "new" settings for tool bar, menu bar and internal
382 borders. We do it this way to detect whether we have to call
383 x_set_window_size as consequence of the new settings. */
384 int windows_width = FRAME_WINDOWS_WIDTH (f);
385 int windows_height = FRAME_WINDOWS_HEIGHT (f);
386 int min_windows_width, min_windows_height;
387 /* These are a bit tedious, maybe we should use a macro. */
388 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
389 int old_windows_width = WINDOW_PIXEL_WIDTH (r);
390 int old_windows_height
391 = (WINDOW_PIXEL_HEIGHT (r)
392 + (FRAME_HAS_MINIBUF_P (f)
393 ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f)))
394 : 0));
395 int new_windows_width, new_windows_height;
396 int old_text_width = FRAME_TEXT_WIDTH (f);
397 int old_text_height = FRAME_TEXT_HEIGHT (f);
398 /* If a size is < 0 use the old value. */
399 int new_text_width = (new_width >= 0) ? new_width : old_text_width;
400 int new_text_height = (new_height >= 0) ? new_height : old_text_height;
401 int new_cols, new_lines;
402 bool inhibit_horizontal, inhibit_vertical;
403 Lisp_Object frame;
405 XSETFRAME (frame, f);
406 /* The following two values are calculated from the old window body
407 sizes and any "new" settings for scroll bars, dividers, fringes and
408 margins (though the latter should have been processed already). */
409 min_windows_width = frame_windows_min_size (frame, Qt, Qt);
410 min_windows_height = frame_windows_min_size (frame, Qnil, Qt);
412 if (inhibit >= 2 && inhibit <= 4)
413 /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay
414 within the limits and either frame_inhibit_resize tells us to do
415 so or INHIBIT equals 4. */
417 inhibit_horizontal = ((windows_width >= min_windows_width
418 && (inhibit == 4 || frame_inhibit_resize (f, true)))
419 ? true : false);
420 inhibit_vertical = ((windows_height >= min_windows_height
421 && (inhibit == 4 || frame_inhibit_resize (f, false)))
422 ? true : false);
424 else
425 /* Otherwise inhibit if INHIBIT equals 5. */
426 inhibit_horizontal = inhibit_vertical = inhibit == 5;
428 new_pixel_width = ((inhibit_horizontal && (inhibit < 5))
429 ? old_pixel_width
430 : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
431 min_windows_width
432 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
433 new_windows_width = new_pixel_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
434 new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_pixel_width);
435 new_cols = new_text_width / unit_width;
437 new_pixel_height = ((inhibit_vertical && (inhibit < 5))
438 ? old_pixel_height
439 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
440 min_windows_height
441 + FRAME_TOP_MARGIN_HEIGHT (f)
442 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
443 new_windows_height = (new_pixel_height
444 - FRAME_TOP_MARGIN_HEIGHT (f)
445 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
446 new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_pixel_height);
447 new_lines = new_text_height / unit_height;
449 #ifdef HAVE_WINDOW_SYSTEM
450 if (FRAME_WINDOW_P (f)
451 && f->official
452 && ((!inhibit_horizontal
453 && (new_pixel_width != old_pixel_width
454 || inhibit == 0 || inhibit == 2))
455 || (!inhibit_vertical
456 && (new_pixel_height != old_pixel_height
457 || inhibit == 0 || inhibit == 2))))
458 /* We are either allowed to change the frame size or the minimum
459 sizes request such a change. Do not care for fixing minimum
460 sizes here, we do that eventually when we're called from
461 change_frame_size. */
463 /* Make sure we respect fullheight and fullwidth. */
464 if (inhibit_horizontal)
465 new_text_width = old_text_width;
466 else if (inhibit_vertical)
467 new_text_height = old_text_height;
469 x_set_window_size (f, 0, new_text_width, new_text_height, 1);
470 f->resized_p = true;
472 return;
474 #endif
476 if (new_text_width == old_text_width
477 && new_text_height == old_text_height
478 && new_windows_width == old_windows_width
479 && new_windows_height == old_windows_height
480 && new_pixel_width == old_pixel_width
481 && new_pixel_height == old_pixel_height)
482 /* No change. Sanitize window sizes and return. */
484 sanitize_window_sizes (frame, Qt);
485 sanitize_window_sizes (frame, Qnil);
487 return;
490 block_input ();
492 #ifdef MSDOS
493 /* We only can set screen dimensions to certain values supported
494 by our video hardware. Try to find the smallest size greater
495 or equal to the requested dimensions. */
496 dos_set_window_size (&new_lines, &new_cols);
497 #endif
499 if (new_windows_width != old_windows_width)
501 resize_frame_windows (f, new_windows_width, 1, 1);
503 /* MSDOS frames cannot PRETEND, as they change frame size by
504 manipulating video hardware. */
505 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
506 FrameCols (FRAME_TTY (f)) = new_cols;
508 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
509 if (WINDOWP (f->tool_bar_window))
511 XWINDOW (f->tool_bar_window)->pixel_width = new_windows_width;
512 XWINDOW (f->tool_bar_window)->total_cols
513 = new_windows_width / unit_width;
515 #endif
518 if (new_windows_height != old_windows_height
519 /* When the top margin has changed we have to recalculate the top
520 edges of all windows. No such calculation is necessary for the
521 left edges. */
522 || WINDOW_TOP_PIXEL_EDGE (r) != FRAME_TOP_MARGIN_HEIGHT (f))
524 resize_frame_windows (f, new_windows_height, 0, 1);
526 /* MSDOS frames cannot PRETEND, as they change frame size by
527 manipulating video hardware. */
528 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
529 FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
532 /* Assign new sizes. */
533 FRAME_TEXT_WIDTH (f) = new_text_width;
534 FRAME_TEXT_HEIGHT (f) = new_text_height;
535 FRAME_PIXEL_WIDTH (f) = new_pixel_width;
536 FRAME_PIXEL_HEIGHT (f) = new_pixel_height;
537 SET_FRAME_COLS (f, new_cols);
538 SET_FRAME_LINES (f, new_lines);
541 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
542 int text_area_x, text_area_y, text_area_width, text_area_height;
544 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
545 &text_area_height);
546 if (w->cursor.x >= text_area_x + text_area_width)
547 w->cursor.hpos = w->cursor.x = 0;
548 if (w->cursor.y >= text_area_y + text_area_height)
549 w->cursor.vpos = w->cursor.y = 0;
552 /* Sanitize window sizes. */
553 sanitize_window_sizes (frame, Qt);
554 sanitize_window_sizes (frame, Qnil);
556 adjust_frame_glyphs (f);
557 calculate_costs (f);
558 SET_FRAME_GARBAGED (f);
560 /* A frame was "resized" if one of its pixelsizes changed, even if its
561 X window wasn't resized at all. */
562 f->resized_p = (new_pixel_width != old_pixel_width
563 || new_pixel_height != old_pixel_height);
565 unblock_input ();
567 run_window_configuration_change_hook (f);
571 struct frame *
572 make_frame (bool mini_p)
574 Lisp_Object frame;
575 register struct frame *f;
576 register struct window *rw, *mw;
577 register Lisp_Object root_window;
578 register Lisp_Object mini_window;
580 f = allocate_frame ();
581 XSETFRAME (frame, f);
583 #ifdef USE_GTK
584 /* Initialize Lisp data. Note that allocate_frame initializes all
585 Lisp data to nil, so do it only for slots which should not be nil. */
586 fset_tool_bar_position (f, Qtop);
587 #endif
589 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
590 non-Lisp data, so do it only for slots which should not be zero.
591 To avoid subtle bugs and for the sake of readability, it's better to
592 initialize enum members explicitly even if their values are zero. */
593 f->wants_modeline = true;
594 f->redisplay = true;
595 f->garbaged = true;
596 f->official = false;
597 f->column_width = 1; /* !FRAME_WINDOW_P value. */
598 f->line_height = 1; /* !FRAME_WINDOW_P value. */
599 #ifdef HAVE_WINDOW_SYSTEM
600 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
601 f->horizontal_scroll_bars = false;
602 f->want_fullscreen = FULLSCREEN_NONE;
603 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
604 f->last_tool_bar_item = -1;
605 #endif
606 #endif
608 root_window = make_window ();
609 rw = XWINDOW (root_window);
610 if (mini_p)
612 mini_window = make_window ();
613 mw = XWINDOW (mini_window);
614 wset_next (rw, mini_window);
615 wset_prev (mw, root_window);
616 mw->mini = 1;
617 wset_frame (mw, frame);
618 fset_minibuffer_window (f, mini_window);
620 else
622 mini_window = Qnil;
623 wset_next (rw, Qnil);
624 fset_minibuffer_window (f, Qnil);
627 wset_frame (rw, frame);
629 /* 10 is arbitrary,
630 just so that there is "something there."
631 Correct size will be set up later with adjust_frame_size. */
633 SET_FRAME_COLS (f, 10);
634 SET_FRAME_LINES (f, 10);
635 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
636 SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
638 rw->total_cols = 10;
639 rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
640 rw->total_lines = mini_p ? 9 : 10;
641 rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
643 if (mini_p)
645 mw->top_line = rw->total_lines;
646 mw->pixel_top = rw->pixel_height;
647 mw->total_cols = rw->total_cols;
648 mw->pixel_width = rw->pixel_width;
649 mw->total_lines = 1;
650 mw->pixel_height = FRAME_LINE_HEIGHT (f);
653 /* Choose a buffer for the frame's root window. */
655 Lisp_Object buf = Fcurrent_buffer ();
657 /* If current buffer is hidden, try to find another one. */
658 if (BUFFER_HIDDEN_P (XBUFFER (buf)))
659 buf = other_buffer_safely (buf);
661 /* Use set_window_buffer, not Fset_window_buffer, and don't let
662 hooks be run by it. The reason is that the whole frame/window
663 arrangement is not yet fully initialized at this point. Windows
664 don't have the right size, glyph matrices aren't initialized
665 etc. Running Lisp functions at this point surely ends in a
666 SEGV. */
667 set_window_buffer (root_window, buf, 0, 0);
668 fset_buffer_list (f, list1 (buf));
671 if (mini_p)
673 set_window_buffer (mini_window,
674 (NILP (Vminibuffer_list)
675 ? get_minibuffer (0)
676 : Fcar (Vminibuffer_list)),
677 0, 0);
678 /* No horizontal scroll bars in minibuffers. */
679 wset_horizontal_scroll_bar (mw, Qnil);
682 fset_root_window (f, root_window);
683 fset_selected_window (f, root_window);
684 /* Make sure this window seems more recently used than
685 a newly-created, never-selected window. */
686 XWINDOW (f->selected_window)->use_time = ++window_select_count;
688 return f;
691 #ifdef HAVE_WINDOW_SYSTEM
692 /* Make a frame using a separate minibuffer window on another frame.
693 MINI_WINDOW is the minibuffer window to use. nil means use the
694 default (the global minibuffer). */
696 struct frame *
697 make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lisp_Object display)
699 register struct frame *f;
700 struct gcpro gcpro1;
702 if (!NILP (mini_window))
703 CHECK_LIVE_WINDOW (mini_window);
705 if (!NILP (mini_window)
706 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
707 error ("Frame and minibuffer must be on the same terminal");
709 /* Make a frame containing just a root window. */
710 f = make_frame (0);
712 if (NILP (mini_window))
714 /* Use default-minibuffer-frame if possible. */
715 if (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
716 || ! FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame))))
718 Lisp_Object frame_dummy;
720 XSETFRAME (frame_dummy, f);
721 GCPRO1 (frame_dummy);
722 /* If there's no minibuffer frame to use, create one. */
723 kset_default_minibuffer_frame
724 (kb, call1 (intern ("make-initial-minibuffer-frame"), display));
725 UNGCPRO;
728 mini_window
729 = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
732 fset_minibuffer_window (f, mini_window);
734 /* Make the chosen minibuffer window display the proper minibuffer,
735 unless it is already showing a minibuffer. */
736 if (NILP (Fmemq (XWINDOW (mini_window)->contents, Vminibuffer_list)))
737 /* Use set_window_buffer instead of Fset_window_buffer (see
738 discussion of bug#11984, bug#12025, bug#12026). */
739 set_window_buffer (mini_window,
740 (NILP (Vminibuffer_list)
741 ? get_minibuffer (0)
742 : Fcar (Vminibuffer_list)), 0, 0);
743 return f;
746 /* Make a frame containing only a minibuffer window. */
748 struct frame *
749 make_minibuffer_frame (void)
751 /* First make a frame containing just a root window, no minibuffer. */
753 register struct frame *f = make_frame (0);
754 register Lisp_Object mini_window;
755 register Lisp_Object frame;
757 XSETFRAME (frame, f);
759 f->auto_raise = 0;
760 f->auto_lower = 0;
761 f->no_split = 1;
762 f->wants_modeline = 0;
764 /* Now label the root window as also being the minibuffer.
765 Avoid infinite looping on the window chain by marking next pointer
766 as nil. */
768 mini_window = f->root_window;
769 fset_minibuffer_window (f, mini_window);
770 XWINDOW (mini_window)->mini = 1;
771 wset_next (XWINDOW (mini_window), Qnil);
772 wset_prev (XWINDOW (mini_window), Qnil);
773 wset_frame (XWINDOW (mini_window), frame);
775 /* Put the proper buffer in that window. */
777 /* Use set_window_buffer instead of Fset_window_buffer (see
778 discussion of bug#11984, bug#12025, bug#12026). */
779 set_window_buffer (mini_window,
780 (NILP (Vminibuffer_list)
781 ? get_minibuffer (0)
782 : Fcar (Vminibuffer_list)), 0, 0);
783 return f;
785 #endif /* HAVE_WINDOW_SYSTEM */
787 /* Construct a frame that refers to a terminal. */
789 static printmax_t tty_frame_count;
791 struct frame *
792 make_initial_frame (void)
794 struct frame *f;
795 struct terminal *terminal;
796 Lisp_Object frame;
798 eassert (initial_kboard);
800 /* The first call must initialize Vframe_list. */
801 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
802 Vframe_list = Qnil;
804 terminal = init_initial_terminal ();
806 f = make_frame (1);
807 XSETFRAME (frame, f);
809 Vframe_list = Fcons (frame, Vframe_list);
811 tty_frame_count = 1;
812 fset_name (f, build_pure_c_string ("F1"));
814 SET_FRAME_VISIBLE (f, 1);
816 f->output_method = terminal->type;
817 f->terminal = terminal;
818 f->terminal->reference_count++;
819 f->output_data.nothing = 0;
821 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
822 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
824 #ifdef HAVE_WINDOW_SYSTEM
825 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
826 f->horizontal_scroll_bars = false;
827 #endif
829 /* The default value of menu-bar-mode is t. */
830 set_menu_bar_lines (f, make_number (1), Qnil);
832 if (!noninteractive)
833 init_frame_faces (f);
835 last_nonminibuf_frame = f;
837 return f;
841 static struct frame *
842 make_terminal_frame (struct terminal *terminal)
844 register struct frame *f;
845 Lisp_Object frame;
846 char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
848 if (!terminal->name)
849 error ("Terminal is not live, can't create new frames on it");
851 f = make_frame (1);
853 XSETFRAME (frame, f);
854 Vframe_list = Fcons (frame, Vframe_list);
856 fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count));
858 SET_FRAME_VISIBLE (f, 1);
860 f->terminal = terminal;
861 f->terminal->reference_count++;
862 #ifdef MSDOS
863 f->output_data.tty->display_info = &the_only_display_info;
864 if (!inhibit_window_system
865 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
866 || XFRAME (selected_frame)->output_method == output_msdos_raw))
867 f->output_method = output_msdos_raw;
868 else
869 f->output_method = output_termcap;
870 #else /* not MSDOS */
871 f->output_method = output_termcap;
872 create_tty_output (f);
873 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
874 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
875 #endif /* not MSDOS */
877 #ifdef HAVE_WINDOW_SYSTEM
878 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
879 f->horizontal_scroll_bars = false;
880 #endif
882 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
883 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f);
884 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
885 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f);
887 /* Set the top frame to the newly created frame. */
888 if (FRAMEP (FRAME_TTY (f)->top_frame)
889 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
890 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */
892 FRAME_TTY (f)->top_frame = frame;
894 if (!noninteractive)
895 init_frame_faces (f);
897 return f;
900 /* Get a suitable value for frame parameter PARAMETER for a newly
901 created frame, based on (1) the user-supplied frame parameter
902 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
904 static Lisp_Object
905 get_future_frame_param (Lisp_Object parameter,
906 Lisp_Object supplied_parms,
907 char *current_value)
909 Lisp_Object result;
911 result = Fassq (parameter, supplied_parms);
912 if (NILP (result))
913 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
914 if (NILP (result) && current_value != NULL)
915 result = build_string (current_value);
916 if (!NILP (result) && !STRINGP (result))
917 result = XCDR (result);
918 if (NILP (result) || !STRINGP (result))
919 result = Qnil;
921 return result;
924 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
925 1, 1, 0,
926 doc: /* Create an additional terminal frame, possibly on another terminal.
927 This function takes one argument, an alist specifying frame parameters.
929 You can create multiple frames on a single text terminal, but only one
930 of them (the selected terminal frame) is actually displayed.
932 In practice, generally you don't need to specify any parameters,
933 except when you want to create a new frame on another terminal.
934 In that case, the `tty' parameter specifies the device file to open,
935 and the `tty-type' parameter specifies the terminal type. Example:
937 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
939 Note that changing the size of one terminal frame automatically
940 affects all frames on the same terminal device. */)
941 (Lisp_Object parms)
943 struct frame *f;
944 struct terminal *t = NULL;
945 Lisp_Object frame, tem;
946 struct frame *sf = SELECTED_FRAME ();
948 #ifdef MSDOS
949 if (sf->output_method != output_msdos_raw
950 && sf->output_method != output_termcap)
951 emacs_abort ();
952 #else /* not MSDOS */
954 #ifdef WINDOWSNT /* This should work now! */
955 if (sf->output_method != output_termcap)
956 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
957 #endif
958 #endif /* not MSDOS */
961 Lisp_Object terminal;
963 terminal = Fassq (Qterminal, parms);
964 if (CONSP (terminal))
966 terminal = XCDR (terminal);
967 t = get_terminal (terminal, 1);
969 #ifdef MSDOS
970 if (t && t != the_only_display_info.terminal)
971 /* msdos.c assumes a single tty_display_info object. */
972 error ("Multiple terminals are not supported on this platform");
973 if (!t)
974 t = the_only_display_info.terminal;
975 #endif
978 if (!t)
980 char *name = 0, *type = 0;
981 Lisp_Object tty, tty_type;
982 USE_SAFE_ALLOCA;
984 tty = get_future_frame_param
985 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
986 ? FRAME_TTY (XFRAME (selected_frame))->name
987 : NULL));
988 if (!NILP (tty))
989 SAFE_ALLOCA_STRING (name, tty);
991 tty_type = get_future_frame_param
992 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
993 ? FRAME_TTY (XFRAME (selected_frame))->type
994 : NULL));
995 if (!NILP (tty_type))
996 SAFE_ALLOCA_STRING (type, tty_type);
998 t = init_tty (name, type, 0); /* Errors are not fatal. */
999 SAFE_FREE ();
1002 f = make_terminal_frame (t);
1005 int width, height;
1006 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1007 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0);
1010 adjust_frame_glyphs (f);
1011 calculate_costs (f);
1012 XSETFRAME (frame, f);
1014 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
1015 store_in_alist (&parms, Qtty,
1016 (t->display_info.tty->name
1017 ? build_string (t->display_info.tty->name)
1018 : Qnil));
1019 Fmodify_frame_parameters (frame, parms);
1021 /* Make the frame face alist be frame-specific, so that each
1022 frame could change its face definitions independently. */
1023 fset_face_alist (f, Fcopy_alist (sf->face_alist));
1024 /* Simple Fcopy_alist isn't enough, because we need the contents of
1025 the vectors which are the CDRs of associations in face_alist to
1026 be copied as well. */
1027 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
1028 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
1029 return frame;
1033 /* Perform the switch to frame FRAME.
1035 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
1036 FRAME1 as frame.
1038 If TRACK is non-zero and the frame that currently has the focus
1039 redirects its focus to the selected frame, redirect that focused
1040 frame's focus to FRAME instead.
1042 FOR_DELETION non-zero means that the selected frame is being
1043 deleted, which includes the possibility that the frame's terminal
1044 is dead.
1046 The value of NORECORD is passed as argument to Fselect_window. */
1048 Lisp_Object
1049 do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
1051 struct frame *sf = SELECTED_FRAME ();
1053 /* If FRAME is a switch-frame event, extract the frame we should
1054 switch to. */
1055 if (CONSP (frame)
1056 && EQ (XCAR (frame), Qswitch_frame)
1057 && CONSP (XCDR (frame)))
1058 frame = XCAR (XCDR (frame));
1060 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
1061 a switch-frame event to arrive after a frame is no longer live,
1062 especially when deleting the initial frame during startup. */
1063 CHECK_FRAME (frame);
1064 if (! FRAME_LIVE_P (XFRAME (frame)))
1065 return Qnil;
1067 if (sf == XFRAME (frame))
1068 return frame;
1070 /* If a frame's focus has been redirected toward the currently
1071 selected frame, we should change the redirection to point to the
1072 newly selected frame. This means that if the focus is redirected
1073 from a minibufferless frame to a surrogate minibuffer frame, we
1074 can use `other-window' to switch between all the frames using
1075 that minibuffer frame, and the focus redirection will follow us
1076 around. */
1077 #if 0
1078 /* This is too greedy; it causes inappropriate focus redirection
1079 that's hard to get rid of. */
1080 if (track)
1082 Lisp_Object tail;
1084 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1086 Lisp_Object focus;
1088 if (!FRAMEP (XCAR (tail)))
1089 emacs_abort ();
1091 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
1093 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
1094 Fredirect_frame_focus (XCAR (tail), frame);
1097 #else /* ! 0 */
1098 /* Instead, apply it only to the frame we're pointing to. */
1099 #ifdef HAVE_WINDOW_SYSTEM
1100 if (track && FRAME_WINDOW_P (XFRAME (frame)))
1102 Lisp_Object focus, xfocus;
1104 xfocus = x_get_focus_frame (XFRAME (frame));
1105 if (FRAMEP (xfocus))
1107 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
1108 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
1109 Fredirect_frame_focus (xfocus, frame);
1112 #endif /* HAVE_X_WINDOWS */
1113 #endif /* ! 0 */
1115 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
1116 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
1118 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
1120 struct frame *f = XFRAME (frame);
1121 struct tty_display_info *tty = FRAME_TTY (f);
1122 Lisp_Object top_frame = tty->top_frame;
1124 /* Don't mark the frame garbaged and/or obscured if we are
1125 switching to the frame that is already the top frame of that
1126 TTY. */
1127 if (!EQ (frame, top_frame))
1129 if (FRAMEP (top_frame))
1130 /* Mark previously displayed frame as now obscured. */
1131 SET_FRAME_VISIBLE (XFRAME (top_frame), 2);
1132 SET_FRAME_VISIBLE (f, 1);
1133 /* If the new TTY frame changed dimensions, we need to
1134 resync term.c's idea of the frame size with the new
1135 frame's data. */
1136 if (FRAME_COLS (f) != FrameCols (tty))
1137 FrameCols (tty) = FRAME_COLS (f);
1138 if (FRAME_TOTAL_LINES (f) != FrameRows (tty))
1139 FrameRows (tty) = FRAME_TOTAL_LINES (f);
1141 tty->top_frame = frame;
1144 selected_frame = frame;
1145 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
1146 last_nonminibuf_frame = XFRAME (selected_frame);
1148 Fselect_window (XFRAME (frame)->selected_window, norecord);
1150 /* We want to make sure that the next event generates a frame-switch
1151 event to the appropriate frame. This seems kludgy to me, but
1152 before you take it out, make sure that evaluating something like
1153 (select-window (frame-root-window (new-frame))) doesn't end up
1154 with your typing being interpreted in the new frame instead of
1155 the one you're actually typing in. */
1156 internal_last_event_frame = Qnil;
1158 return frame;
1161 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
1162 doc: /* Select FRAME.
1163 Subsequent editing commands apply to its selected window.
1164 Optional argument NORECORD means to neither change the order of
1165 recently selected windows nor the buffer list.
1167 The selection of FRAME lasts until the next time the user does
1168 something to select a different frame, or until the next time
1169 this function is called. If you are using a window system, the
1170 previously selected frame may be restored as the selected frame
1171 when returning to the command loop, because it still may have
1172 the window system's input focus. On a text terminal, the next
1173 redisplay will display FRAME.
1175 This function returns FRAME, or nil if FRAME has been deleted. */)
1176 (Lisp_Object frame, Lisp_Object norecord)
1178 return do_switch_frame (frame, 1, 0, norecord);
1181 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
1182 doc: /* Handle a switch-frame event EVENT.
1183 Switch-frame events are usually bound to this function.
1184 A switch-frame event tells Emacs that the window manager has requested
1185 that the user's events be directed to the frame mentioned in the event.
1186 This function selects the selected window of the frame of EVENT.
1188 If EVENT is frame object, handle it as if it were a switch-frame event
1189 to that frame. */)
1190 (Lisp_Object event)
1192 /* Preserve prefix arg that the command loop just cleared. */
1193 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
1194 Frun_hooks (1, &Qmouse_leave_buffer_hook);
1195 /* `switch-frame' implies a focus in. */
1196 call1 (intern ("handle-focus-in"), event);
1197 return do_switch_frame (event, 0, 0, Qnil);
1200 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1201 doc: /* Return the frame that is now selected. */)
1202 (void)
1204 return selected_frame;
1207 DEFUN ("frame-list", Fframe_list, Sframe_list,
1208 0, 0, 0,
1209 doc: /* Return a list of all live frames. */)
1210 (void)
1212 Lisp_Object frames;
1213 frames = Fcopy_sequence (Vframe_list);
1214 #ifdef HAVE_WINDOW_SYSTEM
1215 if (FRAMEP (tip_frame))
1216 frames = Fdelq (tip_frame, frames);
1217 #endif
1218 return frames;
1221 /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1222 same tty (for tty frames) or among frames which uses FRAME's keyboard.
1223 If MINIBUF is nil, do not consider minibuffer-only candidate.
1224 If MINIBUF is `visible', do not consider an invisible candidate.
1225 If MINIBUF is a window, consider only its own frame and candidate now
1226 using that window as the minibuffer.
1227 If MINIBUF is 0, consider candidate if it is visible or iconified.
1228 Otherwise consider any candidate and return nil if CANDIDATE is not
1229 acceptable. */
1231 static Lisp_Object
1232 candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf)
1234 struct frame *c = XFRAME (candidate), *f = XFRAME (frame);
1236 if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f)
1237 && FRAME_KBOARD (c) == FRAME_KBOARD (f))
1238 || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f)
1239 && FRAME_TTY (c) == FRAME_TTY (f)))
1241 if (NILP (minibuf))
1243 if (!FRAME_MINIBUF_ONLY_P (c))
1244 return candidate;
1246 else if (EQ (minibuf, Qvisible))
1248 if (FRAME_VISIBLE_P (c))
1249 return candidate;
1251 else if (WINDOWP (minibuf))
1253 if (EQ (FRAME_MINIBUF_WINDOW (c), minibuf)
1254 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), candidate)
1255 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1256 FRAME_FOCUS_FRAME (c)))
1257 return candidate;
1259 else if (XFASTINT (minibuf) == 0)
1261 if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c))
1262 return candidate;
1264 else
1265 return candidate;
1267 return Qnil;
1270 /* Return the next frame in the frame list after FRAME. */
1272 static Lisp_Object
1273 next_frame (Lisp_Object frame, Lisp_Object minibuf)
1275 Lisp_Object f, tail;
1276 int passed = 0;
1278 /* There must always be at least one frame in Vframe_list. */
1279 eassert (CONSP (Vframe_list));
1281 while (passed < 2)
1282 FOR_EACH_FRAME (tail, f)
1284 if (passed)
1286 f = candidate_frame (f, frame, minibuf);
1287 if (!NILP (f))
1288 return f;
1290 if (EQ (frame, f))
1291 passed++;
1293 return frame;
1296 /* Return the previous frame in the frame list before FRAME. */
1298 static Lisp_Object
1299 prev_frame (Lisp_Object frame, Lisp_Object minibuf)
1301 Lisp_Object f, tail, prev = Qnil;
1303 /* There must always be at least one frame in Vframe_list. */
1304 eassert (CONSP (Vframe_list));
1306 FOR_EACH_FRAME (tail, f)
1308 if (EQ (frame, f) && !NILP (prev))
1309 return prev;
1310 f = candidate_frame (f, frame, minibuf);
1311 if (!NILP (f))
1312 prev = f;
1315 /* We've scanned the entire list. */
1316 if (NILP (prev))
1317 /* We went through the whole frame list without finding a single
1318 acceptable frame. Return the original frame. */
1319 return frame;
1320 else
1321 /* There were no acceptable frames in the list before FRAME; otherwise,
1322 we would have returned directly from the loop. Since PREV is the last
1323 acceptable frame in the list, return it. */
1324 return prev;
1328 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1329 doc: /* Return the next frame in the frame list after FRAME.
1330 It considers only frames on the same terminal as FRAME.
1331 By default, skip minibuffer-only frames.
1332 If omitted, FRAME defaults to the selected frame.
1333 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1334 If MINIFRAME is a window, include only its own frame
1335 and any frame now using that window as the minibuffer.
1336 If MINIFRAME is `visible', include all visible frames.
1337 If MINIFRAME is 0, include all visible and iconified frames.
1338 Otherwise, include all frames. */)
1339 (Lisp_Object frame, Lisp_Object miniframe)
1341 if (NILP (frame))
1342 frame = selected_frame;
1343 CHECK_LIVE_FRAME (frame);
1344 return next_frame (frame, miniframe);
1347 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1348 doc: /* Return the previous frame in the frame list before FRAME.
1349 It considers only frames on the same terminal as FRAME.
1350 By default, skip minibuffer-only frames.
1351 If omitted, FRAME defaults to the selected frame.
1352 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1353 If MINIFRAME is a window, include only its own frame
1354 and any frame now using that window as the minibuffer.
1355 If MINIFRAME is `visible', include all visible frames.
1356 If MINIFRAME is 0, include all visible and iconified frames.
1357 Otherwise, include all frames. */)
1358 (Lisp_Object frame, Lisp_Object miniframe)
1360 if (NILP (frame))
1361 frame = selected_frame;
1362 CHECK_LIVE_FRAME (frame);
1363 return prev_frame (frame, miniframe);
1366 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
1367 Slast_nonminibuf_frame, 0, 0, 0,
1368 doc: /* Return last non-minibuffer frame selected. */)
1369 (void)
1371 Lisp_Object frame = Qnil;
1373 if (last_nonminibuf_frame)
1374 XSETFRAME (frame, last_nonminibuf_frame);
1376 return frame;
1379 /* Return 1 if it is ok to delete frame F;
1380 0 if all frames aside from F are invisible.
1381 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1383 static int
1384 other_visible_frames (struct frame *f)
1386 Lisp_Object frames, this;
1388 FOR_EACH_FRAME (frames, this)
1390 if (f == XFRAME (this))
1391 continue;
1393 /* Verify that we can still talk to the frame's X window,
1394 and note any recent change in visibility. */
1395 #ifdef HAVE_X_WINDOWS
1396 if (FRAME_WINDOW_P (XFRAME (this)))
1397 x_sync (XFRAME (this));
1398 #endif
1400 if (FRAME_VISIBLE_P (XFRAME (this))
1401 || FRAME_ICONIFIED_P (XFRAME (this))
1402 /* Allow deleting the terminal frame when at least one X
1403 frame exists. */
1404 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1405 return 1;
1407 return 0;
1410 /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1411 window. Preferably use the selected frame's minibuffer window
1412 instead. If the selected frame doesn't have one, get some other
1413 frame's minibuffer window. SELECT non-zero means select the new
1414 minibuffer window. */
1415 static void
1416 check_minibuf_window (Lisp_Object frame, int select)
1418 struct frame *f = decode_live_frame (frame);
1420 XSETFRAME (frame, f);
1422 if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
1424 Lisp_Object frames, this, window = make_number (0);
1426 if (!EQ (frame, selected_frame)
1427 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
1428 window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
1429 else
1430 FOR_EACH_FRAME (frames, this)
1432 if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1434 window = FRAME_MINIBUF_WINDOW (XFRAME (this));
1435 break;
1439 /* Don't abort if no window was found (Bug#15247). */
1440 if (WINDOWP (window))
1442 /* Use set_window_buffer instead of Fset_window_buffer (see
1443 discussion of bug#11984, bug#12025, bug#12026). */
1444 set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
1445 minibuf_window = window;
1447 /* SELECT non-zero usually means that FRAME's minibuffer
1448 window was selected; select the new one. */
1449 if (select)
1450 Fselect_window (minibuf_window, Qnil);
1456 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1457 unconditionally. x_connection_closed and delete_terminal use
1458 this. Any other value of FORCE implements the semantics
1459 described for Fdelete_frame. */
1460 Lisp_Object
1461 delete_frame (Lisp_Object frame, Lisp_Object force)
1463 struct frame *f = decode_any_frame (frame);
1464 struct frame *sf;
1465 struct kboard *kb;
1467 int minibuffer_selected, is_tooltip_frame;
1469 if (! FRAME_LIVE_P (f))
1470 return Qnil;
1472 if (NILP (force) && !other_visible_frames (f))
1473 error ("Attempt to delete the sole visible or iconified frame");
1475 /* x_connection_closed must have set FORCE to `noelisp' in order
1476 to delete the last frame, if it is gone. */
1477 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1478 error ("Attempt to delete the only frame");
1480 XSETFRAME (frame, f);
1482 /* Does this frame have a minibuffer, and is it the surrogate
1483 minibuffer for any other frame? */
1484 if (FRAME_HAS_MINIBUF_P (f))
1486 Lisp_Object frames, this;
1488 FOR_EACH_FRAME (frames, this)
1490 Lisp_Object fminiw;
1492 if (EQ (this, frame))
1493 continue;
1495 fminiw = FRAME_MINIBUF_WINDOW (XFRAME (this));
1497 if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw))))
1499 /* If we MUST delete this frame, delete the other first.
1500 But do this only if FORCE equals `noelisp'. */
1501 if (EQ (force, Qnoelisp))
1502 delete_frame (this, Qnoelisp);
1503 else
1504 error ("Attempt to delete a surrogate minibuffer frame");
1509 is_tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
1511 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1512 frame is a tooltip. FORCE is set to `noelisp' when handling
1513 a disconnect from the terminal, so we don't dare call Lisp
1514 code. */
1515 if (NILP (Vrun_hooks) || is_tooltip_frame)
1517 else if (EQ (force, Qnoelisp))
1518 pending_funcalls
1519 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1520 pending_funcalls);
1521 else
1523 #ifdef HAVE_X_WINDOWS
1524 /* Also, save clipboard to the clipboard manager. */
1525 x_clipboard_manager_save_frame (frame);
1526 #endif
1528 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1531 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1532 if (! FRAME_LIVE_P (f))
1533 return Qnil;
1535 /* At this point, we are committed to deleting the frame.
1536 There is no more chance for errors to prevent it. */
1538 minibuffer_selected = EQ (minibuf_window, selected_window);
1539 sf = SELECTED_FRAME ();
1540 /* Don't let the frame remain selected. */
1541 if (f == sf)
1543 Lisp_Object tail;
1544 Lisp_Object frame1 = Qnil;
1546 /* Look for another visible frame on the same terminal.
1547 Do not call next_frame here because it may loop forever.
1548 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1549 FOR_EACH_FRAME (tail, frame1)
1550 if (!EQ (frame, frame1)
1551 && (FRAME_TERMINAL (XFRAME (frame))
1552 == FRAME_TERMINAL (XFRAME (frame1)))
1553 && FRAME_VISIBLE_P (XFRAME (frame1)))
1554 break;
1556 /* If there is none, find *some* other frame. */
1557 if (NILP (frame1) || EQ (frame1, frame))
1559 FOR_EACH_FRAME (tail, frame1)
1561 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1563 /* Do not change a text terminal's top-frame. */
1564 struct frame *f1 = XFRAME (frame1);
1565 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
1567 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
1568 if (!EQ (top_frame, frame))
1569 frame1 = top_frame;
1571 break;
1575 #ifdef NS_IMPL_COCOA
1576 else
1577 /* Under NS, there is no system mechanism for choosing a new
1578 window to get focus -- it is left to application code.
1579 So the portion of THIS application interfacing with NS
1580 needs to know about it. We call Fraise_frame, but the
1581 purpose is really to transfer focus. */
1582 Fraise_frame (frame1);
1583 #endif
1585 do_switch_frame (frame1, 0, 1, Qnil);
1586 sf = SELECTED_FRAME ();
1589 /* Don't allow minibuf_window to remain on a deleted frame. */
1590 check_minibuf_window (frame, minibuffer_selected);
1592 /* Don't let echo_area_window to remain on a deleted frame. */
1593 if (EQ (f->minibuffer_window, echo_area_window))
1594 echo_area_window = sf->minibuffer_window;
1596 /* Clear any X selections for this frame. */
1597 #ifdef HAVE_X_WINDOWS
1598 if (FRAME_X_P (f))
1599 x_clear_frame_selections (f);
1600 #endif
1602 /* Free glyphs.
1603 This function must be called before the window tree of the
1604 frame is deleted because windows contain dynamically allocated
1605 memory. */
1606 free_glyphs (f);
1608 #ifdef HAVE_WINDOW_SYSTEM
1609 /* Give chance to each font driver to free a frame specific data. */
1610 font_update_drivers (f, Qnil);
1611 #endif
1613 /* Mark all the windows that used to be on FRAME as deleted, and then
1614 remove the reference to them. */
1615 delete_all_child_windows (f->root_window);
1616 fset_root_window (f, Qnil);
1618 Vframe_list = Fdelq (frame, Vframe_list);
1619 SET_FRAME_VISIBLE (f, 0);
1621 /* Allow the vector of menu bar contents to be freed in the next
1622 garbage collection. The frame object itself may not be garbage
1623 collected until much later, because recent_keys and other data
1624 structures can still refer to it. */
1625 fset_menu_bar_vector (f, Qnil);
1627 /* If FRAME's buffer lists contains killed
1628 buffers, this helps GC to reclaim them. */
1629 fset_buffer_list (f, Qnil);
1630 fset_buried_buffer_list (f, Qnil);
1632 free_font_driver_list (f);
1633 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
1634 xfree (f->namebuf);
1635 #endif
1636 xfree (f->decode_mode_spec_buffer);
1637 xfree (FRAME_INSERT_COST (f));
1638 xfree (FRAME_DELETEN_COST (f));
1639 xfree (FRAME_INSERTN_COST (f));
1640 xfree (FRAME_DELETE_COST (f));
1642 /* Since some events are handled at the interrupt level, we may get
1643 an event for f at any time; if we zero out the frame's terminal
1644 now, then we may trip up the event-handling code. Instead, we'll
1645 promise that the terminal of the frame must be valid until we
1646 have called the window-system-dependent frame destruction
1647 routine. */
1651 struct terminal *terminal;
1652 block_input ();
1653 if (FRAME_TERMINAL (f)->delete_frame_hook)
1654 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
1655 terminal = FRAME_TERMINAL (f);
1656 f->output_data.nothing = 0;
1657 f->terminal = 0; /* Now the frame is dead. */
1658 unblock_input ();
1660 /* If needed, delete the terminal that this frame was on.
1661 (This must be done after the frame is killed.) */
1662 terminal->reference_count--;
1663 #ifdef USE_GTK
1664 /* FIXME: Deleting the terminal crashes emacs because of a GTK
1665 bug.
1666 http://lists.gnu.org/archive/html/emacs-devel/2011-10/msg00363.html */
1667 if (terminal->reference_count == 0 && terminal->type == output_x_window)
1668 terminal->reference_count = 1;
1669 #endif /* USE_GTK */
1670 if (terminal->reference_count == 0)
1672 Lisp_Object tmp;
1673 XSETTERMINAL (tmp, terminal);
1675 kb = NULL;
1676 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
1678 else
1679 kb = terminal->kboard;
1682 /* If we've deleted the last_nonminibuf_frame, then try to find
1683 another one. */
1684 if (f == last_nonminibuf_frame)
1686 Lisp_Object frames, this;
1688 last_nonminibuf_frame = 0;
1690 FOR_EACH_FRAME (frames, this)
1692 f = XFRAME (this);
1693 if (!FRAME_MINIBUF_ONLY_P (f))
1695 last_nonminibuf_frame = f;
1696 break;
1701 /* If there's no other frame on the same kboard, get out of
1702 single-kboard state if we're in it for this kboard. */
1703 if (kb != NULL)
1705 Lisp_Object frames, this;
1706 /* Some frame we found on the same kboard, or nil if there are none. */
1707 Lisp_Object frame_on_same_kboard = Qnil;
1709 FOR_EACH_FRAME (frames, this)
1710 if (kb == FRAME_KBOARD (XFRAME (this)))
1711 frame_on_same_kboard = this;
1713 if (NILP (frame_on_same_kboard))
1714 not_single_kboard_state (kb);
1718 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1719 find another one. Prefer minibuffer-only frames, but also notice
1720 frames with other windows. */
1721 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1723 Lisp_Object frames, this;
1725 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1726 Lisp_Object frame_with_minibuf = Qnil;
1727 /* Some frame we found on the same kboard, or nil if there are none. */
1728 Lisp_Object frame_on_same_kboard = Qnil;
1730 FOR_EACH_FRAME (frames, this)
1732 struct frame *f1 = XFRAME (this);
1734 /* Consider only frames on the same kboard
1735 and only those with minibuffers. */
1736 if (kb == FRAME_KBOARD (f1)
1737 && FRAME_HAS_MINIBUF_P (f1))
1739 frame_with_minibuf = this;
1740 if (FRAME_MINIBUF_ONLY_P (f1))
1741 break;
1744 if (kb == FRAME_KBOARD (f1))
1745 frame_on_same_kboard = this;
1748 if (!NILP (frame_on_same_kboard))
1750 /* We know that there must be some frame with a minibuffer out
1751 there. If this were not true, all of the frames present
1752 would have to be minibufferless, which implies that at some
1753 point their minibuffer frames must have been deleted, but
1754 that is prohibited at the top; you can't delete surrogate
1755 minibuffer frames. */
1756 if (NILP (frame_with_minibuf))
1757 emacs_abort ();
1759 kset_default_minibuffer_frame (kb, frame_with_minibuf);
1761 else
1762 /* No frames left on this kboard--say no minibuffer either. */
1763 kset_default_minibuffer_frame (kb, Qnil);
1766 /* Cause frame titles to update--necessary if we now have just one frame. */
1767 if (!is_tooltip_frame)
1768 update_mode_lines = 15;
1770 return Qnil;
1773 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1774 doc: /* Delete FRAME, permanently eliminating it from use.
1775 FRAME defaults to the selected frame.
1777 A frame may not be deleted if its minibuffer is used by other frames.
1778 Normally, you may not delete a frame if all other frames are invisible,
1779 but if the second optional argument FORCE is non-nil, you may do so.
1781 This function runs `delete-frame-functions' before actually
1782 deleting the frame, unless the frame is a tooltip.
1783 The functions are run with one argument, the frame to be deleted. */)
1784 (Lisp_Object frame, Lisp_Object force)
1786 return delete_frame (frame, !NILP (force) ? Qt : Qnil);
1790 /* Return mouse position in character cell units. */
1792 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1793 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1794 The position is given in canonical character cells, where (0, 0) is the
1795 upper-left corner of the frame, X is the horizontal offset, and Y is the
1796 vertical offset, measured in units of the frame's default character size.
1797 If Emacs is running on a mouseless terminal or hasn't been programmed
1798 to read the mouse position, it returns the selected frame for FRAME
1799 and nil for X and Y.
1800 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1801 passing the normal return value to that function as an argument,
1802 and returns whatever that function returns. */)
1803 (void)
1805 struct frame *f;
1806 Lisp_Object lispy_dummy;
1807 Lisp_Object x, y, retval;
1808 struct gcpro gcpro1;
1810 f = SELECTED_FRAME ();
1811 x = y = Qnil;
1813 /* It's okay for the hook to refrain from storing anything. */
1814 if (FRAME_TERMINAL (f)->mouse_position_hook)
1816 enum scroll_bar_part party_dummy;
1817 Time time_dummy;
1818 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1819 &lispy_dummy, &party_dummy,
1820 &x, &y,
1821 &time_dummy);
1824 if (! NILP (x))
1826 int col = XINT (x);
1827 int row = XINT (y);
1828 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1829 XSETINT (x, col);
1830 XSETINT (y, row);
1832 XSETFRAME (lispy_dummy, f);
1833 retval = Fcons (lispy_dummy, Fcons (x, y));
1834 GCPRO1 (retval);
1835 if (!NILP (Vmouse_position_function))
1836 retval = call1 (Vmouse_position_function, retval);
1837 RETURN_UNGCPRO (retval);
1840 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1841 Smouse_pixel_position, 0, 0, 0,
1842 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1843 The position is given in pixel units, where (0, 0) is the
1844 upper-left corner of the frame, X is the horizontal offset, and Y is
1845 the vertical offset.
1846 If Emacs is running on a mouseless terminal or hasn't been programmed
1847 to read the mouse position, it returns the selected frame for FRAME
1848 and nil for X and Y. */)
1849 (void)
1851 struct frame *f;
1852 Lisp_Object lispy_dummy;
1853 Lisp_Object x, y;
1855 f = SELECTED_FRAME ();
1856 x = y = Qnil;
1858 /* It's okay for the hook to refrain from storing anything. */
1859 if (FRAME_TERMINAL (f)->mouse_position_hook)
1861 enum scroll_bar_part party_dummy;
1862 Time time_dummy;
1863 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1864 &lispy_dummy, &party_dummy,
1865 &x, &y,
1866 &time_dummy);
1869 XSETFRAME (lispy_dummy, f);
1870 return Fcons (lispy_dummy, Fcons (x, y));
1873 #ifdef HAVE_WINDOW_SYSTEM
1875 /* On frame F, convert character coordinates X and Y to pixel
1876 coordinates *PIX_X and *PIX_Y. */
1878 static void
1879 frame_char_to_pixel_position (struct frame *f, int x, int y,
1880 int *pix_x, int *pix_y)
1882 *pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2;
1883 *pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2;
1885 if (*pix_x < 0)
1886 *pix_x = 0;
1887 if (*pix_x > FRAME_PIXEL_WIDTH (f))
1888 *pix_x = FRAME_PIXEL_WIDTH (f);
1890 if (*pix_y < 0)
1891 *pix_y = 0;
1892 if (*pix_y > FRAME_PIXEL_HEIGHT (f))
1893 *pix_y = FRAME_PIXEL_HEIGHT (f);
1896 /* On frame F, reposition mouse pointer to character coordinates X and Y. */
1898 static void
1899 frame_set_mouse_position (struct frame *f, int x, int y)
1901 int pix_x, pix_y;
1903 frame_char_to_pixel_position (f, x, y, &pix_x, &pix_y);
1904 frame_set_mouse_pixel_position (f, pix_x, pix_y);
1907 #endif /* HAVE_WINDOW_SYSTEM */
1909 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1910 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1911 Coordinates are relative to the frame, not a window,
1912 so the coordinates of the top left character in the frame
1913 may be nonzero due to left-hand scroll bars or the menu bar.
1915 The position is given in canonical character cells, where (0, 0) is
1916 the upper-left corner of the frame, X is the horizontal offset, and
1917 Y is the vertical offset, measured in units of the frame's default
1918 character size.
1920 This function is a no-op for an X frame that is not visible.
1921 If you have just created a frame, you must wait for it to become visible
1922 before calling this function on it, like this.
1923 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1924 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1926 CHECK_LIVE_FRAME (frame);
1927 CHECK_TYPE_RANGED_INTEGER (int, x);
1928 CHECK_TYPE_RANGED_INTEGER (int, y);
1930 /* I think this should be done with a hook. */
1931 #ifdef HAVE_WINDOW_SYSTEM
1932 if (FRAME_WINDOW_P (XFRAME (frame)))
1933 /* Warping the mouse will cause enternotify and focus events. */
1934 frame_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1935 #else
1936 #if defined (MSDOS)
1937 if (FRAME_MSDOS_P (XFRAME (frame)))
1939 Fselect_frame (frame, Qnil);
1940 mouse_moveto (XINT (x), XINT (y));
1942 #else
1943 #ifdef HAVE_GPM
1945 Fselect_frame (frame, Qnil);
1946 term_mouse_moveto (XINT (x), XINT (y));
1948 #endif
1949 #endif
1950 #endif
1952 return Qnil;
1955 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1956 Sset_mouse_pixel_position, 3, 3, 0,
1957 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1958 The position is given in pixels, where (0, 0) is the upper-left corner
1959 of the frame, X is the horizontal offset, and Y is the vertical offset.
1961 Note, this is a no-op for an X frame that is not visible.
1962 If you have just created a frame, you must wait for it to become visible
1963 before calling this function on it, like this.
1964 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1965 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1967 CHECK_LIVE_FRAME (frame);
1968 CHECK_TYPE_RANGED_INTEGER (int, x);
1969 CHECK_TYPE_RANGED_INTEGER (int, y);
1971 /* I think this should be done with a hook. */
1972 #ifdef HAVE_WINDOW_SYSTEM
1973 if (FRAME_WINDOW_P (XFRAME (frame)))
1974 /* Warping the mouse will cause enternotify and focus events. */
1975 frame_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1976 #else
1977 #if defined (MSDOS)
1978 if (FRAME_MSDOS_P (XFRAME (frame)))
1980 Fselect_frame (frame, Qnil);
1981 mouse_moveto (XINT (x), XINT (y));
1983 #else
1984 #ifdef HAVE_GPM
1986 Fselect_frame (frame, Qnil);
1987 term_mouse_moveto (XINT (x), XINT (y));
1989 #endif
1990 #endif
1991 #endif
1993 return Qnil;
1996 static void make_frame_visible_1 (Lisp_Object);
1998 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1999 0, 1, "",
2000 doc: /* Make the frame FRAME visible (assuming it is an X window).
2001 If omitted, FRAME defaults to the currently selected frame. */)
2002 (Lisp_Object frame)
2004 struct frame *f = decode_live_frame (frame);
2006 /* I think this should be done with a hook. */
2007 #ifdef HAVE_WINDOW_SYSTEM
2008 if (FRAME_WINDOW_P (f))
2009 x_make_frame_visible (f);
2010 #endif
2012 make_frame_visible_1 (f->root_window);
2014 /* Make menu bar update for the Buffers and Frames menus. */
2015 /* windows_or_buffers_changed = 15; FIXME: Why? */
2017 XSETFRAME (frame, f);
2018 return frame;
2021 /* Update the display_time slot of the buffers shown in WINDOW
2022 and all its descendants. */
2024 static void
2025 make_frame_visible_1 (Lisp_Object window)
2027 struct window *w;
2029 for (; !NILP (window); window = w->next)
2031 w = XWINDOW (window);
2032 if (WINDOWP (w->contents))
2033 make_frame_visible_1 (w->contents);
2034 else
2035 bset_display_time (XBUFFER (w->contents), Fcurrent_time ());
2039 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
2040 0, 2, "",
2041 doc: /* Make the frame FRAME invisible.
2042 If omitted, FRAME defaults to the currently selected frame.
2043 On graphical displays, invisible frames are not updated and are
2044 usually not displayed at all, even in a window system's \"taskbar\".
2046 Normally you may not make FRAME invisible if all other frames are invisible,
2047 but if the second optional argument FORCE is non-nil, you may do so.
2049 This function has no effect on text terminal frames. Such frames are
2050 always considered visible, whether or not they are currently being
2051 displayed in the terminal. */)
2052 (Lisp_Object frame, Lisp_Object force)
2054 struct frame *f = decode_live_frame (frame);
2056 if (NILP (force) && !other_visible_frames (f))
2057 error ("Attempt to make invisible the sole visible or iconified frame");
2059 /* Don't allow minibuf_window to remain on an invisible frame. */
2060 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
2062 /* I think this should be done with a hook. */
2063 #ifdef HAVE_WINDOW_SYSTEM
2064 if (FRAME_WINDOW_P (f))
2065 x_make_frame_invisible (f);
2066 #endif
2068 /* Make menu bar update for the Buffers and Frames menus. */
2069 windows_or_buffers_changed = 16;
2071 return Qnil;
2074 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
2075 0, 1, "",
2076 doc: /* Make the frame FRAME into an icon.
2077 If omitted, FRAME defaults to the currently selected frame. */)
2078 (Lisp_Object frame)
2080 struct frame *f = decode_live_frame (frame);
2082 /* Don't allow minibuf_window to remain on an iconified frame. */
2083 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
2085 /* I think this should be done with a hook. */
2086 #ifdef HAVE_WINDOW_SYSTEM
2087 if (FRAME_WINDOW_P (f))
2088 x_iconify_frame (f);
2089 #endif
2091 /* Make menu bar update for the Buffers and Frames menus. */
2092 windows_or_buffers_changed = 17;
2094 return Qnil;
2097 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
2098 1, 1, 0,
2099 doc: /* Return t if FRAME is \"visible\" (actually in use for display).
2100 Return the symbol `icon' if FRAME is iconified or \"minimized\".
2101 Return nil if FRAME was made invisible, via `make-frame-invisible'.
2102 On graphical displays, invisible frames are not updated and are
2103 usually not displayed at all, even in a window system's \"taskbar\".
2105 If FRAME is a text terminal frame, this always returns t.
2106 Such frames are always considered visible, whether or not they are
2107 currently being displayed on the terminal. */)
2108 (Lisp_Object frame)
2110 CHECK_LIVE_FRAME (frame);
2112 if (FRAME_VISIBLE_P (XFRAME (frame)))
2113 return Qt;
2114 if (FRAME_ICONIFIED_P (XFRAME (frame)))
2115 return Qicon;
2116 return Qnil;
2119 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
2120 0, 0, 0,
2121 doc: /* Return a list of all frames now \"visible\" (being updated). */)
2122 (void)
2124 Lisp_Object tail, frame, value = Qnil;
2126 FOR_EACH_FRAME (tail, frame)
2127 if (FRAME_VISIBLE_P (XFRAME (frame)))
2128 value = Fcons (frame, value);
2130 return value;
2134 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
2135 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
2136 If FRAME is invisible or iconified, make it visible.
2137 If you don't specify a frame, the selected frame is used.
2138 If Emacs is displaying on an ordinary terminal or some other device which
2139 doesn't support multiple overlapping frames, this function selects FRAME. */)
2140 (Lisp_Object frame)
2142 struct frame *f = decode_live_frame (frame);
2144 XSETFRAME (frame, f);
2146 if (FRAME_TERMCAP_P (f))
2147 /* On a text terminal select FRAME. */
2148 Fselect_frame (frame, Qnil);
2149 else
2150 /* Do like the documentation says. */
2151 Fmake_frame_visible (frame);
2153 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2154 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
2156 return Qnil;
2159 /* Should we have a corresponding function called Flower_Power? */
2160 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
2161 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2162 If you don't specify a frame, the selected frame is used.
2163 If Emacs is displaying on an ordinary terminal or some other device which
2164 doesn't support multiple overlapping frames, this function does nothing. */)
2165 (Lisp_Object frame)
2167 struct frame *f = decode_live_frame (frame);
2169 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2170 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
2172 return Qnil;
2176 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
2177 1, 2, 0,
2178 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2179 In other words, switch-frame events caused by events in FRAME will
2180 request a switch to FOCUS-FRAME, and `last-event-frame' will be
2181 FOCUS-FRAME after reading an event typed at FRAME.
2183 If FOCUS-FRAME is nil, any existing redirection is canceled, and the
2184 frame again receives its own keystrokes.
2186 Focus redirection is useful for temporarily redirecting keystrokes to
2187 a surrogate minibuffer frame when a frame doesn't have its own
2188 minibuffer window.
2190 A frame's focus redirection can be changed by `select-frame'. If frame
2191 FOO is selected, and then a different frame BAR is selected, any
2192 frames redirecting their focus to FOO are shifted to redirect their
2193 focus to BAR. This allows focus redirection to work properly when the
2194 user switches from one frame to another using `select-window'.
2196 This means that a frame whose focus is redirected to itself is treated
2197 differently from a frame whose focus is redirected to nil; the former
2198 is affected by `select-frame', while the latter is not.
2200 The redirection lasts until `redirect-frame-focus' is called to change it. */)
2201 (Lisp_Object frame, Lisp_Object focus_frame)
2203 /* Note that we don't check for a live frame here. It's reasonable
2204 to redirect the focus of a frame you're about to delete, if you
2205 know what other frame should receive those keystrokes. */
2206 struct frame *f = decode_any_frame (frame);
2208 if (! NILP (focus_frame))
2209 CHECK_LIVE_FRAME (focus_frame);
2211 fset_focus_frame (f, focus_frame);
2213 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
2214 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
2216 return Qnil;
2220 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 0, 1, 0,
2221 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
2222 If FRAME is omitted or nil, the selected frame is used.
2223 Return nil if FRAME's focus is not redirected.
2224 See `redirect-frame-focus'. */)
2225 (Lisp_Object frame)
2227 return FRAME_FOCUS_FRAME (decode_live_frame (frame));
2230 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
2231 doc: /* Set the input focus to FRAME.
2232 FRAME nil means use the selected frame.
2233 If there is no window system support, this function does nothing. */)
2234 (Lisp_Object frame)
2236 #ifdef HAVE_WINDOW_SYSTEM
2237 x_focus_frame (decode_window_system_frame (frame));
2238 #endif
2239 return Qnil;
2243 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2245 void
2246 frames_discard_buffer (Lisp_Object buffer)
2248 Lisp_Object frame, tail;
2250 FOR_EACH_FRAME (tail, frame)
2252 fset_buffer_list
2253 (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buffer_list));
2254 fset_buried_buffer_list
2255 (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buried_buffer_list));
2259 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2260 If the alist already has an element for PROP, we change it. */
2262 void
2263 store_in_alist (Lisp_Object *alistptr, Lisp_Object prop, Lisp_Object val)
2265 register Lisp_Object tem;
2267 tem = Fassq (prop, *alistptr);
2268 if (EQ (tem, Qnil))
2269 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2270 else
2271 Fsetcdr (tem, val);
2274 static int
2275 frame_name_fnn_p (char *str, ptrdiff_t len)
2277 if (len > 1 && str[0] == 'F' && '0' <= str[1] && str[1] <= '9')
2279 char *p = str + 2;
2280 while ('0' <= *p && *p <= '9')
2281 p++;
2282 if (p == str + len)
2283 return 1;
2285 return 0;
2288 /* Set the name of the terminal frame. Also used by MSDOS frames.
2289 Modeled after x_set_name which is used for WINDOW frames. */
2291 static void
2292 set_term_frame_name (struct frame *f, Lisp_Object name)
2294 f->explicit_name = ! NILP (name);
2296 /* If NAME is nil, set the name to F<num>. */
2297 if (NILP (name))
2299 char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
2301 /* Check for no change needed in this very common case
2302 before we do any consing. */
2303 if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name)))
2304 return;
2306 name = make_formatted_string (namebuf, "F%"pMd, ++tty_frame_count);
2308 else
2310 CHECK_STRING (name);
2312 /* Don't change the name if it's already NAME. */
2313 if (! NILP (Fstring_equal (name, f->name)))
2314 return;
2316 /* Don't allow the user to set the frame name to F<num>, so it
2317 doesn't clash with the names we generate for terminal frames. */
2318 if (frame_name_fnn_p (SSDATA (name), SBYTES (name)))
2319 error ("Frame names of the form F<num> are usurped by Emacs");
2322 fset_name (f, name);
2323 update_mode_lines = 16;
2326 void
2327 store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
2329 register Lisp_Object old_alist_elt;
2331 /* The buffer-list parameters are stored in a special place and not
2332 in the alist. All buffers must be live. */
2333 if (EQ (prop, Qbuffer_list))
2335 Lisp_Object list = Qnil;
2336 for (; CONSP (val); val = XCDR (val))
2337 if (!NILP (Fbuffer_live_p (XCAR (val))))
2338 list = Fcons (XCAR (val), list);
2339 fset_buffer_list (f, Fnreverse (list));
2340 return;
2342 if (EQ (prop, Qburied_buffer_list))
2344 Lisp_Object list = Qnil;
2345 for (; CONSP (val); val = XCDR (val))
2346 if (!NILP (Fbuffer_live_p (XCAR (val))))
2347 list = Fcons (XCAR (val), list);
2348 fset_buried_buffer_list (f, Fnreverse (list));
2349 return;
2352 /* If PROP is a symbol which is supposed to have frame-local values,
2353 and it is set up based on this frame, switch to the global
2354 binding. That way, we can create or alter the frame-local binding
2355 without messing up the symbol's status. */
2356 if (SYMBOLP (prop))
2358 struct Lisp_Symbol *sym = XSYMBOL (prop);
2359 start:
2360 switch (sym->redirect)
2362 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2363 case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
2364 case SYMBOL_LOCALIZED:
2365 { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
2366 if (blv->frame_local && blv_found (blv) && XFRAME (blv->where) == f)
2367 swap_in_global_binding (sym);
2368 break;
2370 default: emacs_abort ();
2374 /* The tty color needed to be set before the frame's parameter
2375 alist was updated with the new value. This is not true any more,
2376 but we still do this test early on. */
2377 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2378 && f == FRAME_TTY (f)->previous_frame)
2379 /* Force redisplay of this tty. */
2380 FRAME_TTY (f)->previous_frame = NULL;
2382 /* Update the frame parameter alist. */
2383 old_alist_elt = Fassq (prop, f->param_alist);
2384 if (EQ (old_alist_elt, Qnil))
2385 fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
2386 else
2387 Fsetcdr (old_alist_elt, val);
2389 /* Update some other special parameters in their special places
2390 in addition to the alist. */
2392 if (EQ (prop, Qbuffer_predicate))
2393 fset_buffer_predicate (f, val);
2395 if (! FRAME_WINDOW_P (f))
2397 if (EQ (prop, Qmenu_bar_lines))
2398 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2399 else if (EQ (prop, Qname))
2400 set_term_frame_name (f, val);
2403 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2405 if (! MINI_WINDOW_P (XWINDOW (val)))
2406 error ("Surrogate minibuffer windows must be minibuffer windows");
2408 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2409 && !EQ (val, f->minibuffer_window))
2410 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2412 /* Install the chosen minibuffer window, with proper buffer. */
2413 fset_minibuffer_window (f, val);
2417 /* Return color matches UNSPEC on frame F or nil if UNSPEC
2418 is not an unspecified foreground or background color. */
2420 static Lisp_Object
2421 frame_unspecified_color (struct frame *f, Lisp_Object unspec)
2423 return (!strncmp (SSDATA (unspec), unspecified_bg, SBYTES (unspec))
2424 ? tty_color_name (f, FRAME_BACKGROUND_PIXEL (f))
2425 : (!strncmp (SSDATA (unspec), unspecified_fg, SBYTES (unspec))
2426 ? tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)) : Qnil));
2429 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2430 doc: /* Return the parameters-alist of frame FRAME.
2431 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2432 The meaningful PARMs depend on the kind of frame.
2433 If FRAME is omitted or nil, return information on the currently selected frame. */)
2434 (Lisp_Object frame)
2436 Lisp_Object alist;
2437 struct frame *f = decode_any_frame (frame);
2438 int height, width;
2439 struct gcpro gcpro1;
2441 if (!FRAME_LIVE_P (f))
2442 return Qnil;
2444 alist = Fcopy_alist (f->param_alist);
2445 GCPRO1 (alist);
2447 if (!FRAME_WINDOW_P (f))
2449 Lisp_Object elt;
2451 /* If the frame's parameter alist says the colors are
2452 unspecified and reversed, take the frame's background pixel
2453 for foreground and vice versa. */
2454 elt = Fassq (Qforeground_color, alist);
2455 if (CONSP (elt) && STRINGP (XCDR (elt)))
2457 elt = frame_unspecified_color (f, XCDR (elt));
2458 if (!NILP (elt))
2459 store_in_alist (&alist, Qforeground_color, elt);
2461 else
2462 store_in_alist (&alist, Qforeground_color,
2463 tty_color_name (f, FRAME_FOREGROUND_PIXEL (f)));
2464 elt = Fassq (Qbackground_color, alist);
2465 if (CONSP (elt) && STRINGP (XCDR (elt)))
2467 elt = frame_unspecified_color (f, XCDR (elt));
2468 if (!NILP (elt))
2469 store_in_alist (&alist, Qbackground_color, elt);
2471 else
2472 store_in_alist (&alist, Qbackground_color,
2473 tty_color_name (f, FRAME_BACKGROUND_PIXEL (f)));
2474 store_in_alist (&alist, intern ("font"),
2475 build_string (FRAME_MSDOS_P (f)
2476 ? "ms-dos"
2477 : FRAME_W32_P (f) ? "w32term"
2478 :"tty"));
2480 store_in_alist (&alist, Qname, f->name);
2481 height = (f->new_height
2482 ? (f->new_pixelwise
2483 ? (f->new_height / FRAME_LINE_HEIGHT (f))
2484 : f->new_height)
2485 : FRAME_LINES (f));
2486 store_in_alist (&alist, Qheight, make_number (height));
2487 width = (f->new_width
2488 ? (f->new_pixelwise
2489 ? (f->new_width / FRAME_COLUMN_WIDTH (f))
2490 : f->new_width)
2491 : FRAME_COLS (f));
2492 store_in_alist (&alist, Qwidth, make_number (width));
2493 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2494 store_in_alist (&alist, Qminibuffer,
2495 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2496 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2497 : FRAME_MINIBUF_WINDOW (f)));
2498 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2499 store_in_alist (&alist, Qbuffer_list, f->buffer_list);
2500 store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
2502 /* I think this should be done with a hook. */
2503 #ifdef HAVE_WINDOW_SYSTEM
2504 if (FRAME_WINDOW_P (f))
2505 x_report_frame_params (f, &alist);
2506 else
2507 #endif
2509 /* This ought to be correct in f->param_alist for an X frame. */
2510 Lisp_Object lines;
2511 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2512 store_in_alist (&alist, Qmenu_bar_lines, lines);
2515 UNGCPRO;
2516 return alist;
2520 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2521 doc: /* Return FRAME's value for parameter PARAMETER.
2522 If FRAME is nil, describe the currently selected frame. */)
2523 (Lisp_Object frame, Lisp_Object parameter)
2525 struct frame *f = decode_any_frame (frame);
2526 Lisp_Object value = Qnil;
2528 CHECK_SYMBOL (parameter);
2530 XSETFRAME (frame, f);
2532 if (FRAME_LIVE_P (f))
2534 /* Avoid consing in frequent cases. */
2535 if (EQ (parameter, Qname))
2536 value = f->name;
2537 #ifdef HAVE_X_WINDOWS
2538 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2539 value = XCAR (FRAME_DISPLAY_INFO (f)->name_list_element);
2540 #endif /* HAVE_X_WINDOWS */
2541 else if (EQ (parameter, Qbackground_color)
2542 || EQ (parameter, Qforeground_color))
2544 value = Fassq (parameter, f->param_alist);
2545 if (CONSP (value))
2547 value = XCDR (value);
2548 /* Fframe_parameters puts the actual fg/bg color names,
2549 even if f->param_alist says otherwise. This is
2550 important when param_alist's notion of colors is
2551 "unspecified". We need to do the same here. */
2552 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2553 value = frame_unspecified_color (f, value);
2555 else
2556 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2558 else if (EQ (parameter, Qdisplay_type)
2559 || EQ (parameter, Qbackground_mode))
2560 value = Fcdr (Fassq (parameter, f->param_alist));
2561 else
2562 /* FIXME: Avoid this code path at all (as well as code duplication)
2563 by sharing more code with Fframe_parameters. */
2564 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2567 return value;
2571 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2572 Smodify_frame_parameters, 2, 2, 0,
2573 doc: /* Modify the parameters of frame FRAME according to ALIST.
2574 If FRAME is nil, it defaults to the selected frame.
2575 ALIST is an alist of parameters to change and their new values.
2576 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2577 The meaningful PARMs depend on the kind of frame.
2578 Undefined PARMs are ignored, but stored in the frame's parameter list
2579 so that `frame-parameters' will return them.
2581 The value of frame parameter FOO can also be accessed
2582 as a frame-local binding for the variable FOO, if you have
2583 enabled such bindings for that variable with `make-variable-frame-local'.
2584 Note that this functionality is obsolete as of Emacs 22.2, and its
2585 use is not recommended. Explicitly check for a frame-parameter instead. */)
2586 (Lisp_Object frame, Lisp_Object alist)
2588 struct frame *f = decode_live_frame (frame);
2589 register Lisp_Object prop, val;
2591 CHECK_LIST (alist);
2593 /* I think this should be done with a hook. */
2594 #ifdef HAVE_WINDOW_SYSTEM
2595 if (FRAME_WINDOW_P (f))
2596 x_set_frame_parameters (f, alist);
2597 else
2598 #endif
2599 #ifdef MSDOS
2600 if (FRAME_MSDOS_P (f))
2601 IT_set_frame_parameters (f, alist);
2602 else
2603 #endif
2606 EMACS_INT length = XFASTINT (Flength (alist));
2607 ptrdiff_t i;
2608 Lisp_Object *parms;
2609 Lisp_Object *values;
2610 USE_SAFE_ALLOCA;
2611 SAFE_ALLOCA_LISP (parms, 2 * length);
2612 values = parms + length;
2614 /* Extract parm names and values into those vectors. */
2616 for (i = 0; CONSP (alist); alist = XCDR (alist))
2618 Lisp_Object elt;
2620 elt = XCAR (alist);
2621 parms[i] = Fcar (elt);
2622 values[i] = Fcdr (elt);
2623 i++;
2626 /* Now process them in reverse of specified order. */
2627 while (--i >= 0)
2629 prop = parms[i];
2630 val = values[i];
2631 store_frame_param (f, prop, val);
2633 if (EQ (prop, Qforeground_color)
2634 || EQ (prop, Qbackground_color))
2635 update_face_from_frame_parameter (f, prop, val);
2638 SAFE_FREE ();
2640 return Qnil;
2643 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2644 0, 1, 0,
2645 doc: /* Height in pixels of a line in the font in frame FRAME.
2646 If FRAME is omitted or nil, the selected frame is used.
2647 For a terminal frame, the value is always 1. */)
2648 (Lisp_Object frame)
2650 #ifdef HAVE_WINDOW_SYSTEM
2651 struct frame *f = decode_any_frame (frame);
2653 if (FRAME_WINDOW_P (f))
2654 return make_number (FRAME_LINE_HEIGHT (f));
2655 else
2656 #endif
2657 return make_number (1);
2661 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2662 0, 1, 0,
2663 doc: /* Width in pixels of characters in the font in frame FRAME.
2664 If FRAME is omitted or nil, the selected frame is used.
2665 On a graphical screen, the width is the standard width of the default font.
2666 For a terminal screen, the value is always 1. */)
2667 (Lisp_Object frame)
2669 #ifdef HAVE_WINDOW_SYSTEM
2670 struct frame *f = decode_any_frame (frame);
2672 if (FRAME_WINDOW_P (f))
2673 return make_number (FRAME_COLUMN_WIDTH (f));
2674 else
2675 #endif
2676 return make_number (1);
2679 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2680 Sframe_pixel_height, 0, 1, 0,
2681 doc: /* Return a FRAME's height in pixels.
2682 If FRAME is omitted or nil, the selected frame is used. The exact value
2683 of the result depends on the window-system and toolkit in use:
2685 In the Gtk+ version of Emacs, it includes only any window (including
2686 the minibuffer or echo area), mode line, and header line. It does not
2687 include the tool bar or menu bar.
2689 With other graphical versions, it also includes the tool bar and the
2690 menu bar.
2692 For a text terminal, it includes the menu bar. In this case, the
2693 result is really in characters rather than pixels (i.e., is identical
2694 to `frame-height'). */)
2695 (Lisp_Object frame)
2697 struct frame *f = decode_any_frame (frame);
2699 #ifdef HAVE_WINDOW_SYSTEM
2700 if (FRAME_WINDOW_P (f))
2701 return make_number (FRAME_PIXEL_HEIGHT (f));
2702 else
2703 #endif
2704 return make_number (FRAME_TOTAL_LINES (f));
2707 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2708 Sframe_pixel_width, 0, 1, 0,
2709 doc: /* Return FRAME's width in pixels.
2710 For a terminal frame, the result really gives the width in characters.
2711 If FRAME is omitted or nil, the selected frame is used. */)
2712 (Lisp_Object frame)
2714 struct frame *f = decode_any_frame (frame);
2716 #ifdef HAVE_WINDOW_SYSTEM
2717 if (FRAME_WINDOW_P (f))
2718 return make_number (FRAME_PIXEL_WIDTH (f));
2719 else
2720 #endif
2721 return make_number (FRAME_TOTAL_COLS (f));
2724 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
2725 Stool_bar_pixel_width, 0, 1, 0,
2726 doc: /* Return width in pixels of FRAME's tool bar.
2727 The result is greater than zero only when the tool bar is on the left
2728 or right side of FRAME. If FRAME is omitted or nil, the selected frame
2729 is used. */)
2730 (Lisp_Object frame)
2732 #ifdef FRAME_TOOLBAR_WIDTH
2733 struct frame *f = decode_any_frame (frame);
2735 if (FRAME_WINDOW_P (f))
2736 return make_number (FRAME_TOOLBAR_WIDTH (f));
2737 #endif
2738 return make_number (0);
2741 DEFUN ("frame-text-cols", Fframe_text_cols, Sframe_text_cols, 0, 1, 0,
2742 doc: /* Return width in columns of FRAME's text area. */)
2743 (Lisp_Object frame)
2745 return make_number (FRAME_COLS (decode_any_frame (frame)));
2748 DEFUN ("frame-text-lines", Fframe_text_lines, Sframe_text_lines, 0, 1, 0,
2749 doc: /* Return height in lines of FRAME's text area. */)
2750 (Lisp_Object frame)
2752 return make_number (FRAME_LINES (decode_any_frame (frame)));
2755 DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0,
2756 doc: /* Return number of total columns of FRAME. */)
2757 (Lisp_Object frame)
2759 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame)));
2762 DEFUN ("frame-total-lines", Fframe_total_lines, Sframe_total_lines, 0, 1, 0,
2763 doc: /* Return number of total lines of FRAME. */)
2764 (Lisp_Object frame)
2766 return make_number (FRAME_TOTAL_LINES (decode_any_frame (frame)));
2769 DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0,
2770 doc: /* Return text area width of FRAME in pixels. */)
2771 (Lisp_Object frame)
2773 return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame)));
2776 DEFUN ("frame-text-height", Fframe_text_height, Sframe_text_height, 0, 1, 0,
2777 doc: /* Return text area height of FRAME in pixels. */)
2778 (Lisp_Object frame)
2780 return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame)));
2783 DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0,
2784 doc: /* Return scroll bar width of FRAME in pixels. */)
2785 (Lisp_Object frame)
2787 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame)));
2790 DEFUN ("frame-scroll-bar-height", Fscroll_bar_height, Sscroll_bar_height, 0, 1, 0,
2791 doc: /* Return scroll bar height of FRAME in pixels. */)
2792 (Lisp_Object frame)
2794 return make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (decode_any_frame (frame)));
2797 DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
2798 doc: /* Return fringe width of FRAME in pixels. */)
2799 (Lisp_Object frame)
2801 return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
2804 DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
2805 doc: /* Return border width of FRAME in pixels. */)
2806 (Lisp_Object frame)
2808 return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
2811 DEFUN ("frame-right-divider-width", Fright_divider_width, Sright_divider_width, 0, 1, 0,
2812 doc: /* Return width (in pixels) of vertical window dividers on FRAME. */)
2813 (Lisp_Object frame)
2815 return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame)));
2818 DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_width, 0, 1, 0,
2819 doc: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
2820 (Lisp_Object frame)
2822 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame)));
2825 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0,
2826 doc: /* Specify that the frame FRAME has HEIGHT text lines.
2827 Optional third arg PRETEND non-nil means that redisplay should use
2828 HEIGHT lines but that the idea of the actual height of the frame should
2829 not be changed. Optional fourth argument PIXELWISE non-nil means that
2830 FRAME should be HEIGHT pixels high. */)
2831 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
2833 struct frame *f = decode_live_frame (frame);
2834 int pixel_height;
2836 CHECK_TYPE_RANGED_INTEGER (int, height);
2838 pixel_height = (!NILP (pixelwise)
2839 ? XINT (height)
2840 : XINT (height) * FRAME_LINE_HEIGHT (f));
2841 if (pixel_height != FRAME_TEXT_HEIGHT (f))
2842 adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend));
2844 return Qnil;
2847 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4, 0,
2848 doc: /* Specify that the frame FRAME has WIDTH columns.
2849 Optional third arg PRETEND non-nil means that redisplay should use WIDTH
2850 columns but that the idea of the actual width of the frame should not
2851 be changed. Optional fourth argument PIXELWISE non-nil means that FRAME
2852 should be WIDTH pixels wide. */)
2853 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
2855 struct frame *f = decode_live_frame (frame);
2856 int pixel_width;
2858 CHECK_TYPE_RANGED_INTEGER (int, width);
2860 pixel_width = (!NILP (pixelwise)
2861 ? XINT (width)
2862 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2863 if (pixel_width != FRAME_TEXT_WIDTH (f))
2864 adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend));
2866 return Qnil;
2869 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
2870 doc: /* Sets size of FRAME to WIDTH by HEIGHT, measured in characters.
2871 Optional argument PIXELWISE non-nil means to measure in pixels. */)
2872 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
2874 struct frame *f = decode_live_frame (frame);
2875 int pixel_width, pixel_height;
2877 CHECK_TYPE_RANGED_INTEGER (int, width);
2878 CHECK_TYPE_RANGED_INTEGER (int, height);
2880 pixel_width = (!NILP (pixelwise)
2881 ? XINT (width)
2882 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2883 pixel_height = (!NILP (pixelwise)
2884 ? XINT (height)
2885 : XINT (height) * FRAME_LINE_HEIGHT (f));
2887 if (pixel_width != FRAME_TEXT_WIDTH (f)
2888 || pixel_height != FRAME_TEXT_HEIGHT (f))
2889 adjust_frame_size (f, pixel_width, pixel_height, 1, 0);
2891 return Qnil;
2894 DEFUN ("set-frame-position", Fset_frame_position,
2895 Sset_frame_position, 3, 3, 0,
2896 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2897 If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are
2898 actually the position of the upper left corner of the frame. Negative
2899 values for XOFFSET or YOFFSET are interpreted relative to the rightmost
2900 or bottommost possible position (that stays within the screen). */)
2901 (Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset)
2903 register struct frame *f = decode_live_frame (frame);
2905 CHECK_TYPE_RANGED_INTEGER (int, xoffset);
2906 CHECK_TYPE_RANGED_INTEGER (int, yoffset);
2908 /* I think this should be done with a hook. */
2909 #ifdef HAVE_WINDOW_SYSTEM
2910 if (FRAME_WINDOW_P (f))
2911 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2912 #endif
2914 return Qt;
2918 /***********************************************************************
2919 Frame Parameters
2920 ***********************************************************************/
2922 /* Connect the frame-parameter names for X frames
2923 to the ways of passing the parameter values to the window system.
2925 The name of a parameter, as a Lisp symbol,
2926 has an `x-frame-parameter' property which is an integer in Lisp
2927 that is an index in this table. */
2929 struct frame_parm_table {
2930 const char *name;
2931 Lisp_Object *variable;
2934 static const struct frame_parm_table frame_parms[] =
2936 {"auto-raise", &Qauto_raise},
2937 {"auto-lower", &Qauto_lower},
2938 {"background-color", 0},
2939 {"border-color", &Qborder_color},
2940 {"border-width", &Qborder_width},
2941 {"cursor-color", &Qcursor_color},
2942 {"cursor-type", &Qcursor_type},
2943 {"font", 0},
2944 {"foreground-color", 0},
2945 {"icon-name", &Qicon_name},
2946 {"icon-type", &Qicon_type},
2947 {"internal-border-width", &Qinternal_border_width},
2948 {"right-divider-width", &Qright_divider_width},
2949 {"bottom-divider-width", &Qbottom_divider_width},
2950 {"menu-bar-lines", &Qmenu_bar_lines},
2951 {"mouse-color", &Qmouse_color},
2952 {"name", &Qname},
2953 {"scroll-bar-width", &Qscroll_bar_width},
2954 {"scroll-bar-height", &Qscroll_bar_height},
2955 {"title", &Qtitle},
2956 {"unsplittable", &Qunsplittable},
2957 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2958 {"horizontal-scroll-bars", &Qhorizontal_scroll_bars},
2959 {"visibility", &Qvisibility},
2960 {"tool-bar-lines", &Qtool_bar_lines},
2961 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2962 {"scroll-bar-background", &Qscroll_bar_background},
2963 {"screen-gamma", &Qscreen_gamma},
2964 {"line-spacing", &Qline_spacing},
2965 {"left-fringe", &Qleft_fringe},
2966 {"right-fringe", &Qright_fringe},
2967 {"wait-for-wm", &Qwait_for_wm},
2968 {"fullscreen", &Qfullscreen},
2969 {"font-backend", &Qfont_backend},
2970 {"alpha", &Qalpha},
2971 {"sticky", &Qsticky},
2972 {"tool-bar-position", &Qtool_bar_position},
2975 #ifdef HAVE_WINDOW_SYSTEM
2977 /* Change the parameters of frame F as specified by ALIST.
2978 If a parameter is not specially recognized, do nothing special;
2979 otherwise call the `x_set_...' function for that parameter.
2980 Except for certain geometry properties, always call store_frame_param
2981 to store the new value in the parameter alist. */
2983 void
2984 x_set_frame_parameters (struct frame *f, Lisp_Object alist)
2986 Lisp_Object tail;
2988 /* If both of these parameters are present, it's more efficient to
2989 set them both at once. So we wait until we've looked at the
2990 entire list before we set them. */
2991 int width IF_LINT (= 0), height IF_LINT (= 0);
2992 bool width_change = 0, height_change = 0;
2994 /* Same here. */
2995 Lisp_Object left, top;
2997 /* Same with these. */
2998 Lisp_Object icon_left, icon_top;
3000 /* Record in these vectors all the parms specified. */
3001 Lisp_Object *parms;
3002 Lisp_Object *values;
3003 ptrdiff_t i, p;
3004 bool left_no_change = 0, top_no_change = 0;
3005 #ifdef HAVE_X_WINDOWS
3006 bool icon_left_no_change = 0, icon_top_no_change = 0;
3007 #endif
3009 i = 0;
3010 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3011 i++;
3013 USE_SAFE_ALLOCA;
3014 SAFE_ALLOCA_LISP (parms, 2 * i);
3015 values = parms + i;
3017 /* Extract parm names and values into those vectors. */
3019 i = 0;
3020 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3022 Lisp_Object elt;
3024 elt = XCAR (tail);
3025 parms[i] = Fcar (elt);
3026 values[i] = Fcdr (elt);
3027 i++;
3029 /* TAIL and ALIST are not used again below here. */
3030 alist = tail = Qnil;
3032 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
3033 because their values appear in VALUES and strings are not valid. */
3034 top = left = Qunbound;
3035 icon_left = icon_top = Qunbound;
3037 /* Process foreground_color and background_color before anything else.
3038 They are independent of other properties, but other properties (e.g.,
3039 cursor_color) are dependent upon them. */
3040 /* Process default font as well, since fringe widths depends on it. */
3041 for (p = 0; p < i; p++)
3043 Lisp_Object prop, val;
3045 prop = parms[p];
3046 val = values[p];
3047 if (EQ (prop, Qforeground_color)
3048 || EQ (prop, Qbackground_color)
3049 || EQ (prop, Qfont))
3051 register Lisp_Object param_index, old_value;
3053 old_value = get_frame_param (f, prop);
3054 if (NILP (Fequal (val, old_value)))
3056 store_frame_param (f, prop, val);
3058 param_index = Fget (prop, Qx_frame_parameter);
3059 if (NATNUMP (param_index)
3060 && XFASTINT (param_index) < ARRAYELTS (frame_parms)
3061 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3062 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
3067 /* Now process them in reverse of specified order. */
3068 while (i-- != 0)
3070 Lisp_Object prop, val;
3072 prop = parms[i];
3073 val = values[i];
3075 if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX))
3077 width_change = 1;
3078 width = XFASTINT (val) * FRAME_COLUMN_WIDTH (f) ;
3080 else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX))
3082 height_change = 1;
3083 height = XFASTINT (val) * FRAME_LINE_HEIGHT (f);
3085 else if (EQ (prop, Qtop))
3086 top = val;
3087 else if (EQ (prop, Qleft))
3088 left = val;
3089 else if (EQ (prop, Qicon_top))
3090 icon_top = val;
3091 else if (EQ (prop, Qicon_left))
3092 icon_left = val;
3093 else if (EQ (prop, Qforeground_color)
3094 || EQ (prop, Qbackground_color)
3095 || EQ (prop, Qfont))
3096 /* Processed above. */
3097 continue;
3098 else
3100 register Lisp_Object param_index, old_value;
3102 old_value = get_frame_param (f, prop);
3104 store_frame_param (f, prop, val);
3106 param_index = Fget (prop, Qx_frame_parameter);
3107 if (NATNUMP (param_index)
3108 && XFASTINT (param_index) < ARRAYELTS (frame_parms)
3109 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3110 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
3114 /* Don't die if just one of these was set. */
3115 if (EQ (left, Qunbound))
3117 left_no_change = 1;
3118 if (f->left_pos < 0)
3119 left = list2 (Qplus, make_number (f->left_pos));
3120 else
3121 XSETINT (left, f->left_pos);
3123 if (EQ (top, Qunbound))
3125 top_no_change = 1;
3126 if (f->top_pos < 0)
3127 top = list2 (Qplus, make_number (f->top_pos));
3128 else
3129 XSETINT (top, f->top_pos);
3132 /* If one of the icon positions was not set, preserve or default it. */
3133 if (! TYPE_RANGED_INTEGERP (int, icon_left))
3135 #ifdef HAVE_X_WINDOWS
3136 icon_left_no_change = 1;
3137 #endif
3138 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
3139 if (NILP (icon_left))
3140 XSETINT (icon_left, 0);
3142 if (! TYPE_RANGED_INTEGERP (int, icon_top))
3144 #ifdef HAVE_X_WINDOWS
3145 icon_top_no_change = 1;
3146 #endif
3147 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
3148 if (NILP (icon_top))
3149 XSETINT (icon_top, 0);
3152 /* Don't set these parameters unless they've been explicitly
3153 specified. The window might be mapped or resized while we're in
3154 this function, and we don't want to override that unless the lisp
3155 code has asked for it.
3157 Don't set these parameters unless they actually differ from the
3158 window's current parameters; the window may not actually exist
3159 yet. */
3161 Lisp_Object frame;
3163 XSETFRAME (frame, f);
3165 if ((width_change && width != FRAME_TEXT_WIDTH (f))
3166 || (height_change && height != FRAME_TEXT_HEIGHT (f))
3167 || f->new_height || f->new_width)
3169 /* If necessary provide default values for HEIGHT and WIDTH. Do
3170 that here since otherwise a size change implied by an
3171 intermittent font change may get lost as in Bug#17142. */
3172 if (!width_change)
3173 width = (f->new_width
3174 ? (f->new_pixelwise
3175 ? f->new_width
3176 : (f->new_width * FRAME_COLUMN_WIDTH (f)))
3177 : FRAME_TEXT_WIDTH (f));
3179 if (!height_change)
3180 height = (f->new_height
3181 ? (f->new_pixelwise
3182 ? f->new_height
3183 : (f->new_height * FRAME_LINE_HEIGHT (f)))
3184 : FRAME_TEXT_HEIGHT (f));
3186 Fset_frame_size (frame, make_number (width), make_number (height), Qt);
3189 if ((!NILP (left) || !NILP (top))
3190 && ! (left_no_change && top_no_change)
3191 && ! (NUMBERP (left) && XINT (left) == f->left_pos
3192 && NUMBERP (top) && XINT (top) == f->top_pos))
3194 int leftpos = 0;
3195 int toppos = 0;
3197 /* Record the signs. */
3198 f->size_hint_flags &= ~ (XNegative | YNegative);
3199 if (EQ (left, Qminus))
3200 f->size_hint_flags |= XNegative;
3201 else if (TYPE_RANGED_INTEGERP (int, left))
3203 leftpos = XINT (left);
3204 if (leftpos < 0)
3205 f->size_hint_flags |= XNegative;
3207 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3208 && CONSP (XCDR (left))
3209 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
3211 leftpos = - XINT (XCAR (XCDR (left)));
3212 f->size_hint_flags |= XNegative;
3214 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3215 && CONSP (XCDR (left))
3216 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
3218 leftpos = XINT (XCAR (XCDR (left)));
3221 if (EQ (top, Qminus))
3222 f->size_hint_flags |= YNegative;
3223 else if (TYPE_RANGED_INTEGERP (int, top))
3225 toppos = XINT (top);
3226 if (toppos < 0)
3227 f->size_hint_flags |= YNegative;
3229 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3230 && CONSP (XCDR (top))
3231 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
3233 toppos = - XINT (XCAR (XCDR (top)));
3234 f->size_hint_flags |= YNegative;
3236 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3237 && CONSP (XCDR (top))
3238 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
3240 toppos = XINT (XCAR (XCDR (top)));
3244 /* Store the numeric value of the position. */
3245 f->top_pos = toppos;
3246 f->left_pos = leftpos;
3248 f->win_gravity = NorthWestGravity;
3250 /* Actually set that position, and convert to absolute. */
3251 x_set_offset (f, leftpos, toppos, -1);
3253 #ifdef HAVE_X_WINDOWS
3254 if ((!NILP (icon_left) || !NILP (icon_top))
3255 && ! (icon_left_no_change && icon_top_no_change))
3256 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3257 #endif /* HAVE_X_WINDOWS */
3260 SAFE_FREE ();
3264 /* Insert a description of internally-recorded parameters of frame X
3265 into the parameter alist *ALISTPTR that is to be given to the user.
3266 Only parameters that are specific to the X window system
3267 and whose values are not correctly recorded in the frame's
3268 param_alist need to be considered here. */
3270 void
3271 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
3273 Lisp_Object tem;
3274 uprintmax_t w;
3275 char buf[INT_BUFSIZE_BOUND (w)];
3277 /* Represent negative positions (off the top or left screen edge)
3278 in a way that Fmodify_frame_parameters will understand correctly. */
3279 XSETINT (tem, f->left_pos);
3280 if (f->left_pos >= 0)
3281 store_in_alist (alistptr, Qleft, tem);
3282 else
3283 store_in_alist (alistptr, Qleft, list2 (Qplus, tem));
3285 XSETINT (tem, f->top_pos);
3286 if (f->top_pos >= 0)
3287 store_in_alist (alistptr, Qtop, tem);
3288 else
3289 store_in_alist (alistptr, Qtop, list2 (Qplus, tem));
3291 store_in_alist (alistptr, Qborder_width,
3292 make_number (f->border_width));
3293 store_in_alist (alistptr, Qinternal_border_width,
3294 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
3295 store_in_alist (alistptr, Qright_divider_width,
3296 make_number (FRAME_RIGHT_DIVIDER_WIDTH (f)));
3297 store_in_alist (alistptr, Qbottom_divider_width,
3298 make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f)));
3299 store_in_alist (alistptr, Qleft_fringe,
3300 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
3301 store_in_alist (alistptr, Qright_fringe,
3302 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
3303 store_in_alist (alistptr, Qscroll_bar_width,
3304 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3305 ? make_number (0)
3306 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3307 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3308 /* nil means "use default width"
3309 for non-toolkit scroll bar.
3310 ruler-mode.el depends on this. */
3311 : Qnil));
3312 store_in_alist (alistptr, Qscroll_bar_height,
3313 (! FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)
3314 ? make_number (0)
3315 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0
3316 ? make_number (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f))
3317 /* nil means "use default height"
3318 for non-toolkit scroll bar. */
3319 : Qnil));
3320 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
3321 MS-Windows it returns a value whose type is HANDLE, which is
3322 actually a pointer. Explicit casting avoids compiler
3323 warnings. */
3324 w = (uintptr_t) FRAME_X_WINDOW (f);
3325 store_in_alist (alistptr, Qwindow_id,
3326 make_formatted_string (buf, "%"pMu, w));
3327 #ifdef HAVE_X_WINDOWS
3328 #ifdef USE_X_TOOLKIT
3329 /* Tooltip frame may not have this widget. */
3330 if (FRAME_X_OUTPUT (f)->widget)
3331 #endif
3332 w = (uintptr_t) FRAME_OUTER_WINDOW (f);
3333 store_in_alist (alistptr, Qouter_window_id,
3334 make_formatted_string (buf, "%"pMu, w));
3335 #endif
3336 store_in_alist (alistptr, Qicon_name, f->icon_name);
3337 store_in_alist (alistptr, Qvisibility,
3338 (FRAME_VISIBLE_P (f) ? Qt
3339 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3340 store_in_alist (alistptr, Qdisplay,
3341 XCAR (FRAME_DISPLAY_INFO (f)->name_list_element));
3343 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_DISPLAY_INFO (f)->root_window)
3344 tem = Qnil;
3345 else
3346 tem = make_natnum ((uintptr_t) FRAME_X_OUTPUT (f)->parent_desc);
3347 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
3348 store_in_alist (alistptr, Qparent_id, tem);
3349 store_in_alist (alistptr, Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f));
3353 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3354 the previous value of that parameter, NEW_VALUE is the new value. */
3356 void
3357 x_set_fullscreen (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3359 if (NILP (new_value))
3360 f->want_fullscreen = FULLSCREEN_NONE;
3361 else if (EQ (new_value, Qfullboth) || EQ (new_value, Qfullscreen))
3362 f->want_fullscreen = FULLSCREEN_BOTH;
3363 else if (EQ (new_value, Qfullwidth))
3364 f->want_fullscreen = FULLSCREEN_WIDTH;
3365 else if (EQ (new_value, Qfullheight))
3366 f->want_fullscreen = FULLSCREEN_HEIGHT;
3367 else if (EQ (new_value, Qmaximized))
3368 f->want_fullscreen = FULLSCREEN_MAXIMIZED;
3370 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
3371 FRAME_TERMINAL (f)->fullscreen_hook (f);
3375 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3376 the previous value of that parameter, NEW_VALUE is the new value. */
3378 void
3379 x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3381 if (NILP (new_value))
3382 f->extra_line_spacing = 0;
3383 else if (RANGED_INTEGERP (0, new_value, INT_MAX))
3384 f->extra_line_spacing = XFASTINT (new_value);
3385 else if (FLOATP (new_value))
3387 int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f) + 0.5;
3389 if (new_spacing >= 0)
3390 f->extra_line_spacing = new_spacing;
3391 else
3392 signal_error ("Invalid line-spacing", new_value);
3394 else
3395 signal_error ("Invalid line-spacing", new_value);
3396 if (FRAME_VISIBLE_P (f))
3397 redraw_frame (f);
3401 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3402 the previous value of that parameter, NEW_VALUE is the new value. */
3404 void
3405 x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3407 Lisp_Object bgcolor;
3409 if (NILP (new_value))
3410 f->gamma = 0;
3411 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3412 /* The value 0.4545 is the normal viewing gamma. */
3413 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3414 else
3415 signal_error ("Invalid screen-gamma", new_value);
3417 /* Apply the new gamma value to the frame background. */
3418 bgcolor = Fassq (Qbackground_color, f->param_alist);
3419 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3421 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
3422 if (NATNUMP (parm_index)
3423 && XFASTINT (parm_index) < ARRAYELTS (frame_parms)
3424 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3425 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3426 (f, bgcolor, Qnil);
3429 Fclear_face_cache (Qnil);
3433 void
3434 x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3436 Lisp_Object font_object;
3437 int fontset = -1;
3438 #ifdef HAVE_X_WINDOWS
3439 Lisp_Object font_param = arg;
3440 #endif
3442 /* Set the frame parameter back to the old value because we may
3443 fail to use ARG as the new parameter value. */
3444 store_frame_param (f, Qfont, oldval);
3446 /* ARG is a fontset name, a font name, a cons of fontset name and a
3447 font object, or a font object. In the last case, this function
3448 never fail. */
3449 if (STRINGP (arg))
3451 fontset = fs_query_fontset (arg, 0);
3452 if (fontset < 0)
3454 font_object = font_open_by_name (f, arg);
3455 if (NILP (font_object))
3456 error ("Font `%s' is not defined", SSDATA (arg));
3457 arg = AREF (font_object, FONT_NAME_INDEX);
3459 else if (fontset > 0)
3461 font_object = font_open_by_name (f, fontset_ascii (fontset));
3462 if (NILP (font_object))
3463 error ("Font `%s' is not defined", SDATA (arg));
3464 arg = AREF (font_object, FONT_NAME_INDEX);
3466 else
3467 error ("The default fontset can't be used for a frame font");
3469 else if (CONSP (arg) && STRINGP (XCAR (arg)) && FONT_OBJECT_P (XCDR (arg)))
3471 /* This is the case that the ASCII font of F's fontset XCAR
3472 (arg) is changed to the font XCDR (arg) by
3473 `set-fontset-font'. */
3474 fontset = fs_query_fontset (XCAR (arg), 0);
3475 if (fontset < 0)
3476 error ("Unknown fontset: %s", SDATA (XCAR (arg)));
3477 font_object = XCDR (arg);
3478 arg = AREF (font_object, FONT_NAME_INDEX);
3479 #ifdef HAVE_X_WINDOWS
3480 font_param = Ffont_get (font_object, QCname);
3481 #endif
3483 else if (FONT_OBJECT_P (arg))
3485 font_object = arg;
3486 #ifdef HAVE_X_WINDOWS
3487 font_param = Ffont_get (font_object, QCname);
3488 #endif
3489 /* This is to store the XLFD font name in the frame parameter for
3490 backward compatibility. We should store the font-object
3491 itself in the future. */
3492 arg = AREF (font_object, FONT_NAME_INDEX);
3493 fontset = FRAME_FONTSET (f);
3494 /* Check if we can use the current fontset. If not, set FONTSET
3495 to -1 to generate a new fontset from FONT-OBJECT. */
3496 if (fontset >= 0)
3498 Lisp_Object ascii_font = fontset_ascii (fontset);
3499 Lisp_Object spec = font_spec_from_name (ascii_font);
3501 if (NILP (spec))
3502 signal_error ("Invalid font name", ascii_font);
3504 if (! font_match_p (spec, font_object))
3505 fontset = -1;
3508 else
3509 signal_error ("Invalid font", arg);
3511 if (! NILP (Fequal (font_object, oldval)))
3512 return;
3514 x_new_font (f, font_object, fontset);
3515 store_frame_param (f, Qfont, arg);
3516 #ifdef HAVE_X_WINDOWS
3517 store_frame_param (f, Qfont_param, font_param);
3518 #endif
3519 /* Recalculate toolbar height. */
3520 f->n_tool_bar_rows = 0;
3522 /* Ensure we redraw it. */
3523 clear_current_matrices (f);
3525 /* Attempt to hunt down bug#16028. */
3526 SET_FRAME_GARBAGED (f);
3528 recompute_basic_faces (f);
3530 do_pending_window_change (0);
3532 /* We used to call face-set-after-frame-default here, but it leads to
3533 recursive calls (since that function can set the `default' face's
3534 font which in turns changes the frame's `font' parameter).
3535 Also I don't know what this call is meant to do, but it seems the
3536 wrong way to do it anyway (it does a lot more work than what seems
3537 reasonable in response to a change to `font'). */
3541 void
3542 x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3544 if (! NILP (new_value)
3545 && !CONSP (new_value))
3547 char *p0, *p1;
3549 CHECK_STRING (new_value);
3550 p0 = p1 = SSDATA (new_value);
3551 new_value = Qnil;
3552 while (*p0)
3554 while (*p1 && ! c_isspace (*p1) && *p1 != ',') p1++;
3555 if (p0 < p1)
3556 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3557 new_value);
3558 if (*p1)
3560 int c;
3562 while ((c = *++p1) && c_isspace (c));
3564 p0 = p1;
3566 new_value = Fnreverse (new_value);
3569 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3570 return;
3572 if (FRAME_FONT (f))
3573 free_all_realized_faces (Qnil);
3575 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
3576 if (NILP (new_value))
3578 if (NILP (old_value))
3579 error ("No font backend available");
3580 font_update_drivers (f, old_value);
3581 error ("None of specified font backends are available");
3583 store_frame_param (f, Qfont_backend, new_value);
3585 if (FRAME_FONT (f))
3587 Lisp_Object frame;
3589 XSETFRAME (frame, f);
3590 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3591 ++face_change_count;
3592 windows_or_buffers_changed = 18;
3596 void
3597 x_set_left_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3599 int unit = FRAME_COLUMN_WIDTH (f);
3600 int old_width = FRAME_LEFT_FRINGE_WIDTH (f);
3601 int new_width;
3603 new_width = (RANGED_INTEGERP (-INT_MAX, new_value, INT_MAX)
3604 ? eabs (XINT (new_value)) : 8);
3606 if (new_width != old_width)
3608 FRAME_LEFT_FRINGE_WIDTH (f) = new_width;
3609 FRAME_FRINGE_COLS (f) /* Round up. */
3610 = (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit;
3612 if (FRAME_X_WINDOW (f) != 0)
3613 adjust_frame_size (f, -1, -1, 3, 0);
3615 SET_FRAME_GARBAGED (f);
3620 void
3621 x_set_right_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3623 int unit = FRAME_COLUMN_WIDTH (f);
3624 int old_width = FRAME_RIGHT_FRINGE_WIDTH (f);
3625 int new_width;
3627 new_width = (RANGED_INTEGERP (-INT_MAX, new_value, INT_MAX)
3628 ? eabs (XINT (new_value)) : 8);
3630 if (new_width != old_width)
3632 FRAME_RIGHT_FRINGE_WIDTH (f) = new_width;
3633 FRAME_FRINGE_COLS (f) /* Round up. */
3634 = (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit;
3636 if (FRAME_X_WINDOW (f) != 0)
3637 adjust_frame_size (f, -1, -1, 3, 0);
3639 SET_FRAME_GARBAGED (f);
3644 void
3645 x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3647 CHECK_TYPE_RANGED_INTEGER (int, arg);
3649 if (XINT (arg) == f->border_width)
3650 return;
3652 if (FRAME_X_WINDOW (f) != 0)
3653 error ("Cannot change the border width of a frame");
3655 f->border_width = XINT (arg);
3658 void
3659 x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3661 int old = FRAME_RIGHT_DIVIDER_WIDTH (f);
3663 CHECK_TYPE_RANGED_INTEGER (int, arg);
3664 FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg);
3665 if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0)
3666 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
3667 if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old)
3669 adjust_frame_size (f, -1, -1, 4, 0);
3670 adjust_frame_glyphs (f);
3671 SET_FRAME_GARBAGED (f);
3676 void
3677 x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3679 int old = FRAME_BOTTOM_DIVIDER_WIDTH (f);
3681 CHECK_TYPE_RANGED_INTEGER (int, arg);
3682 FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg);
3683 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0)
3684 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
3685 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old)
3687 adjust_frame_size (f, -1, -1, 4, 0);
3688 adjust_frame_glyphs (f);
3689 SET_FRAME_GARBAGED (f);
3693 void
3694 x_set_visibility (struct frame *f, Lisp_Object value, Lisp_Object oldval)
3696 Lisp_Object frame;
3697 XSETFRAME (frame, f);
3699 if (NILP (value))
3700 Fmake_frame_invisible (frame, Qt);
3701 else if (EQ (value, Qicon))
3702 Ficonify_frame (frame);
3703 else
3704 Fmake_frame_visible (frame);
3707 void
3708 x_set_autoraise (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3710 f->auto_raise = !EQ (Qnil, arg);
3713 void
3714 x_set_autolower (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3716 f->auto_lower = !EQ (Qnil, arg);
3719 void
3720 x_set_unsplittable (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3722 f->no_split = !NILP (arg);
3725 void
3726 x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3728 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3729 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3730 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3731 || (!NILP (arg) && !FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3733 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3734 = (NILP (arg)
3735 ? vertical_scroll_bar_none
3736 : EQ (Qleft, arg)
3737 ? vertical_scroll_bar_left
3738 : EQ (Qright, arg)
3739 ? vertical_scroll_bar_right
3740 : EQ (Qleft, Vdefault_frame_scroll_bars)
3741 ? vertical_scroll_bar_left
3742 : EQ (Qright, Vdefault_frame_scroll_bars)
3743 ? vertical_scroll_bar_right
3744 : vertical_scroll_bar_none);
3746 /* We set this parameter before creating the X window for the
3747 frame, so we can get the geometry right from the start.
3748 However, if the window hasn't been created yet, we shouldn't
3749 call x_set_window_size. */
3750 if (FRAME_X_WINDOW (f))
3751 adjust_frame_size (f, -1, -1, 3, 0);
3753 SET_FRAME_GARBAGED (f);
3757 void
3758 x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3760 #if USE_HORIZONTAL_SCROLL_BARS
3761 if ((NILP (arg) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))
3762 || (!NILP (arg) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)))
3764 f->horizontal_scroll_bars = NILP (arg) ? false : true;
3766 /* We set this parameter before creating the X window for the
3767 frame, so we can get the geometry right from the start.
3768 However, if the window hasn't been created yet, we shouldn't
3769 call x_set_window_size. */
3770 if (FRAME_X_WINDOW (f))
3771 adjust_frame_size (f, -1, -1, 3, 0);
3773 SET_FRAME_GARBAGED (f);
3775 #endif
3778 void
3779 x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3781 int unit = FRAME_COLUMN_WIDTH (f);
3783 if (NILP (arg))
3785 x_set_scroll_bar_default_width (f);
3787 if (FRAME_X_WINDOW (f))
3788 adjust_frame_size (f, -1, -1, 3, 0);
3790 SET_FRAME_GARBAGED (f);
3792 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3793 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3795 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3796 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
3797 if (FRAME_X_WINDOW (f))
3798 adjust_frame_size (f, -1, -1, 3, 0);
3800 SET_FRAME_GARBAGED (f);
3803 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3804 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3807 void
3808 x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3810 #if USE_HORIZONTAL_SCROLL_BARS
3811 int unit = FRAME_LINE_HEIGHT (f);
3813 if (NILP (arg))
3815 x_set_scroll_bar_default_height (f);
3817 if (FRAME_X_WINDOW (f))
3818 adjust_frame_size (f, -1, -1, 3, 0);
3820 SET_FRAME_GARBAGED (f);
3822 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3823 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_HEIGHT (f))
3825 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg);
3826 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit;
3827 if (FRAME_X_WINDOW (f))
3828 adjust_frame_size (f, -1, -1, 3, 0);
3830 SET_FRAME_GARBAGED (f);
3833 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.vpos = 0;
3834 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.y = 0;
3835 #endif
3838 void
3839 x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3841 double alpha = 1.0;
3842 double newval[2];
3843 int i;
3844 Lisp_Object item;
3846 for (i = 0; i < 2; i++)
3848 newval[i] = 1.0;
3849 if (CONSP (arg))
3851 item = CAR (arg);
3852 arg = CDR (arg);
3854 else
3855 item = arg;
3857 if (NILP (item))
3858 alpha = - 1.0;
3859 else if (FLOATP (item))
3861 alpha = XFLOAT_DATA (item);
3862 if (! (0 <= alpha && alpha <= 1.0))
3863 args_out_of_range (make_float (0.0), make_float (1.0));
3865 else if (INTEGERP (item))
3867 EMACS_INT ialpha = XINT (item);
3868 if (! (0 <= ialpha && alpha <= 100))
3869 args_out_of_range (make_number (0), make_number (100));
3870 alpha = ialpha / 100.0;
3872 else
3873 wrong_type_argument (Qnumberp, item);
3874 newval[i] = alpha;
3877 for (i = 0; i < 2; i++)
3878 f->alpha[i] = newval[i];
3880 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3881 block_input ();
3882 x_set_frame_alpha (f);
3883 unblock_input ();
3884 #endif
3886 return;
3889 #ifndef HAVE_NS
3891 /* Non-zero if mouse is grabbed on DPYINFO
3892 and we know the frame where it is. */
3894 bool x_mouse_grabbed (Display_Info *dpyinfo)
3896 return (dpyinfo->grabbed
3897 && dpyinfo->last_mouse_frame
3898 && FRAME_LIVE_P (dpyinfo->last_mouse_frame));
3901 /* Re-highlight something with mouse-face properties
3902 on DPYINFO using saved frame and mouse position. */
3904 void
3905 x_redo_mouse_highlight (Display_Info *dpyinfo)
3907 if (dpyinfo->last_mouse_motion_frame
3908 && FRAME_LIVE_P (dpyinfo->last_mouse_motion_frame))
3909 note_mouse_highlight (dpyinfo->last_mouse_motion_frame,
3910 dpyinfo->last_mouse_motion_x,
3911 dpyinfo->last_mouse_motion_y);
3914 #endif /* HAVE_NS */
3916 /* Subroutines of creating an X frame. */
3918 /* Make sure that Vx_resource_name is set to a reasonable value.
3919 Fix it up, or set it to `emacs' if it is too hopeless. */
3921 void
3922 validate_x_resource_name (void)
3924 ptrdiff_t len = 0;
3925 /* Number of valid characters in the resource name. */
3926 ptrdiff_t good_count = 0;
3927 /* Number of invalid characters in the resource name. */
3928 ptrdiff_t bad_count = 0;
3929 Lisp_Object new;
3930 ptrdiff_t i;
3932 if (!STRINGP (Vx_resource_class))
3933 Vx_resource_class = build_string (EMACS_CLASS);
3935 if (STRINGP (Vx_resource_name))
3937 unsigned char *p = SDATA (Vx_resource_name);
3939 len = SBYTES (Vx_resource_name);
3941 /* Only letters, digits, - and _ are valid in resource names.
3942 Count the valid characters and count the invalid ones. */
3943 for (i = 0; i < len; i++)
3945 int c = p[i];
3946 if (! ((c >= 'a' && c <= 'z')
3947 || (c >= 'A' && c <= 'Z')
3948 || (c >= '0' && c <= '9')
3949 || c == '-' || c == '_'))
3950 bad_count++;
3951 else
3952 good_count++;
3955 else
3956 /* Not a string => completely invalid. */
3957 bad_count = 5, good_count = 0;
3959 /* If name is valid already, return. */
3960 if (bad_count == 0)
3961 return;
3963 /* If name is entirely invalid, or nearly so, or is so implausibly
3964 large that alloca might not work, use `emacs'. */
3965 if (good_count < 2 || MAX_ALLOCA - sizeof ".customization" < len)
3967 Vx_resource_name = build_string ("emacs");
3968 return;
3971 /* Name is partly valid. Copy it and replace the invalid characters
3972 with underscores. */
3974 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3976 for (i = 0; i < len; i++)
3978 int c = SREF (new, i);
3979 if (! ((c >= 'a' && c <= 'z')
3980 || (c >= 'A' && c <= 'Z')
3981 || (c >= '0' && c <= '9')
3982 || c == '-' || c == '_'))
3983 SSET (new, i, '_');
3987 /* Get specified attribute from resource database RDB.
3988 See Fx_get_resource below for other parameters. */
3990 static Lisp_Object
3991 xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3993 CHECK_STRING (attribute);
3994 CHECK_STRING (class);
3996 if (!NILP (component))
3997 CHECK_STRING (component);
3998 if (!NILP (subclass))
3999 CHECK_STRING (subclass);
4000 if (NILP (component) != NILP (subclass))
4001 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
4003 validate_x_resource_name ();
4005 /* Allocate space for the components, the dots which separate them,
4006 and the final '\0'. Make them big enough for the worst case. */
4007 ptrdiff_t name_keysize = (SBYTES (Vx_resource_name)
4008 + (STRINGP (component)
4009 ? SBYTES (component) : 0)
4010 + SBYTES (attribute)
4011 + 3);
4013 ptrdiff_t class_keysize = (SBYTES (Vx_resource_class)
4014 + SBYTES (class)
4015 + (STRINGP (subclass)
4016 ? SBYTES (subclass) : 0)
4017 + 3);
4018 USE_SAFE_ALLOCA;
4019 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
4020 char *class_key = name_key + name_keysize;
4022 /* Start with emacs.FRAMENAME for the name (the specific one)
4023 and with `Emacs' for the class key (the general one). */
4024 lispstpcpy (name_key, Vx_resource_name);
4025 lispstpcpy (class_key, Vx_resource_class);
4027 strcat (class_key, ".");
4028 strcat (class_key, SSDATA (class));
4030 if (!NILP (component))
4032 strcat (class_key, ".");
4033 strcat (class_key, SSDATA (subclass));
4035 strcat (name_key, ".");
4036 strcat (name_key, SSDATA (component));
4039 strcat (name_key, ".");
4040 strcat (name_key, SSDATA (attribute));
4042 char *value = x_get_string_resource (rdb, name_key, class_key);
4043 SAFE_FREE();
4045 if (value && *value)
4046 return build_string (value);
4047 else
4048 return Qnil;
4052 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
4053 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
4054 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
4055 class, where INSTANCE is the name under which Emacs was invoked, or
4056 the name specified by the `-name' or `-rn' command-line arguments.
4058 The optional arguments COMPONENT and SUBCLASS add to the key and the
4059 class, respectively. You must specify both of them or neither.
4060 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
4061 and the class is `Emacs.CLASS.SUBCLASS'. */)
4062 (Lisp_Object attribute, Lisp_Object class, Lisp_Object component,
4063 Lisp_Object subclass)
4065 check_window_system (NULL);
4067 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
4068 attribute, class, component, subclass);
4071 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
4073 Lisp_Object
4074 display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
4075 Lisp_Object class, Lisp_Object component,
4076 Lisp_Object subclass)
4078 return xrdb_get_resource (dpyinfo->xrdb,
4079 attribute, class, component, subclass);
4082 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
4083 /* Used when C code wants a resource value. */
4084 /* Called from oldXMenu/Create.c. */
4085 char *
4086 x_get_resource_string (const char *attribute, const char *class)
4088 char *result;
4089 struct frame *sf = SELECTED_FRAME ();
4090 ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
4091 USE_SAFE_ALLOCA;
4093 /* Allocate space for the components, the dots which separate them,
4094 and the final '\0'. */
4095 ptrdiff_t name_keysize = invocation_namelen + strlen (attribute) + 2;
4096 ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2;
4097 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
4098 char *class_key = name_key + name_keysize;
4100 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
4101 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
4103 result = x_get_string_resource (FRAME_DISPLAY_INFO (sf)->xrdb,
4104 name_key, class_key);
4105 SAFE_FREE ();
4106 return result;
4108 #endif
4110 /* Return the value of parameter PARAM.
4112 First search ALIST, then Vdefault_frame_alist, then the X defaults
4113 database, using ATTRIBUTE as the attribute name and CLASS as its class.
4115 Convert the resource to the type specified by desired_type.
4117 If no default is specified, return Qunbound. If you call
4118 x_get_arg, make sure you deal with Qunbound in a reasonable way,
4119 and don't let it get stored in any Lisp-visible variables! */
4121 Lisp_Object
4122 x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
4123 const char *attribute, const char *class, enum resource_types type)
4125 Lisp_Object tem;
4127 tem = Fassq (param, alist);
4129 if (!NILP (tem))
4131 /* If we find this parm in ALIST, clear it out
4132 so that it won't be "left over" at the end. */
4133 Lisp_Object tail;
4134 XSETCAR (tem, Qnil);
4135 /* In case the parameter appears more than once in the alist,
4136 clear it out. */
4137 for (tail = alist; CONSP (tail); tail = XCDR (tail))
4138 if (CONSP (XCAR (tail))
4139 && EQ (XCAR (XCAR (tail)), param))
4140 XSETCAR (XCAR (tail), Qnil);
4142 else
4143 tem = Fassq (param, Vdefault_frame_alist);
4145 /* If it wasn't specified in ALIST or the Lisp-level defaults,
4146 look in the X resources. */
4147 if (EQ (tem, Qnil))
4149 if (attribute && dpyinfo)
4151 AUTO_STRING (at, attribute);
4152 AUTO_STRING (cl, class);
4153 tem = display_x_get_resource (dpyinfo, at, cl, Qnil, Qnil);
4155 if (NILP (tem))
4156 return Qunbound;
4158 switch (type)
4160 case RES_TYPE_NUMBER:
4161 return make_number (atoi (SSDATA (tem)));
4163 case RES_TYPE_BOOLEAN_NUMBER:
4164 if (!strcmp (SSDATA (tem), "on")
4165 || !strcmp (SSDATA (tem), "true"))
4166 return make_number (1);
4167 return make_number (atoi (SSDATA (tem)));
4168 break;
4170 case RES_TYPE_FLOAT:
4171 return make_float (atof (SSDATA (tem)));
4173 case RES_TYPE_BOOLEAN:
4174 tem = Fdowncase (tem);
4175 if (!strcmp (SSDATA (tem), "on")
4176 #ifdef HAVE_NS
4177 || !strcmp (SSDATA (tem), "yes")
4178 #endif
4179 || !strcmp (SSDATA (tem), "true"))
4180 return Qt;
4181 else
4182 return Qnil;
4184 case RES_TYPE_STRING:
4185 return tem;
4187 case RES_TYPE_SYMBOL:
4188 /* As a special case, we map the values `true' and `on'
4189 to Qt, and `false' and `off' to Qnil. */
4191 Lisp_Object lower;
4192 lower = Fdowncase (tem);
4193 if (!strcmp (SSDATA (lower), "on")
4194 #ifdef HAVE_NS
4195 || !strcmp (SSDATA (lower), "yes")
4196 #endif
4197 || !strcmp (SSDATA (lower), "true"))
4198 return Qt;
4199 else if (!strcmp (SSDATA (lower), "off")
4200 #ifdef HAVE_NS
4201 || !strcmp (SSDATA (lower), "no")
4202 #endif
4203 || !strcmp (SSDATA (lower), "false"))
4204 return Qnil;
4205 else
4206 return Fintern (tem, Qnil);
4209 default:
4210 emacs_abort ();
4213 else
4214 return Qunbound;
4216 return Fcdr (tem);
4219 static Lisp_Object
4220 x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param,
4221 const char *attribute, const char *class,
4222 enum resource_types type)
4224 return x_get_arg (FRAME_DISPLAY_INFO (f),
4225 alist, param, attribute, class, type);
4228 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
4230 Lisp_Object
4231 x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist,
4232 Lisp_Object param,
4233 const char *attribute, const char *class,
4234 enum resource_types type)
4236 Lisp_Object value;
4238 value = x_get_arg (FRAME_DISPLAY_INFO (f), alist, param,
4239 attribute, class, type);
4240 if (! NILP (value) && ! EQ (value, Qunbound))
4241 store_frame_param (f, param, value);
4243 return value;
4247 /* Record in frame F the specified or default value according to ALIST
4248 of the parameter named PROP (a Lisp symbol).
4249 If no value is specified for PROP, look for an X default for XPROP
4250 on the frame named NAME.
4251 If that is not found either, use the value DEFLT. */
4253 Lisp_Object
4254 x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
4255 Lisp_Object deflt, const char *xprop, const char *xclass,
4256 enum resource_types type)
4258 Lisp_Object tem;
4260 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
4261 if (EQ (tem, Qunbound))
4262 tem = deflt;
4263 AUTO_FRAME_ARG (arg, prop, tem);
4264 x_set_frame_parameters (f, arg);
4265 return tem;
4269 #if !defined (HAVE_X_WINDOWS) && defined (NoValue)
4272 * XParseGeometry parses strings of the form
4273 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
4274 * width, height, xoffset, and yoffset are unsigned integers.
4275 * Example: "=80x24+300-49"
4276 * The equal sign is optional.
4277 * It returns a bitmask that indicates which of the four values
4278 * were actually found in the string. For each value found,
4279 * the corresponding argument is updated; for each value
4280 * not found, the corresponding argument is left unchanged.
4283 static int
4284 XParseGeometry (char *string,
4285 int *x, int *y,
4286 unsigned int *width, unsigned int *height)
4288 int mask = NoValue;
4289 char *strind;
4290 unsigned long tempWidth, tempHeight;
4291 long int tempX, tempY;
4292 char *nextCharacter;
4294 if (string == NULL || *string == '\0')
4295 return mask;
4296 if (*string == '=')
4297 string++; /* ignore possible '=' at beg of geometry spec */
4299 strind = string;
4300 if (*strind != '+' && *strind != '-' && *strind != 'x')
4302 tempWidth = strtoul (strind, &nextCharacter, 10);
4303 if (strind == nextCharacter)
4304 return 0;
4305 strind = nextCharacter;
4306 mask |= WidthValue;
4309 if (*strind == 'x' || *strind == 'X')
4311 strind++;
4312 tempHeight = strtoul (strind, &nextCharacter, 10);
4313 if (strind == nextCharacter)
4314 return 0;
4315 strind = nextCharacter;
4316 mask |= HeightValue;
4319 if (*strind == '+' || *strind == '-')
4321 if (*strind == '-')
4322 mask |= XNegative;
4323 tempX = strtol (strind, &nextCharacter, 10);
4324 if (strind == nextCharacter)
4325 return 0;
4326 strind = nextCharacter;
4327 mask |= XValue;
4328 if (*strind == '+' || *strind == '-')
4330 if (*strind == '-')
4331 mask |= YNegative;
4332 tempY = strtol (strind, &nextCharacter, 10);
4333 if (strind == nextCharacter)
4334 return 0;
4335 strind = nextCharacter;
4336 mask |= YValue;
4340 /* If strind isn't at the end of the string then it's an invalid
4341 geometry specification. */
4343 if (*strind != '\0')
4344 return 0;
4346 if (mask & XValue)
4347 *x = clip_to_bounds (INT_MIN, tempX, INT_MAX);
4348 if (mask & YValue)
4349 *y = clip_to_bounds (INT_MIN, tempY, INT_MAX);
4350 if (mask & WidthValue)
4351 *width = min (tempWidth, UINT_MAX);
4352 if (mask & HeightValue)
4353 *height = min (tempHeight, UINT_MAX);
4354 return mask;
4357 #endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
4360 /* NS used to define x-parse-geometry in ns-win.el, but that confused
4361 make-docfile: the documentation string in ns-win.el was used for
4362 x-parse-geometry even in non-NS builds.
4364 With two definitions of x-parse-geometry in this file, various
4365 things still get confused (eg M-x apropos documentation), so that
4366 it is best if the two definitions just share the same doc-string.
4368 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4369 doc: /* Parse a display geometry string STRING.
4370 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4371 The properties returned may include `top', `left', `height', and `width'.
4372 For X, the value of `left' or `top' may be an integer,
4373 or a list (+ N) meaning N pixels relative to top/left corner,
4374 or a list (- N) meaning -N pixels relative to bottom/right corner.
4375 On Nextstep, this just calls `ns-parse-geometry'. */)
4376 (Lisp_Object string)
4378 int geometry, x, y;
4379 unsigned int width, height;
4380 Lisp_Object result;
4382 CHECK_STRING (string);
4384 #ifdef HAVE_NS
4385 if (strchr (SSDATA (string), ' ') != NULL)
4386 return call1 (Qns_parse_geometry, string);
4387 #endif
4388 geometry = XParseGeometry (SSDATA (string),
4389 &x, &y, &width, &height);
4390 result = Qnil;
4391 if (geometry & XValue)
4393 Lisp_Object element;
4395 if (x >= 0 && (geometry & XNegative))
4396 element = list3 (Qleft, Qminus, make_number (-x));
4397 else if (x < 0 && ! (geometry & XNegative))
4398 element = list3 (Qleft, Qplus, make_number (x));
4399 else
4400 element = Fcons (Qleft, make_number (x));
4401 result = Fcons (element, result);
4404 if (geometry & YValue)
4406 Lisp_Object element;
4408 if (y >= 0 && (geometry & YNegative))
4409 element = list3 (Qtop, Qminus, make_number (-y));
4410 else if (y < 0 && ! (geometry & YNegative))
4411 element = list3 (Qtop, Qplus, make_number (y));
4412 else
4413 element = Fcons (Qtop, make_number (y));
4414 result = Fcons (element, result);
4417 if (geometry & WidthValue)
4418 result = Fcons (Fcons (Qwidth, make_number (width)), result);
4419 if (geometry & HeightValue)
4420 result = Fcons (Fcons (Qheight, make_number (height)), result);
4422 return result;
4426 /* Calculate the desired size and position of frame F.
4427 Return the flags saying which aspects were specified.
4429 Also set the win_gravity and size_hint_flags of F.
4431 Adjust height for toolbar if TOOLBAR_P is 1.
4433 This function does not make the coordinates positive. */
4435 #define DEFAULT_ROWS 35
4436 #define DEFAULT_COLS 80
4438 long
4439 x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4441 Lisp_Object height, width, user_size, top, left, user_position;
4442 long window_prompting = 0;
4443 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
4445 /* Default values if we fall through.
4446 Actually, if that happens we should get
4447 window manager prompting. */
4448 SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
4449 SET_FRAME_COLS (f, DEFAULT_COLS);
4450 SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
4451 SET_FRAME_LINES (f, DEFAULT_ROWS);
4453 /* Window managers expect that if program-specified
4454 positions are not (0,0), they're intentional, not defaults. */
4455 f->top_pos = 0;
4456 f->left_pos = 0;
4458 /* Ensure that earlier new_width and new_height settings won't
4459 override what we specify below. */
4460 f->new_width = f->new_height = 0;
4462 height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4463 width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4464 if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
4466 if (!EQ (width, Qunbound))
4468 CHECK_NUMBER (width);
4469 if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
4470 xsignal1 (Qargs_out_of_range, width);
4472 SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
4475 if (!EQ (height, Qunbound))
4477 CHECK_NUMBER (height);
4478 if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
4479 xsignal1 (Qargs_out_of_range, height);
4481 SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
4484 user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4485 if (!NILP (user_size) && !EQ (user_size, Qunbound))
4486 window_prompting |= USSize;
4487 else
4488 window_prompting |= PSize;
4491 /* Add a tool bar height to the initial frame height so that the user
4492 gets a text display area of the size he specified with -g or via
4493 .Xdefaults. Later changes of the tool bar height don't change the
4494 frame size. This is done so that users can create tall Emacs
4495 frames without having to guess how tall the tool bar will get. */
4496 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4498 int margin, relief;
4500 relief = (tool_bar_button_relief >= 0
4501 ? tool_bar_button_relief
4502 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4504 if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX))
4505 margin = XFASTINT (Vtool_bar_button_margin);
4506 else if (CONSP (Vtool_bar_button_margin)
4507 && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX))
4508 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4509 else
4510 margin = 0;
4512 FRAME_TOOL_BAR_HEIGHT (f)
4513 = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4514 Vframe_initial_frame_tool_bar_height = make_number (FRAME_TOOL_BAR_HEIGHT (f));
4517 top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4518 left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4519 user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4520 if (! EQ (top, Qunbound) || ! EQ (left, Qunbound))
4522 if (EQ (top, Qminus))
4524 f->top_pos = 0;
4525 window_prompting |= YNegative;
4527 else if (CONSP (top) && EQ (XCAR (top), Qminus)
4528 && CONSP (XCDR (top))
4529 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
4531 f->top_pos = - XINT (XCAR (XCDR (top)));
4532 window_prompting |= YNegative;
4534 else if (CONSP (top) && EQ (XCAR (top), Qplus)
4535 && CONSP (XCDR (top))
4536 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
4538 f->top_pos = XINT (XCAR (XCDR (top)));
4540 else if (EQ (top, Qunbound))
4541 f->top_pos = 0;
4542 else
4544 CHECK_TYPE_RANGED_INTEGER (int, top);
4545 f->top_pos = XINT (top);
4546 if (f->top_pos < 0)
4547 window_prompting |= YNegative;
4550 if (EQ (left, Qminus))
4552 f->left_pos = 0;
4553 window_prompting |= XNegative;
4555 else if (CONSP (left) && EQ (XCAR (left), Qminus)
4556 && CONSP (XCDR (left))
4557 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
4559 f->left_pos = - XINT (XCAR (XCDR (left)));
4560 window_prompting |= XNegative;
4562 else if (CONSP (left) && EQ (XCAR (left), Qplus)
4563 && CONSP (XCDR (left))
4564 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
4566 f->left_pos = XINT (XCAR (XCDR (left)));
4568 else if (EQ (left, Qunbound))
4569 f->left_pos = 0;
4570 else
4572 CHECK_TYPE_RANGED_INTEGER (int, left);
4573 f->left_pos = XINT (left);
4574 if (f->left_pos < 0)
4575 window_prompting |= XNegative;
4578 if (!NILP (user_position) && ! EQ (user_position, Qunbound))
4579 window_prompting |= USPosition;
4580 else
4581 window_prompting |= PPosition;
4584 if (window_prompting & XNegative)
4586 if (window_prompting & YNegative)
4587 f->win_gravity = SouthEastGravity;
4588 else
4589 f->win_gravity = NorthEastGravity;
4591 else
4593 if (window_prompting & YNegative)
4594 f->win_gravity = SouthWestGravity;
4595 else
4596 f->win_gravity = NorthWestGravity;
4599 f->size_hint_flags = window_prompting;
4601 return window_prompting;
4606 #endif /* HAVE_WINDOW_SYSTEM */
4608 void
4609 frame_make_pointer_invisible (struct frame *f)
4611 if (! NILP (Vmake_pointer_invisible))
4613 if (f && FRAME_LIVE_P (f) && !f->pointer_invisible
4614 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4616 f->mouse_moved = 0;
4617 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 1);
4618 f->pointer_invisible = 1;
4623 void
4624 frame_make_pointer_visible (struct frame *f)
4626 /* We don't check Vmake_pointer_invisible here in case the
4627 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4628 if (f && FRAME_LIVE_P (f) && f->pointer_invisible && f->mouse_moved
4629 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4631 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 0);
4632 f->pointer_invisible = 0;
4636 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p,
4637 Sframe_pointer_visible_p, 0, 1, 0,
4638 doc: /* Return t if the mouse pointer displayed on FRAME is visible.
4639 Otherwise it returns nil. FRAME omitted or nil means the
4640 selected frame. This is useful when `make-pointer-invisible' is set. */)
4641 (Lisp_Object frame)
4643 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
4648 /***********************************************************************
4649 Multimonitor data
4650 ***********************************************************************/
4652 #ifdef HAVE_WINDOW_SYSTEM
4654 # if (defined HAVE_NS \
4655 || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR)))
4656 void
4657 free_monitors (struct MonitorInfo *monitors, int n_monitors)
4659 int i;
4660 for (i = 0; i < n_monitors; ++i)
4661 xfree (monitors[i].name);
4662 xfree (monitors);
4664 # endif
4666 Lisp_Object
4667 make_monitor_attribute_list (struct MonitorInfo *monitors,
4668 int n_monitors,
4669 int primary_monitor,
4670 Lisp_Object monitor_frames,
4671 const char *source)
4673 Lisp_Object attributes_list = Qnil;
4674 Lisp_Object primary_monitor_attributes = Qnil;
4675 int i;
4677 for (i = 0; i < n_monitors; ++i)
4679 Lisp_Object geometry, workarea, attributes = Qnil;
4680 struct MonitorInfo *mi = &monitors[i];
4682 if (mi->geom.width == 0) continue;
4684 workarea = list4i (mi->work.x, mi->work.y,
4685 mi->work.width, mi->work.height);
4686 geometry = list4i (mi->geom.x, mi->geom.y,
4687 mi->geom.width, mi->geom.height);
4688 attributes = Fcons (Fcons (Qsource, build_string (source)),
4689 attributes);
4690 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
4691 attributes);
4692 attributes = Fcons (Fcons (Qmm_size,
4693 list2i (mi->mm_width, mi->mm_height)),
4694 attributes);
4695 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
4696 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
4697 if (mi->name)
4698 attributes = Fcons (Fcons (Qname, make_string (mi->name,
4699 strlen (mi->name))),
4700 attributes);
4702 if (i == primary_monitor)
4703 primary_monitor_attributes = attributes;
4704 else
4705 attributes_list = Fcons (attributes, attributes_list);
4708 if (!NILP (primary_monitor_attributes))
4709 attributes_list = Fcons (primary_monitor_attributes, attributes_list);
4710 return attributes_list;
4713 #endif /* HAVE_WINDOW_SYSTEM */
4716 /***********************************************************************
4717 Initialization
4718 ***********************************************************************/
4720 void
4721 syms_of_frame (void)
4723 DEFSYM (Qframep, "framep");
4724 DEFSYM (Qframe_live_p, "frame-live-p");
4725 DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
4726 DEFSYM (Qexplicit_name, "explicit-name");
4727 DEFSYM (Qheight, "height");
4728 DEFSYM (Qicon, "icon");
4729 DEFSYM (Qminibuffer, "minibuffer");
4730 DEFSYM (Qmodeline, "modeline");
4731 DEFSYM (Qonly, "only");
4732 DEFSYM (Qnone, "none");
4733 DEFSYM (Qwidth, "width");
4734 DEFSYM (Qgeometry, "geometry");
4735 DEFSYM (Qicon_left, "icon-left");
4736 DEFSYM (Qicon_top, "icon-top");
4737 DEFSYM (Qtooltip, "tooltip");
4738 DEFSYM (Quser_position, "user-position");
4739 DEFSYM (Quser_size, "user-size");
4740 DEFSYM (Qwindow_id, "window-id");
4741 #ifdef HAVE_X_WINDOWS
4742 DEFSYM (Qouter_window_id, "outer-window-id");
4743 #endif
4744 DEFSYM (Qparent_id, "parent-id");
4745 DEFSYM (Qx, "x");
4746 DEFSYM (Qw32, "w32");
4747 DEFSYM (Qpc, "pc");
4748 DEFSYM (Qns, "ns");
4749 DEFSYM (Qvisible, "visible");
4750 DEFSYM (Qbuffer_predicate, "buffer-predicate");
4751 DEFSYM (Qbuffer_list, "buffer-list");
4752 DEFSYM (Qburied_buffer_list, "buried-buffer-list");
4753 DEFSYM (Qdisplay_type, "display-type");
4754 DEFSYM (Qbackground_mode, "background-mode");
4755 DEFSYM (Qnoelisp, "noelisp");
4756 DEFSYM (Qtty_color_mode, "tty-color-mode");
4757 DEFSYM (Qtty, "tty");
4758 DEFSYM (Qtty_type, "tty-type");
4760 DEFSYM (Qface_set_after_frame_default, "face-set-after-frame-default");
4762 DEFSYM (Qfullwidth, "fullwidth");
4763 DEFSYM (Qfullheight, "fullheight");
4764 DEFSYM (Qfullboth, "fullboth");
4765 DEFSYM (Qmaximized, "maximized");
4766 DEFSYM (Qx_resource_name, "x-resource-name");
4767 DEFSYM (Qx_frame_parameter, "x-frame-parameter");
4769 DEFSYM (Qterminal, "terminal");
4771 DEFSYM (Qgeometry, "geometry");
4772 DEFSYM (Qworkarea, "workarea");
4773 DEFSYM (Qmm_size, "mm-size");
4774 DEFSYM (Qframes, "frames");
4775 DEFSYM (Qsource, "source");
4777 #ifdef HAVE_NS
4778 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
4779 #endif
4782 int i;
4784 for (i = 0; i < ARRAYELTS (frame_parms); i++)
4786 Lisp_Object v = intern_c_string (frame_parms[i].name);
4787 if (frame_parms[i].variable)
4789 *frame_parms[i].variable = v;
4790 staticpro (frame_parms[i].variable);
4792 Fput (v, Qx_frame_parameter, make_number (i));
4796 #ifdef HAVE_WINDOW_SYSTEM
4797 DEFVAR_LISP ("x-resource-name", Vx_resource_name,
4798 doc: /* The name Emacs uses to look up X resources.
4799 `x-get-resource' uses this as the first component of the instance name
4800 when requesting resource values.
4801 Emacs initially sets `x-resource-name' to the name under which Emacs
4802 was invoked, or to the value specified with the `-name' or `-rn'
4803 switches, if present.
4805 It may be useful to bind this variable locally around a call
4806 to `x-get-resource'. See also the variable `x-resource-class'. */);
4807 Vx_resource_name = Qnil;
4809 DEFVAR_LISP ("x-resource-class", Vx_resource_class,
4810 doc: /* The class Emacs uses to look up X resources.
4811 `x-get-resource' uses this as the first component of the instance class
4812 when requesting resource values.
4814 Emacs initially sets `x-resource-class' to "Emacs".
4816 Setting this variable permanently is not a reasonable thing to do,
4817 but binding this variable locally around a call to `x-get-resource'
4818 is a reasonable practice. See also the variable `x-resource-name'. */);
4819 Vx_resource_class = build_string (EMACS_CLASS);
4821 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit,
4822 doc: /* The lower limit of the frame opacity (alpha transparency).
4823 The value should range from 0 (invisible) to 100 (completely opaque).
4824 You can also use a floating number between 0.0 and 1.0. */);
4825 Vframe_alpha_lower_limit = make_number (20);
4826 #endif
4828 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist,
4829 doc: /* Alist of default values for frame creation.
4830 These may be set in your init file, like this:
4831 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4832 These override values given in window system configuration data,
4833 including X Windows' defaults database.
4834 For values specific to the first Emacs frame, see `initial-frame-alist'.
4835 For window-system specific values, see `window-system-default-frame-alist'.
4836 For values specific to the separate minibuffer frame, see
4837 `minibuffer-frame-alist'.
4838 The `menu-bar-lines' element of the list controls whether new frames
4839 have menu bars; `menu-bar-mode' works by altering this element.
4840 Setting this variable does not affect existing frames, only new ones. */);
4841 Vdefault_frame_alist = Qnil;
4843 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars,
4844 doc: /* Default position of vertical scroll bars on this window-system. */);
4845 #ifdef HAVE_WINDOW_SYSTEM
4846 #if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
4847 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
4848 default. */
4849 Vdefault_frame_scroll_bars = Qright;
4850 #else
4851 Vdefault_frame_scroll_bars = Qleft;
4852 #endif
4853 #else
4854 Vdefault_frame_scroll_bars = Qnil;
4855 #endif
4857 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
4858 scroll_bar_adjust_thumb_portion_p,
4859 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
4860 Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards
4861 even if the end of the buffer is shown (i.e. overscrolling).
4862 Set to nil if you want the thumb to be at the bottom when the end of the buffer
4863 is shown. Also, the thumb fills the whole scroll bar when the entire buffer
4864 is visible. In this case you can not overscroll. */);
4865 scroll_bar_adjust_thumb_portion_p = 1;
4867 DEFVAR_LISP ("terminal-frame", Vterminal_frame,
4868 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4870 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function,
4871 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4872 `mouse-position' calls this function, passing its usual return value as
4873 argument, and returns whatever this function returns.
4874 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4875 which need to do mouse handling at the Lisp level. */);
4876 Vmouse_position_function = Qnil;
4878 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight,
4879 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4880 If the value is an integer, highlighting is only shown after moving the
4881 mouse, while keyboard input turns off the highlight even when the mouse
4882 is over the clickable text. However, the mouse shape still indicates
4883 when the mouse is over clickable text. */);
4884 Vmouse_highlight = Qt;
4886 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible,
4887 doc: /* If non-nil, make pointer invisible while typing.
4888 The pointer becomes visible again when the mouse is moved. */);
4889 Vmake_pointer_invisible = Qt;
4891 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
4892 doc: /* Normal hook run when a frame gains input focus. */);
4893 Vfocus_in_hook = Qnil;
4894 DEFSYM (Qfocus_in_hook, "focus-in-hook");
4896 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
4897 doc: /* Normal hook run when a frame loses input focus. */);
4898 Vfocus_out_hook = Qnil;
4899 DEFSYM (Qfocus_out_hook, "focus-out-hook");
4901 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
4902 doc: /* Functions run before deleting a frame.
4903 The functions are run with one arg, the frame to be deleted.
4904 See `delete-frame'.
4906 Note that functions in this list may be called just before the frame is
4907 actually deleted, or some time later (or even both when an earlier function
4908 in `delete-frame-functions' (indirectly) calls `delete-frame'
4909 recursively). */);
4910 Vdelete_frame_functions = Qnil;
4911 DEFSYM (Qdelete_frame_functions, "delete-frame-functions");
4913 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode,
4914 doc: /* Non-nil if Menu-Bar mode is enabled.
4915 See the command `menu-bar-mode' for a description of this minor mode.
4916 Setting this variable directly does not take effect;
4917 either customize it (see the info node `Easy Customization')
4918 or call the function `menu-bar-mode'. */);
4919 Vmenu_bar_mode = Qt;
4921 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode,
4922 doc: /* Non-nil if Tool-Bar mode is enabled.
4923 See the command `tool-bar-mode' for a description of this minor mode.
4924 Setting this variable directly does not take effect;
4925 either customize it (see the info node `Easy Customization')
4926 or call the function `tool-bar-mode'. */);
4927 #ifdef HAVE_WINDOW_SYSTEM
4928 Vtool_bar_mode = Qt;
4929 #else
4930 Vtool_bar_mode = Qnil;
4931 #endif
4933 DEFVAR_LISP ("frame-initial-frame-tool-bar-height", Vframe_initial_frame_tool_bar_height,
4934 doc: /* Height of tool bar of initial frame. */);
4935 Vframe_initial_frame_tool_bar_height = make_number (0);
4937 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4938 doc: /* Minibufferless frames use this frame's minibuffer.
4939 Emacs cannot create minibufferless frames unless this is set to an
4940 appropriate surrogate.
4942 Emacs consults this variable only when creating minibufferless
4943 frames; once the frame is created, it sticks with its assigned
4944 minibuffer, no matter what this variable is set to. This means that
4945 this variable doesn't necessarily say anything meaningful about the
4946 current set of frames, or where the minibuffer is currently being
4947 displayed.
4949 This variable is local to the current terminal and cannot be buffer-local. */);
4951 DEFVAR_BOOL ("focus-follows-mouse", focus_follows_mouse,
4952 doc: /* Non-nil if window system changes focus when you move the mouse.
4953 You should set this variable to tell Emacs how your window manager
4954 handles focus, since there is no way in general for Emacs to find out
4955 automatically. See also `mouse-autoselect-window'. */);
4956 focus_follows_mouse = 0;
4958 DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise,
4959 doc: /* Non-nil means resize frames pixelwise.
4960 If this option is nil, resizing a frame rounds its sizes to the frame's
4961 current values of `frame-char-height' and `frame-char-width'. If this
4962 is non-nil, no rounding occurs, hence frame sizes can increase/decrease
4963 by one pixel.
4965 With some window managers you may have to set this to non-nil in order
4966 to fully maximize frames. To resize your initial frame pixelwise, set
4967 this option to a non-nil value in your init file. */);
4968 frame_resize_pixelwise = 0;
4970 DEFVAR_BOOL ("frame-inhibit-implied-resize", frame_inhibit_implied_resize,
4971 doc: /* Non-nil means do not resize frame implicitly.
4972 If this option is nil, setting default font, menubar mode, fringe width,
4973 or scroll bar mode of a specific frame may resize the frame in order to
4974 preserve the number of columns or lines it displays. If this option is
4975 non-nil, no such resizing is done. */);
4976 frame_inhibit_implied_resize = 0;
4978 staticpro (&Vframe_list);
4980 defsubr (&Sframep);
4981 defsubr (&Sframe_live_p);
4982 defsubr (&Swindow_system);
4983 defsubr (&Smake_terminal_frame);
4984 defsubr (&Shandle_switch_frame);
4985 defsubr (&Sselect_frame);
4986 defsubr (&Sselected_frame);
4987 defsubr (&Sframe_list);
4988 defsubr (&Snext_frame);
4989 defsubr (&Sprevious_frame);
4990 defsubr (&Slast_nonminibuf_frame);
4991 defsubr (&Sdelete_frame);
4992 defsubr (&Smouse_position);
4993 defsubr (&Smouse_pixel_position);
4994 defsubr (&Sset_mouse_position);
4995 defsubr (&Sset_mouse_pixel_position);
4996 #if 0
4997 defsubr (&Sframe_configuration);
4998 defsubr (&Srestore_frame_configuration);
4999 #endif
5000 defsubr (&Smake_frame_visible);
5001 defsubr (&Smake_frame_invisible);
5002 defsubr (&Siconify_frame);
5003 defsubr (&Sframe_visible_p);
5004 defsubr (&Svisible_frame_list);
5005 defsubr (&Sraise_frame);
5006 defsubr (&Slower_frame);
5007 defsubr (&Sx_focus_frame);
5008 defsubr (&Sredirect_frame_focus);
5009 defsubr (&Sframe_focus);
5010 defsubr (&Sframe_parameters);
5011 defsubr (&Sframe_parameter);
5012 defsubr (&Smodify_frame_parameters);
5013 defsubr (&Sframe_char_height);
5014 defsubr (&Sframe_char_width);
5015 defsubr (&Sframe_pixel_height);
5016 defsubr (&Sframe_pixel_width);
5017 defsubr (&Sframe_text_cols);
5018 defsubr (&Sframe_text_lines);
5019 defsubr (&Sframe_total_cols);
5020 defsubr (&Sframe_total_lines);
5021 defsubr (&Sframe_text_width);
5022 defsubr (&Sframe_text_height);
5023 defsubr (&Sscroll_bar_width);
5024 defsubr (&Sscroll_bar_height);
5025 defsubr (&Sfringe_width);
5026 defsubr (&Sborder_width);
5027 defsubr (&Sright_divider_width);
5028 defsubr (&Sbottom_divider_width);
5029 defsubr (&Stool_bar_pixel_width);
5030 defsubr (&Sset_frame_height);
5031 defsubr (&Sset_frame_width);
5032 defsubr (&Sset_frame_size);
5033 defsubr (&Sset_frame_position);
5034 defsubr (&Sframe_pointer_visible_p);
5036 #ifdef HAVE_WINDOW_SYSTEM
5037 defsubr (&Sx_get_resource);
5038 defsubr (&Sx_parse_geometry);
5039 #endif