Support IF NOT EXISTS in SQL declarations
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2
3 Copyright (C) 1993-1995, 1997, 1999-2012 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
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.
11
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.
16
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/>. */
19
20 #include <config.h>
21
22 #define FRAME_INLINE EXTERN_INLINE
23
24 #include <stdio.h>
25 #include <errno.h>
26 #include <limits.h>
27
28 #include <c-ctype.h>
29
30 #include "lisp.h"
31 #include "character.h"
32
33 #ifdef HAVE_WINDOW_SYSTEM
34 #include TERM_HEADER
35 #endif /* HAVE_WINDOW_SYSTEM */
36
37 #include "buffer.h"
38 /* These help us bind and responding to switch-frame events. */
39 #include "commands.h"
40 #include "keyboard.h"
41 #include "frame.h"
42 #include "blockinput.h"
43 #include "termchar.h"
44 #include "termhooks.h"
45 #include "dispextern.h"
46 #include "window.h"
47 #include "font.h"
48 #ifdef HAVE_WINDOW_SYSTEM
49 #include "fontset.h"
50 #endif
51 #ifdef MSDOS
52 #include "msdos.h"
53 #include "dosfns.h"
54 #endif
55
56 #ifdef HAVE_NS
57 Lisp_Object Qns_parse_geometry;
58 #endif
59
60 Lisp_Object Qframep, Qframe_live_p;
61 Lisp_Object Qicon, Qmodeline;
62 Lisp_Object Qonly, Qnone;
63 Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
64 Lisp_Object Qvisible;
65 Lisp_Object Qdisplay_type;
66 static Lisp_Object Qbackground_mode;
67 Lisp_Object Qnoelisp;
68
69 static Lisp_Object Qx_frame_parameter;
70 Lisp_Object Qx_resource_name;
71 Lisp_Object Qterminal;
72 Lisp_Object Qterminal_live_p;
73
74 /* Frame parameters (set or reported). */
75
76 Lisp_Object Qauto_raise, Qauto_lower;
77 Lisp_Object Qborder_color, Qborder_width;
78 Lisp_Object Qcursor_color, Qcursor_type;
79 static Lisp_Object Qgeometry; /* Not used */
80 Lisp_Object Qheight, Qwidth;
81 Lisp_Object Qleft, Qright;
82 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
83 Lisp_Object Qtooltip;
84 Lisp_Object Qinternal_border_width;
85 Lisp_Object Qmouse_color;
86 Lisp_Object Qminibuffer;
87 Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
88 Lisp_Object Qvisibility;
89 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
90 Lisp_Object Qscreen_gamma;
91 Lisp_Object Qline_spacing;
92 static Lisp_Object Quser_position, Quser_size;
93 Lisp_Object Qwait_for_wm;
94 static Lisp_Object Qwindow_id;
95 #ifdef HAVE_X_WINDOWS
96 static Lisp_Object Qouter_window_id;
97 #endif
98 Lisp_Object Qparent_id;
99 Lisp_Object Qtitle, Qname;
100 static Lisp_Object Qexplicit_name;
101 Lisp_Object Qunsplittable;
102 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
103 Lisp_Object Qleft_fringe, Qright_fringe;
104 Lisp_Object Qbuffer_predicate;
105 static Lisp_Object Qbuffer_list, Qburied_buffer_list;
106 Lisp_Object Qtty_color_mode;
107 Lisp_Object Qtty, Qtty_type;
108
109 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
110 Lisp_Object Qsticky;
111 Lisp_Object Qfont_backend;
112 Lisp_Object Qalpha;
113
114 Lisp_Object Qface_set_after_frame_default;
115
116 static Lisp_Object Qdelete_frame_functions;
117
118 #ifdef HAVE_WINDOW_SYSTEM
119 static void x_report_frame_params (struct frame *, Lisp_Object *);
120 #endif
121
122 /* These setters are used only in this file, so they can be private. */
123 static void
124 fset_buffer_predicate (struct frame *f, Lisp_Object val)
125 {
126 f->buffer_predicate = val;
127 }
128 static void
129 fset_minibuffer_window (struct frame *f, Lisp_Object val)
130 {
131 f->minibuffer_window = val;
132 }
133
134 struct frame *
135 decode_live_frame (register Lisp_Object frame)
136 {
137 if (NILP (frame))
138 frame = selected_frame;
139 CHECK_LIVE_FRAME (frame);
140 return XFRAME (frame);
141 }
142
143 struct frame *
144 decode_any_frame (register Lisp_Object frame)
145 {
146 if (NILP (frame))
147 frame = selected_frame;
148 CHECK_FRAME (frame);
149 return XFRAME (frame);
150 }
151
152 static void
153 set_menu_bar_lines_1 (Lisp_Object window, int n)
154 {
155 struct window *w = XWINDOW (window);
156
157 w->last_modified = 0;
158 wset_top_line (w, make_number (XFASTINT (w->top_line) + n));
159 wset_total_lines (w, make_number (XFASTINT (w->total_lines) - n));
160
161 /* Handle just the top child in a vertical split. */
162 if (!NILP (w->vchild))
163 set_menu_bar_lines_1 (w->vchild, n);
164
165 /* Adjust all children in a horizontal split. */
166 for (window = w->hchild; !NILP (window); window = w->next)
167 {
168 w = XWINDOW (window);
169 set_menu_bar_lines_1 (window, n);
170 }
171 }
172
173 void
174 set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
175 {
176 int nlines;
177 int olines = FRAME_MENU_BAR_LINES (f);
178
179 /* Right now, menu bars don't work properly in minibuf-only frames;
180 most of the commands try to apply themselves to the minibuffer
181 frame itself, and get an error because you can't switch buffers
182 in or split the minibuffer window. */
183 if (FRAME_MINIBUF_ONLY_P (f))
184 return;
185
186 if (TYPE_RANGED_INTEGERP (int, value))
187 nlines = XINT (value);
188 else
189 nlines = 0;
190
191 if (nlines != olines)
192 {
193 windows_or_buffers_changed++;
194 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
195 FRAME_MENU_BAR_LINES (f) = nlines;
196 set_menu_bar_lines_1 (f->root_window, nlines - olines);
197 adjust_glyphs (f);
198 }
199 }
200 \f
201 Lisp_Object Vframe_list;
202
203 \f
204 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
205 doc: /* Return non-nil if OBJECT is a frame.
206 Value is:
207 t for a termcap frame (a character-only terminal),
208 'x' for an Emacs frame that is really an X window,
209 'w32' for an Emacs frame that is a window on MS-Windows display,
210 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
211 'pc' for a direct-write MS-DOS frame.
212 See also `frame-live-p'. */)
213 (Lisp_Object object)
214 {
215 if (!FRAMEP (object))
216 return Qnil;
217 switch (XFRAME (object)->output_method)
218 {
219 case output_initial: /* The initial frame is like a termcap frame. */
220 case output_termcap:
221 return Qt;
222 case output_x_window:
223 return Qx;
224 case output_w32:
225 return Qw32;
226 case output_msdos_raw:
227 return Qpc;
228 case output_mac:
229 return Qmac;
230 case output_ns:
231 return Qns;
232 default:
233 emacs_abort ();
234 }
235 }
236
237 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
238 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
239 Value is nil if OBJECT is not a live frame. If object is a live
240 frame, the return value indicates what sort of terminal device it is
241 displayed on. See the documentation of `framep' for possible
242 return values. */)
243 (Lisp_Object object)
244 {
245 return ((FRAMEP (object)
246 && FRAME_LIVE_P (XFRAME (object)))
247 ? Fframep (object)
248 : Qnil);
249 }
250
251 DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
252 doc: /* The name of the window system that FRAME is displaying through.
253 The value is a symbol:
254 nil for a termcap frame (a character-only terminal),
255 'x' for an Emacs frame that is really an X window,
256 'w32' for an Emacs frame that is a window on MS-Windows display,
257 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
258 'pc' for a direct-write MS-DOS frame.
259
260 FRAME defaults to the currently selected frame.
261
262 Use of this function as a predicate is deprecated. Instead,
263 use `display-graphic-p' or any of the other `display-*-p'
264 predicates which report frame's specific UI-related capabilities. */)
265 (Lisp_Object frame)
266 {
267 Lisp_Object type;
268 if (NILP (frame))
269 frame = selected_frame;
270
271 type = Fframep (frame);
272
273 if (NILP (type))
274 wrong_type_argument (Qframep, frame);
275
276 if (EQ (type, Qt))
277 return Qnil;
278 else
279 return type;
280 }
281
282 struct frame *
283 make_frame (int mini_p)
284 {
285 Lisp_Object frame;
286 register struct frame *f;
287 register Lisp_Object root_window;
288 register Lisp_Object mini_window;
289
290 f = allocate_frame ();
291 XSETFRAME (frame, f);
292
293 /* Initialize Lisp data. Note that allocate_frame initializes all
294 Lisp data to nil, so do it only for slots which should not be nil. */
295 fset_tool_bar_position (f, Qtop);
296
297 /* Initialize non-Lisp data. Note that allocate_frame zeroes out all
298 non-Lisp data, so do it only for slots which should not be zero.
299 To avoid subtle bugs and for the sake of readability, it's better to
300 initialize enum members explicitly even if their values are zero. */
301 f->wants_modeline = 1;
302 f->garbaged = 1;
303 f->has_minibuffer = mini_p;
304 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
305 f->column_width = 1; /* !FRAME_WINDOW_P value */
306 f->line_height = 1; /* !FRAME_WINDOW_P value */
307 #ifdef HAVE_WINDOW_SYSTEM
308 f->want_fullscreen = FULLSCREEN_NONE;
309 #endif
310
311 root_window = make_window ();
312 if (mini_p)
313 {
314 mini_window = make_window ();
315 wset_next (XWINDOW (root_window), mini_window);
316 wset_prev (XWINDOW (mini_window), root_window);
317 XWINDOW (mini_window)->mini = 1;
318 wset_frame (XWINDOW (mini_window), frame);
319 fset_minibuffer_window (f, mini_window);
320 }
321 else
322 {
323 mini_window = Qnil;
324 wset_next (XWINDOW (root_window), Qnil);
325 fset_minibuffer_window (f, Qnil);
326 }
327
328 wset_frame (XWINDOW (root_window), frame);
329
330 /* 10 is arbitrary,
331 just so that there is "something there."
332 Correct size will be set up later with change_frame_size. */
333
334 SET_FRAME_COLS (f, 10);
335 FRAME_LINES (f) = 10;
336
337 wset_total_cols (XWINDOW (root_window), make_number (10));
338 wset_total_lines (XWINDOW (root_window), make_number (mini_p ? 9 : 10));
339
340 if (mini_p)
341 {
342 wset_total_cols (XWINDOW (mini_window), make_number (10));
343 wset_top_line (XWINDOW (mini_window), make_number (9));
344 wset_total_lines (XWINDOW (mini_window), make_number (1));
345 }
346
347 /* Choose a buffer for the frame's root window. */
348 {
349 Lisp_Object buf;
350
351 wset_buffer (XWINDOW (root_window), Qt);
352 buf = Fcurrent_buffer ();
353 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
354 a space), try to find another one. */
355 if (SREF (Fbuffer_name (buf), 0) == ' ')
356 buf = other_buffer_safely (buf);
357
358 /* Use set_window_buffer, not Fset_window_buffer, and don't let
359 hooks be run by it. The reason is that the whole frame/window
360 arrangement is not yet fully initialized at this point. Windows
361 don't have the right size, glyph matrices aren't initialized
362 etc. Running Lisp functions at this point surely ends in a
363 SEGV. */
364 set_window_buffer (root_window, buf, 0, 0);
365 fset_buffer_list (f, Fcons (buf, Qnil));
366 }
367
368 if (mini_p)
369 {
370 wset_buffer (XWINDOW (mini_window), Qt);
371 set_window_buffer (mini_window,
372 (NILP (Vminibuffer_list)
373 ? get_minibuffer (0)
374 : Fcar (Vminibuffer_list)),
375 0, 0);
376 }
377
378 fset_root_window (f, root_window);
379 fset_selected_window (f, root_window);
380 /* Make sure this window seems more recently used than
381 a newly-created, never-selected window. */
382 XWINDOW (f->selected_window)->use_time = ++window_select_count;
383
384 return f;
385 }
386 \f
387 #ifdef HAVE_WINDOW_SYSTEM
388 /* Make a frame using a separate minibuffer window on another frame.
389 MINI_WINDOW is the minibuffer window to use. nil means use the
390 default (the global minibuffer). */
391
392 struct frame *
393 make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lisp_Object display)
394 {
395 register struct frame *f;
396 struct gcpro gcpro1;
397
398 if (!NILP (mini_window))
399 CHECK_LIVE_WINDOW (mini_window);
400
401 if (!NILP (mini_window)
402 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
403 error ("Frame and minibuffer must be on the same terminal");
404
405 /* Make a frame containing just a root window. */
406 f = make_frame (0);
407
408 if (NILP (mini_window))
409 {
410 /* Use default-minibuffer-frame if possible. */
411 if (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
412 || ! FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame))))
413 {
414 Lisp_Object frame_dummy;
415
416 XSETFRAME (frame_dummy, f);
417 GCPRO1 (frame_dummy);
418 /* If there's no minibuffer frame to use, create one. */
419 kset_default_minibuffer_frame
420 (kb, call1 (intern ("make-initial-minibuffer-frame"), display));
421 UNGCPRO;
422 }
423
424 mini_window
425 = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window;
426 }
427
428 fset_minibuffer_window (f, mini_window);
429
430 /* Make the chosen minibuffer window display the proper minibuffer,
431 unless it is already showing a minibuffer. */
432 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
433 /* Use set_window_buffer instead of Fset_window_buffer (see
434 discussion of bug#11984, bug#12025, bug#12026). */
435 set_window_buffer (mini_window,
436 (NILP (Vminibuffer_list)
437 ? get_minibuffer (0)
438 : Fcar (Vminibuffer_list)), 0, 0);
439 return f;
440 }
441
442 /* Make a frame containing only a minibuffer window. */
443
444 struct frame *
445 make_minibuffer_frame (void)
446 {
447 /* First make a frame containing just a root window, no minibuffer. */
448
449 register struct frame *f = make_frame (0);
450 register Lisp_Object mini_window;
451 register Lisp_Object frame;
452
453 XSETFRAME (frame, f);
454
455 f->auto_raise = 0;
456 f->auto_lower = 0;
457 f->no_split = 1;
458 f->wants_modeline = 0;
459 f->has_minibuffer = 1;
460
461 /* Now label the root window as also being the minibuffer.
462 Avoid infinite looping on the window chain by marking next pointer
463 as nil. */
464
465 mini_window = f->root_window;
466 fset_minibuffer_window (f, mini_window);
467 XWINDOW (mini_window)->mini = 1;
468 wset_next (XWINDOW (mini_window), Qnil);
469 wset_prev (XWINDOW (mini_window), Qnil);
470 wset_frame (XWINDOW (mini_window), frame);
471
472 /* Put the proper buffer in that window. */
473
474 /* Use set_window_buffer instead of Fset_window_buffer (see
475 discussion of bug#11984, bug#12025, bug#12026). */
476 set_window_buffer (mini_window,
477 (NILP (Vminibuffer_list)
478 ? get_minibuffer (0)
479 : Fcar (Vminibuffer_list)), 0, 0);
480 return f;
481 }
482 #endif /* HAVE_WINDOW_SYSTEM */
483 \f
484 /* Construct a frame that refers to a terminal. */
485
486 static printmax_t tty_frame_count;
487
488 struct frame *
489 make_initial_frame (void)
490 {
491 struct frame *f;
492 struct terminal *terminal;
493 Lisp_Object frame;
494
495 eassert (initial_kboard);
496
497 /* The first call must initialize Vframe_list. */
498 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
499 Vframe_list = Qnil;
500
501 terminal = init_initial_terminal ();
502
503 f = make_frame (1);
504 XSETFRAME (frame, f);
505
506 Vframe_list = Fcons (frame, Vframe_list);
507
508 tty_frame_count = 1;
509 fset_name (f, build_pure_c_string ("F1"));
510
511 f->visible = 1;
512 f->async_visible = 1;
513
514 f->output_method = terminal->type;
515 f->terminal = terminal;
516 f->terminal->reference_count++;
517 f->output_data.nothing = 0;
518
519 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
520 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
521
522 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
523
524 /* The default value of menu-bar-mode is t. */
525 set_menu_bar_lines (f, make_number (1), Qnil);
526
527 if (!noninteractive)
528 init_frame_faces (f);
529
530 return f;
531 }
532
533
534 static struct frame *
535 make_terminal_frame (struct terminal *terminal)
536 {
537 register struct frame *f;
538 Lisp_Object frame;
539 char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
540
541 if (!terminal->name)
542 error ("Terminal is not live, can't create new frames on it");
543
544 f = make_frame (1);
545
546 XSETFRAME (frame, f);
547 Vframe_list = Fcons (frame, Vframe_list);
548
549 fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count));
550
551 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
552 f->async_visible = 1; /* Don't let visible be cleared later. */
553 f->terminal = terminal;
554 f->terminal->reference_count++;
555 #ifdef MSDOS
556 f->output_data.tty->display_info = &the_only_display_info;
557 if (!inhibit_window_system
558 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
559 || XFRAME (selected_frame)->output_method == output_msdos_raw))
560 f->output_method = output_msdos_raw;
561 else
562 f->output_method = output_termcap;
563 #else /* not MSDOS */
564 f->output_method = output_termcap;
565 create_tty_output (f);
566 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
567 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
568 #endif /* not MSDOS */
569
570 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
571 FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
572
573 /* Set the top frame to the newly created frame. */
574 if (FRAMEP (FRAME_TTY (f)->top_frame)
575 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
576 XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
577
578 FRAME_TTY (f)->top_frame = frame;
579
580 if (!noninteractive)
581 init_frame_faces (f);
582
583 return f;
584 }
585
586 /* Get a suitable value for frame parameter PARAMETER for a newly
587 created frame, based on (1) the user-supplied frame parameter
588 alist SUPPLIED_PARMS, and (2) CURRENT_VALUE. */
589
590 static Lisp_Object
591 get_future_frame_param (Lisp_Object parameter,
592 Lisp_Object supplied_parms,
593 char *current_value)
594 {
595 Lisp_Object result;
596
597 result = Fassq (parameter, supplied_parms);
598 if (NILP (result))
599 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
600 if (NILP (result) && current_value != NULL)
601 result = build_string (current_value);
602 if (!NILP (result) && !STRINGP (result))
603 result = XCDR (result);
604 if (NILP (result) || !STRINGP (result))
605 result = Qnil;
606
607 return result;
608 }
609
610 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
611 1, 1, 0,
612 doc: /* Create an additional terminal frame, possibly on another terminal.
613 This function takes one argument, an alist specifying frame parameters.
614
615 You can create multiple frames on a single text terminal, but only one
616 of them (the selected terminal frame) is actually displayed.
617
618 In practice, generally you don't need to specify any parameters,
619 except when you want to create a new frame on another terminal.
620 In that case, the `tty' parameter specifies the device file to open,
621 and the `tty-type' parameter specifies the terminal type. Example:
622
623 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
624
625 Note that changing the size of one terminal frame automatically
626 affects all frames on the same terminal device. */)
627 (Lisp_Object parms)
628 {
629 struct frame *f;
630 struct terminal *t = NULL;
631 Lisp_Object frame, tem;
632 struct frame *sf = SELECTED_FRAME ();
633
634 #ifdef MSDOS
635 if (sf->output_method != output_msdos_raw
636 && sf->output_method != output_termcap)
637 emacs_abort ();
638 #else /* not MSDOS */
639
640 #ifdef WINDOWSNT /* This should work now! */
641 if (sf->output_method != output_termcap)
642 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
643 #endif
644 #endif /* not MSDOS */
645
646 {
647 Lisp_Object terminal;
648
649 terminal = Fassq (Qterminal, parms);
650 if (CONSP (terminal))
651 {
652 terminal = XCDR (terminal);
653 t = get_terminal (terminal, 1);
654 }
655 #ifdef MSDOS
656 if (t && t != the_only_display_info.terminal)
657 /* msdos.c assumes a single tty_display_info object. */
658 error ("Multiple terminals are not supported on this platform");
659 if (!t)
660 t = the_only_display_info.terminal;
661 #endif
662 }
663
664 if (!t)
665 {
666 char *name = 0, *type = 0;
667 Lisp_Object tty, tty_type;
668
669 tty = get_future_frame_param
670 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
671 ? FRAME_TTY (XFRAME (selected_frame))->name
672 : NULL));
673 if (!NILP (tty))
674 {
675 name = alloca (SBYTES (tty) + 1);
676 memcpy (name, SSDATA (tty), SBYTES (tty));
677 name[SBYTES (tty)] = 0;
678 }
679
680 tty_type = get_future_frame_param
681 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
682 ? FRAME_TTY (XFRAME (selected_frame))->type
683 : NULL));
684 if (!NILP (tty_type))
685 {
686 type = alloca (SBYTES (tty_type) + 1);
687 memcpy (type, SSDATA (tty_type), SBYTES (tty_type));
688 type[SBYTES (tty_type)] = 0;
689 }
690
691 t = init_tty (name, type, 0); /* Errors are not fatal. */
692 }
693
694 f = make_terminal_frame (t);
695
696 {
697 int width, height;
698 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
699 change_frame_size (f, height, width, 0, 0, 0);
700 }
701
702 adjust_glyphs (f);
703 calculate_costs (f);
704 XSETFRAME (frame, f);
705 Fmodify_frame_parameters (frame, parms);
706 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
707 build_string (t->display_info.tty->type)),
708 Qnil));
709 if (t->display_info.tty->name != NULL)
710 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
711 build_string (t->display_info.tty->name)),
712 Qnil));
713 else
714 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
715
716 /* Make the frame face alist be frame-specific, so that each
717 frame could change its face definitions independently. */
718 fset_face_alist (f, Fcopy_alist (sf->face_alist));
719 /* Simple Fcopy_alist isn't enough, because we need the contents of
720 the vectors which are the CDRs of associations in face_alist to
721 be copied as well. */
722 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
723 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
724 return frame;
725 }
726
727 \f
728 /* Perform the switch to frame FRAME.
729
730 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
731 FRAME1 as frame.
732
733 If TRACK is non-zero and the frame that currently has the focus
734 redirects its focus to the selected frame, redirect that focused
735 frame's focus to FRAME instead.
736
737 FOR_DELETION non-zero means that the selected frame is being
738 deleted, which includes the possibility that the frame's terminal
739 is dead.
740
741 The value of NORECORD is passed as argument to Fselect_window. */
742
743 Lisp_Object
744 do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
745 {
746 struct frame *sf = SELECTED_FRAME ();
747
748 /* If FRAME is a switch-frame event, extract the frame we should
749 switch to. */
750 if (CONSP (frame)
751 && EQ (XCAR (frame), Qswitch_frame)
752 && CONSP (XCDR (frame)))
753 frame = XCAR (XCDR (frame));
754
755 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
756 a switch-frame event to arrive after a frame is no longer live,
757 especially when deleting the initial frame during startup. */
758 CHECK_FRAME (frame);
759 if (! FRAME_LIVE_P (XFRAME (frame)))
760 return Qnil;
761
762 if (sf == XFRAME (frame))
763 return frame;
764
765 /* This is too greedy; it causes inappropriate focus redirection
766 that's hard to get rid of. */
767 #if 0
768 /* If a frame's focus has been redirected toward the currently
769 selected frame, we should change the redirection to point to the
770 newly selected frame. This means that if the focus is redirected
771 from a minibufferless frame to a surrogate minibuffer frame, we
772 can use `other-window' to switch between all the frames using
773 that minibuffer frame, and the focus redirection will follow us
774 around. */
775 if (track)
776 {
777 Lisp_Object tail;
778
779 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
780 {
781 Lisp_Object focus;
782
783 if (!FRAMEP (XCAR (tail)))
784 emacs_abort ();
785
786 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
787
788 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
789 Fredirect_frame_focus (XCAR (tail), frame);
790 }
791 }
792 #else /* ! 0 */
793 /* Instead, apply it only to the frame we're pointing to. */
794 #ifdef HAVE_WINDOW_SYSTEM
795 if (track && FRAME_WINDOW_P (XFRAME (frame)))
796 {
797 Lisp_Object focus, xfocus;
798
799 xfocus = x_get_focus_frame (XFRAME (frame));
800 if (FRAMEP (xfocus))
801 {
802 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
803 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
804 Fredirect_frame_focus (xfocus, frame);
805 }
806 }
807 #endif /* HAVE_X_WINDOWS */
808 #endif /* ! 0 */
809
810 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
811 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
812
813 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
814 {
815 if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
816 /* Mark previously displayed frame as now obscured. */
817 XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2;
818 XFRAME (frame)->async_visible = 1;
819 FRAME_TTY (XFRAME (frame))->top_frame = frame;
820 }
821
822 selected_frame = frame;
823 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
824 last_nonminibuf_frame = XFRAME (selected_frame);
825
826 Fselect_window (XFRAME (frame)->selected_window, norecord);
827
828 /* We want to make sure that the next event generates a frame-switch
829 event to the appropriate frame. This seems kludgy to me, but
830 before you take it out, make sure that evaluating something like
831 (select-window (frame-root-window (new-frame))) doesn't end up
832 with your typing being interpreted in the new frame instead of
833 the one you're actually typing in. */
834 internal_last_event_frame = Qnil;
835
836 return frame;
837 }
838
839 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
840 doc: /* Select FRAME.
841 Subsequent editing commands apply to its selected window.
842 Optional argument NORECORD means to neither change the order of
843 recently selected windows nor the buffer list.
844
845 The selection of FRAME lasts until the next time the user does
846 something to select a different frame, or until the next time
847 this function is called. If you are using a window system, the
848 previously selected frame may be restored as the selected frame
849 when returning to the command loop, because it still may have
850 the window system's input focus. On a text terminal, the next
851 redisplay will display FRAME.
852
853 This function returns FRAME, or nil if FRAME has been deleted. */)
854 (Lisp_Object frame, Lisp_Object norecord)
855 {
856 return do_switch_frame (frame, 1, 0, norecord);
857 }
858
859
860 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
861 doc: /* Handle a switch-frame event EVENT.
862 Switch-frame events are usually bound to this function.
863 A switch-frame event tells Emacs that the window manager has requested
864 that the user's events be directed to the frame mentioned in the event.
865 This function selects the selected window of the frame of EVENT.
866
867 If EVENT is frame object, handle it as if it were a switch-frame event
868 to that frame. */)
869 (Lisp_Object event)
870 {
871 /* Preserve prefix arg that the command loop just cleared. */
872 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
873 Frun_hooks (1, &Qmouse_leave_buffer_hook);
874 return do_switch_frame (event, 0, 0, Qnil);
875 }
876
877 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
878 doc: /* Return the frame that is now selected. */)
879 (void)
880 {
881 return selected_frame;
882 }
883 \f
884 DEFUN ("frame-list", Fframe_list, Sframe_list,
885 0, 0, 0,
886 doc: /* Return a list of all live frames. */)
887 (void)
888 {
889 Lisp_Object frames;
890 frames = Fcopy_sequence (Vframe_list);
891 #ifdef HAVE_WINDOW_SYSTEM
892 if (FRAMEP (tip_frame))
893 frames = Fdelq (tip_frame, frames);
894 #endif
895 return frames;
896 }
897
898 /* Return the next frame in the frame list after FRAME.
899 If MINIBUF is nil, exclude minibuffer-only frames.
900 If MINIBUF is a window, include only its own frame
901 and any frame now using that window as the minibuffer.
902 If MINIBUF is `visible', include all visible frames.
903 If MINIBUF is 0, include all visible and iconified frames.
904 Otherwise, include all frames. */
905
906 static Lisp_Object
907 next_frame (Lisp_Object frame, Lisp_Object minibuf)
908 {
909 Lisp_Object f, tail;
910 int passed = 0;
911
912 /* There must always be at least one frame in Vframe_list. */
913 if (! CONSP (Vframe_list))
914 emacs_abort ();
915
916 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
917 forever. Forestall that. */
918 CHECK_LIVE_FRAME (frame);
919
920 while (1)
921 FOR_EACH_FRAME (tail, f)
922 {
923 if (passed
924 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
925 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
926 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
927 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
928 {
929 /* Decide whether this frame is eligible to be returned. */
930
931 /* If we've looped all the way around without finding any
932 eligible frames, return the original frame. */
933 if (EQ (f, frame))
934 return f;
935
936 /* Let minibuf decide if this frame is acceptable. */
937 if (NILP (minibuf))
938 {
939 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
940 return f;
941 }
942 else if (EQ (minibuf, Qvisible))
943 {
944 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
945 if (FRAME_VISIBLE_P (XFRAME (f)))
946 return f;
947 }
948 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
949 {
950 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
951 if (FRAME_VISIBLE_P (XFRAME (f))
952 || FRAME_ICONIFIED_P (XFRAME (f)))
953 return f;
954 }
955 else if (WINDOWP (minibuf))
956 {
957 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
958 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
959 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
960 FRAME_FOCUS_FRAME (XFRAME (f))))
961 return f;
962 }
963 else
964 return f;
965 }
966
967 if (EQ (frame, f))
968 passed++;
969 }
970 }
971
972 /* Return the previous frame in the frame list before FRAME.
973 If MINIBUF is nil, exclude minibuffer-only frames.
974 If MINIBUF is a window, include only its own frame
975 and any frame now using that window as the minibuffer.
976 If MINIBUF is `visible', include all visible frames.
977 If MINIBUF is 0, include all visible and iconified frames.
978 Otherwise, include all frames. */
979
980 static Lisp_Object
981 prev_frame (Lisp_Object frame, Lisp_Object minibuf)
982 {
983 Lisp_Object f, tail, prev = Qnil;
984
985 /* There must always be at least one frame in Vframe_list. */
986 eassert (CONSP (Vframe_list));
987
988 FOR_EACH_FRAME (tail, f)
989 {
990 if (EQ (frame, f) && !NILP (prev))
991 return prev;
992
993 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
994 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
995 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
996 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
997 {
998 /* Decide whether this frame is eligible to be returned,
999 according to minibuf. */
1000 if (NILP (minibuf))
1001 {
1002 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1003 prev = f;
1004 }
1005 else if (WINDOWP (minibuf))
1006 {
1007 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1008 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1009 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1010 FRAME_FOCUS_FRAME (XFRAME (f))))
1011 prev = f;
1012 }
1013 else if (EQ (minibuf, Qvisible))
1014 {
1015 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1016 if (FRAME_VISIBLE_P (XFRAME (f)))
1017 prev = f;
1018 }
1019 else if (XFASTINT (minibuf) == 0)
1020 {
1021 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1022 if (FRAME_VISIBLE_P (XFRAME (f))
1023 || FRAME_ICONIFIED_P (XFRAME (f)))
1024 prev = f;
1025 }
1026 else
1027 prev = f;
1028 }
1029 }
1030
1031 /* We've scanned the entire list. */
1032 if (NILP (prev))
1033 /* We went through the whole frame list without finding a single
1034 acceptable frame. Return the original frame. */
1035 return frame;
1036 else
1037 /* There were no acceptable frames in the list before FRAME; otherwise,
1038 we would have returned directly from the loop. Since PREV is the last
1039 acceptable frame in the list, return it. */
1040 return prev;
1041 }
1042
1043
1044 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1045 doc: /* Return the next frame in the frame list after FRAME.
1046 It considers only frames on the same terminal as FRAME.
1047 By default, skip minibuffer-only frames.
1048 If omitted, FRAME defaults to the selected frame.
1049 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1050 If MINIFRAME is a window, include only its own frame
1051 and any frame now using that window as the minibuffer.
1052 If MINIFRAME is `visible', include all visible frames.
1053 If MINIFRAME is 0, include all visible and iconified frames.
1054 Otherwise, include all frames. */)
1055 (Lisp_Object frame, Lisp_Object miniframe)
1056 {
1057 if (NILP (frame))
1058 frame = selected_frame;
1059
1060 CHECK_LIVE_FRAME (frame);
1061 return next_frame (frame, miniframe);
1062 }
1063
1064 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1065 doc: /* Return the previous frame in the frame list before FRAME.
1066 It considers only frames on the same terminal as FRAME.
1067 By default, skip minibuffer-only frames.
1068 If omitted, FRAME defaults to the selected frame.
1069 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1070 If MINIFRAME is a window, include only its own frame
1071 and any frame now using that window as the minibuffer.
1072 If MINIFRAME is `visible', include all visible frames.
1073 If MINIFRAME is 0, include all visible and iconified frames.
1074 Otherwise, include all frames. */)
1075 (Lisp_Object frame, Lisp_Object miniframe)
1076 {
1077 if (NILP (frame))
1078 frame = selected_frame;
1079 CHECK_LIVE_FRAME (frame);
1080 return prev_frame (frame, miniframe);
1081 }
1082 \f
1083 /* Return 1 if it is ok to delete frame F;
1084 0 if all frames aside from F are invisible.
1085 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1086
1087 static int
1088 other_visible_frames (FRAME_PTR f)
1089 {
1090 Lisp_Object frames, this;
1091
1092 FOR_EACH_FRAME (frames, this)
1093 {
1094 if (f == XFRAME (this))
1095 continue;
1096
1097 /* Verify that we can still talk to the frame's X window,
1098 and note any recent change in visibility. */
1099 #ifdef HAVE_WINDOW_SYSTEM
1100 if (FRAME_WINDOW_P (XFRAME (this)))
1101 {
1102 x_sync (XFRAME (this));
1103 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1104 }
1105 #endif
1106
1107 if (FRAME_VISIBLE_P (XFRAME (this))
1108 || FRAME_ICONIFIED_P (XFRAME (this))
1109 /* Allow deleting the terminal frame when at least one X
1110 frame exists. */
1111 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1112 return 1;
1113 }
1114 return 0;
1115 }
1116
1117 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1118 unconditionally. x_connection_closed and delete_terminal use
1119 this. Any other value of FORCE implements the semantics
1120 described for Fdelete_frame. */
1121 Lisp_Object
1122 delete_frame (Lisp_Object frame, Lisp_Object force)
1123 {
1124 struct frame *f = decode_any_frame (frame);
1125 struct frame *sf = SELECTED_FRAME ();
1126 struct kboard *kb;
1127
1128 int minibuffer_selected, is_tooltip_frame;
1129
1130 if (! FRAME_LIVE_P (f))
1131 return Qnil;
1132
1133 if (NILP (force) && !other_visible_frames (f))
1134 error ("Attempt to delete the sole visible or iconified frame");
1135
1136 /* x_connection_closed must have set FORCE to `noelisp' in order
1137 to delete the last frame, if it is gone. */
1138 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1139 error ("Attempt to delete the only frame");
1140
1141 XSETFRAME (frame, f);
1142
1143 /* Does this frame have a minibuffer, and is it the surrogate
1144 minibuffer for any other frame? */
1145 if (FRAME_HAS_MINIBUF_P (f))
1146 {
1147 Lisp_Object frames, this;
1148
1149 FOR_EACH_FRAME (frames, this)
1150 {
1151 if (! EQ (this, frame)
1152 && EQ (frame,
1153 WINDOW_FRAME (XWINDOW
1154 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1155 {
1156 /* If we MUST delete this frame, delete the other first.
1157 But do this only if FORCE equals `noelisp'. */
1158 if (EQ (force, Qnoelisp))
1159 delete_frame (this, Qnoelisp);
1160 else
1161 error ("Attempt to delete a surrogate minibuffer frame");
1162 }
1163 }
1164 }
1165
1166 is_tooltip_frame = !NILP (Fframe_parameter (frame, intern ("tooltip")));
1167
1168 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1169 frame is a tooltip. FORCE is set to `noelisp' when handling
1170 a disconnect from the terminal, so we don't dare call Lisp
1171 code. */
1172 if (NILP (Vrun_hooks) || is_tooltip_frame)
1173 ;
1174 else if (EQ (force, Qnoelisp))
1175 pending_funcalls
1176 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1177 pending_funcalls);
1178 else
1179 {
1180 #ifdef HAVE_X_WINDOWS
1181 /* Also, save clipboard to the clipboard manager. */
1182 x_clipboard_manager_save_frame (frame);
1183 #endif
1184
1185 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1186 }
1187
1188 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1189 if (! FRAME_LIVE_P (f))
1190 return Qnil;
1191
1192 /* At this point, we are committed to deleting the frame.
1193 There is no more chance for errors to prevent it. */
1194
1195 minibuffer_selected = EQ (minibuf_window, selected_window);
1196
1197 /* Don't let the frame remain selected. */
1198 if (f == sf)
1199 {
1200 Lisp_Object tail, frame1;
1201
1202 /* Look for another visible frame on the same terminal. */
1203 frame1 = next_frame (frame, Qvisible);
1204
1205 /* If there is none, find *some* other frame. */
1206 if (NILP (frame1) || EQ (frame1, frame))
1207 {
1208 FOR_EACH_FRAME (tail, frame1)
1209 {
1210 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1211 {
1212 /* Do not change a text terminal's top-frame. */
1213 struct frame *f1 = XFRAME (frame1);
1214 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
1215 {
1216 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
1217 if (!EQ (top_frame, frame))
1218 frame1 = top_frame;
1219 }
1220 break;
1221 }
1222 }
1223 }
1224 #ifdef NS_IMPL_COCOA
1225 else
1226 /* Under NS, there is no system mechanism for choosing a new
1227 window to get focus -- it is left to application code.
1228 So the portion of THIS application interfacing with NS
1229 needs to know about it. We call Fraise_frame, but the
1230 purpose is really to transfer focus. */
1231 Fraise_frame (frame1);
1232 #endif
1233
1234 do_switch_frame (frame1, 0, 1, Qnil);
1235 sf = SELECTED_FRAME ();
1236 }
1237
1238 /* Don't allow minibuf_window to remain on a deleted frame. */
1239 if (EQ (f->minibuffer_window, minibuf_window))
1240 {
1241 /* Use set_window_buffer instead of Fset_window_buffer (see
1242 discussion of bug#11984, bug#12025, bug#12026). */
1243 set_window_buffer (sf->minibuffer_window,
1244 XWINDOW (minibuf_window)->buffer, 0, 0);
1245 minibuf_window = sf->minibuffer_window;
1246
1247 /* If the dying minibuffer window was selected,
1248 select the new one. */
1249 if (minibuffer_selected)
1250 Fselect_window (minibuf_window, Qnil);
1251 }
1252
1253 /* Don't let echo_area_window to remain on a deleted frame. */
1254 if (EQ (f->minibuffer_window, echo_area_window))
1255 echo_area_window = sf->minibuffer_window;
1256
1257 /* Clear any X selections for this frame. */
1258 #ifdef HAVE_X_WINDOWS
1259 if (FRAME_X_P (f))
1260 x_clear_frame_selections (f);
1261 #endif
1262
1263 /* Free glyphs.
1264 This function must be called before the window tree of the
1265 frame is deleted because windows contain dynamically allocated
1266 memory. */
1267 free_glyphs (f);
1268
1269 #ifdef HAVE_WINDOW_SYSTEM
1270 /* Give chance to each font driver to free a frame specific data. */
1271 font_update_drivers (f, Qnil);
1272 #endif
1273
1274 /* Mark all the windows that used to be on FRAME as deleted, and then
1275 remove the reference to them. */
1276 delete_all_child_windows (f->root_window);
1277 fset_root_window (f, Qnil);
1278
1279 Vframe_list = Fdelq (frame, Vframe_list);
1280 FRAME_SET_VISIBLE (f, 0);
1281
1282 /* Allow the vector of menu bar contents to be freed in the next
1283 garbage collection. The frame object itself may not be garbage
1284 collected until much later, because recent_keys and other data
1285 structures can still refer to it. */
1286 fset_menu_bar_vector (f, Qnil);
1287
1288 /* If FRAME's buffer lists contains killed
1289 buffers, this helps GC to reclaim them. */
1290 fset_buffer_list (f, Qnil);
1291 fset_buried_buffer_list (f, Qnil);
1292
1293 free_font_driver_list (f);
1294 xfree (f->namebuf);
1295 xfree (f->decode_mode_spec_buffer);
1296 xfree (FRAME_INSERT_COST (f));
1297 xfree (FRAME_DELETEN_COST (f));
1298 xfree (FRAME_INSERTN_COST (f));
1299 xfree (FRAME_DELETE_COST (f));
1300 xfree (FRAME_MESSAGE_BUF (f));
1301
1302 /* Since some events are handled at the interrupt level, we may get
1303 an event for f at any time; if we zero out the frame's terminal
1304 now, then we may trip up the event-handling code. Instead, we'll
1305 promise that the terminal of the frame must be valid until we
1306 have called the window-system-dependent frame destruction
1307 routine. */
1308
1309 if (FRAME_TERMINAL (f)->delete_frame_hook)
1310 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
1311
1312 {
1313 struct terminal *terminal = FRAME_TERMINAL (f);
1314 f->output_data.nothing = 0;
1315 f->terminal = 0; /* Now the frame is dead. */
1316
1317 /* If needed, delete the terminal that this frame was on.
1318 (This must be done after the frame is killed.) */
1319 terminal->reference_count--;
1320 #ifdef USE_GTK
1321 /* FIXME: Deleting the terminal crashes emacs because of a GTK
1322 bug.
1323 http://lists.gnu.org/archive/html/emacs-devel/2011-10/msg00363.html */
1324 if (terminal->reference_count == 0 && terminal->type == output_x_window)
1325 terminal->reference_count = 1;
1326 #endif /* USE_GTK */
1327 if (terminal->reference_count == 0)
1328 {
1329 Lisp_Object tmp;
1330 XSETTERMINAL (tmp, terminal);
1331
1332 kb = NULL;
1333 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
1334 }
1335 else
1336 kb = terminal->kboard;
1337 }
1338
1339 /* If we've deleted the last_nonminibuf_frame, then try to find
1340 another one. */
1341 if (f == last_nonminibuf_frame)
1342 {
1343 Lisp_Object frames, this;
1344
1345 last_nonminibuf_frame = 0;
1346
1347 FOR_EACH_FRAME (frames, this)
1348 {
1349 f = XFRAME (this);
1350 if (!FRAME_MINIBUF_ONLY_P (f))
1351 {
1352 last_nonminibuf_frame = f;
1353 break;
1354 }
1355 }
1356 }
1357
1358 /* If there's no other frame on the same kboard, get out of
1359 single-kboard state if we're in it for this kboard. */
1360 if (kb != NULL)
1361 {
1362 Lisp_Object frames, this;
1363 /* Some frame we found on the same kboard, or nil if there are none. */
1364 Lisp_Object frame_on_same_kboard = Qnil;
1365
1366 FOR_EACH_FRAME (frames, this)
1367 if (kb == FRAME_KBOARD (XFRAME (this)))
1368 frame_on_same_kboard = this;
1369
1370 if (NILP (frame_on_same_kboard))
1371 not_single_kboard_state (kb);
1372 }
1373
1374
1375 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1376 find another one. Prefer minibuffer-only frames, but also notice
1377 frames with other windows. */
1378 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1379 {
1380 Lisp_Object frames, this;
1381
1382 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1383 Lisp_Object frame_with_minibuf = Qnil;
1384 /* Some frame we found on the same kboard, or nil if there are none. */
1385 Lisp_Object frame_on_same_kboard = Qnil;
1386
1387 FOR_EACH_FRAME (frames, this)
1388 {
1389 struct frame *f1 = XFRAME (this);
1390
1391 /* Consider only frames on the same kboard
1392 and only those with minibuffers. */
1393 if (kb == FRAME_KBOARD (f1)
1394 && FRAME_HAS_MINIBUF_P (f1))
1395 {
1396 frame_with_minibuf = this;
1397 if (FRAME_MINIBUF_ONLY_P (f1))
1398 break;
1399 }
1400
1401 if (kb == FRAME_KBOARD (f1))
1402 frame_on_same_kboard = this;
1403 }
1404
1405 if (!NILP (frame_on_same_kboard))
1406 {
1407 /* We know that there must be some frame with a minibuffer out
1408 there. If this were not true, all of the frames present
1409 would have to be minibufferless, which implies that at some
1410 point their minibuffer frames must have been deleted, but
1411 that is prohibited at the top; you can't delete surrogate
1412 minibuffer frames. */
1413 if (NILP (frame_with_minibuf))
1414 emacs_abort ();
1415
1416 kset_default_minibuffer_frame (kb, frame_with_minibuf);
1417 }
1418 else
1419 /* No frames left on this kboard--say no minibuffer either. */
1420 kset_default_minibuffer_frame (kb, Qnil);
1421 }
1422
1423 /* Cause frame titles to update--necessary if we now have just one frame. */
1424 if (!is_tooltip_frame)
1425 update_mode_lines = 1;
1426
1427 return Qnil;
1428 }
1429
1430 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1431 doc: /* Delete FRAME, permanently eliminating it from use.
1432 FRAME defaults to the selected frame.
1433
1434 A frame may not be deleted if its minibuffer is used by other frames.
1435 Normally, you may not delete a frame if all other frames are invisible,
1436 but if the second optional argument FORCE is non-nil, you may do so.
1437
1438 This function runs `delete-frame-functions' before actually
1439 deleting the frame, unless the frame is a tooltip.
1440 The functions are run with one argument, the frame to be deleted. */)
1441 (Lisp_Object frame, Lisp_Object force)
1442 {
1443 return delete_frame (frame, !NILP (force) ? Qt : Qnil);
1444 }
1445
1446 \f
1447 /* Return mouse position in character cell units. */
1448
1449 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1450 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1451 The position is given in character cells, where (0, 0) is the
1452 upper-left corner of the frame, X is the horizontal offset, and Y is
1453 the vertical offset.
1454 If Emacs is running on a mouseless terminal or hasn't been programmed
1455 to read the mouse position, it returns the selected frame for FRAME
1456 and nil for X and Y.
1457 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1458 passing the normal return value to that function as an argument,
1459 and returns whatever that function returns. */)
1460 (void)
1461 {
1462 FRAME_PTR f;
1463 Lisp_Object lispy_dummy;
1464 Lisp_Object x, y, retval;
1465 struct gcpro gcpro1;
1466
1467 f = SELECTED_FRAME ();
1468 x = y = Qnil;
1469
1470 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1471 /* It's okay for the hook to refrain from storing anything. */
1472 if (FRAME_TERMINAL (f)->mouse_position_hook)
1473 {
1474 enum scroll_bar_part party_dummy;
1475 Time time_dummy;
1476 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1477 &lispy_dummy, &party_dummy,
1478 &x, &y,
1479 &time_dummy);
1480 }
1481
1482 if (! NILP (x))
1483 {
1484 int col = XINT (x);
1485 int row = XINT (y);
1486 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1487 XSETINT (x, col);
1488 XSETINT (y, row);
1489 }
1490 #endif
1491 XSETFRAME (lispy_dummy, f);
1492 retval = Fcons (lispy_dummy, Fcons (x, y));
1493 GCPRO1 (retval);
1494 if (!NILP (Vmouse_position_function))
1495 retval = call1 (Vmouse_position_function, retval);
1496 RETURN_UNGCPRO (retval);
1497 }
1498
1499 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1500 Smouse_pixel_position, 0, 0, 0,
1501 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1502 The position is given in pixel units, where (0, 0) is the
1503 upper-left corner of the frame, X is the horizontal offset, and Y is
1504 the vertical offset.
1505 If Emacs is running on a mouseless terminal or hasn't been programmed
1506 to read the mouse position, it returns the selected frame for FRAME
1507 and nil for X and Y. */)
1508 (void)
1509 {
1510 FRAME_PTR f;
1511 Lisp_Object lispy_dummy;
1512 Lisp_Object x, y;
1513
1514 f = SELECTED_FRAME ();
1515 x = y = Qnil;
1516
1517 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1518 /* It's okay for the hook to refrain from storing anything. */
1519 if (FRAME_TERMINAL (f)->mouse_position_hook)
1520 {
1521 enum scroll_bar_part party_dummy;
1522 Time time_dummy;
1523 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1524 &lispy_dummy, &party_dummy,
1525 &x, &y,
1526 &time_dummy);
1527 }
1528
1529 #endif
1530 XSETFRAME (lispy_dummy, f);
1531 return Fcons (lispy_dummy, Fcons (x, y));
1532 }
1533
1534 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1535 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1536 Coordinates are relative to the frame, not a window,
1537 so the coordinates of the top left character in the frame
1538 may be nonzero due to left-hand scroll bars or the menu bar.
1539
1540 The position is given in character cells, where (0, 0) is the
1541 upper-left corner of the frame, X is the horizontal offset, and Y is
1542 the vertical offset.
1543
1544 This function is a no-op for an X frame that is not visible.
1545 If you have just created a frame, you must wait for it to become visible
1546 before calling this function on it, like this.
1547 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1548 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1549 {
1550 CHECK_LIVE_FRAME (frame);
1551 CHECK_TYPE_RANGED_INTEGER (int, x);
1552 CHECK_TYPE_RANGED_INTEGER (int, y);
1553
1554 /* I think this should be done with a hook. */
1555 #ifdef HAVE_WINDOW_SYSTEM
1556 if (FRAME_WINDOW_P (XFRAME (frame)))
1557 /* Warping the mouse will cause enternotify and focus events. */
1558 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1559 #else
1560 #if defined (MSDOS) && defined (HAVE_MOUSE)
1561 if (FRAME_MSDOS_P (XFRAME (frame)))
1562 {
1563 Fselect_frame (frame, Qnil);
1564 mouse_moveto (XINT (x), XINT (y));
1565 }
1566 #else
1567 #ifdef HAVE_GPM
1568 {
1569 Fselect_frame (frame, Qnil);
1570 term_mouse_moveto (XINT (x), XINT (y));
1571 }
1572 #endif
1573 #endif
1574 #endif
1575
1576 return Qnil;
1577 }
1578
1579 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1580 Sset_mouse_pixel_position, 3, 3, 0,
1581 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1582 The position is given in pixels, where (0, 0) is the upper-left corner
1583 of the frame, X is the horizontal offset, and Y is the vertical offset.
1584
1585 Note, this is a no-op for an X frame that is not visible.
1586 If you have just created a frame, you must wait for it to become visible
1587 before calling this function on it, like this.
1588 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1589 (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
1590 {
1591 CHECK_LIVE_FRAME (frame);
1592 CHECK_TYPE_RANGED_INTEGER (int, x);
1593 CHECK_TYPE_RANGED_INTEGER (int, y);
1594
1595 /* I think this should be done with a hook. */
1596 #ifdef HAVE_WINDOW_SYSTEM
1597 if (FRAME_WINDOW_P (XFRAME (frame)))
1598 /* Warping the mouse will cause enternotify and focus events. */
1599 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1600 #else
1601 #if defined (MSDOS) && defined (HAVE_MOUSE)
1602 if (FRAME_MSDOS_P (XFRAME (frame)))
1603 {
1604 Fselect_frame (frame, Qnil);
1605 mouse_moveto (XINT (x), XINT (y));
1606 }
1607 #else
1608 #ifdef HAVE_GPM
1609 {
1610 Fselect_frame (frame, Qnil);
1611 term_mouse_moveto (XINT (x), XINT (y));
1612 }
1613 #endif
1614 #endif
1615 #endif
1616
1617 return Qnil;
1618 }
1619 \f
1620 static void make_frame_visible_1 (Lisp_Object);
1621
1622 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1623 0, 1, "",
1624 doc: /* Make the frame FRAME visible (assuming it is an X window).
1625 If omitted, FRAME defaults to the currently selected frame. */)
1626 (Lisp_Object frame)
1627 {
1628 struct frame *f = decode_live_frame (frame);
1629
1630 /* I think this should be done with a hook. */
1631 #ifdef HAVE_WINDOW_SYSTEM
1632 if (FRAME_WINDOW_P (f))
1633 {
1634 FRAME_SAMPLE_VISIBILITY (f);
1635 x_make_frame_visible (f);
1636 }
1637 #endif
1638
1639 make_frame_visible_1 (f->root_window);
1640
1641 /* Make menu bar update for the Buffers and Frames menus. */
1642 windows_or_buffers_changed++;
1643
1644 XSETFRAME (frame, f);
1645 return frame;
1646 }
1647
1648 /* Update the display_time slot of the buffers shown in WINDOW
1649 and all its descendants. */
1650
1651 static void
1652 make_frame_visible_1 (Lisp_Object window)
1653 {
1654 struct window *w;
1655
1656 for (;!NILP (window); window = w->next)
1657 {
1658 w = XWINDOW (window);
1659
1660 if (!NILP (w->buffer))
1661 bset_display_time (XBUFFER (w->buffer), Fcurrent_time ());
1662
1663 if (!NILP (w->vchild))
1664 make_frame_visible_1 (w->vchild);
1665 if (!NILP (w->hchild))
1666 make_frame_visible_1 (w->hchild);
1667 }
1668 }
1669
1670 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1671 0, 2, "",
1672 doc: /* Make the frame FRAME invisible.
1673 If omitted, FRAME defaults to the currently selected frame.
1674 On graphical displays, invisible frames are not updated and are
1675 usually not displayed at all, even in a window system's \"taskbar\".
1676
1677 Normally you may not make FRAME invisible if all other frames are invisible,
1678 but if the second optional argument FORCE is non-nil, you may do so.
1679
1680 This function has no effect on text terminal frames. Such frames are
1681 always considered visible, whether or not they are currently being
1682 displayed in the terminal. */)
1683 (Lisp_Object frame, Lisp_Object force)
1684 {
1685 struct frame *f = decode_live_frame (frame);
1686
1687 if (NILP (force) && !other_visible_frames (f))
1688 error ("Attempt to make invisible the sole visible or iconified frame");
1689
1690 /* Don't allow minibuf_window to remain on a deleted frame. */
1691 if (EQ (f->minibuffer_window, minibuf_window))
1692 {
1693 struct frame *sf = XFRAME (selected_frame);
1694 /* Use set_window_buffer instead of Fset_window_buffer (see
1695 discussion of bug#11984, bug#12025, bug#12026). */
1696 set_window_buffer (sf->minibuffer_window,
1697 XWINDOW (minibuf_window)->buffer, 0, 0);
1698 minibuf_window = sf->minibuffer_window;
1699 }
1700
1701 /* I think this should be done with a hook. */
1702 #ifdef HAVE_WINDOW_SYSTEM
1703 if (FRAME_WINDOW_P (f))
1704 x_make_frame_invisible (f);
1705 #endif
1706
1707 /* Make menu bar update for the Buffers and Frames menus. */
1708 windows_or_buffers_changed++;
1709
1710 return Qnil;
1711 }
1712
1713 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1714 0, 1, "",
1715 doc: /* Make the frame FRAME into an icon.
1716 If omitted, FRAME defaults to the currently selected frame. */)
1717 (Lisp_Object frame)
1718 {
1719 struct frame *f = decode_live_frame (frame);
1720
1721 /* Don't allow minibuf_window to remain on an iconified frame. */
1722 if (EQ (f->minibuffer_window, minibuf_window))
1723 {
1724 struct frame *sf = XFRAME (selected_frame);
1725 /* Use set_window_buffer instead of Fset_window_buffer (see
1726 discussion of bug#11984, bug#12025, bug#12026). */
1727 set_window_buffer (sf->minibuffer_window,
1728 XWINDOW (minibuf_window)->buffer, 0, 0);
1729 minibuf_window = sf->minibuffer_window;
1730 }
1731
1732 /* I think this should be done with a hook. */
1733 #ifdef HAVE_WINDOW_SYSTEM
1734 if (FRAME_WINDOW_P (f))
1735 x_iconify_frame (f);
1736 #endif
1737
1738 /* Make menu bar update for the Buffers and Frames menus. */
1739 windows_or_buffers_changed++;
1740
1741 return Qnil;
1742 }
1743
1744 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1745 1, 1, 0,
1746 doc: /* Return t if FRAME is \"visible\" (actually in use for display).
1747 Return the symbol `icon' if FRAME is iconified or \"minimized\".
1748 Return nil if FRAME was made invisible, via `make-frame-invisible'.
1749 On graphical displays, invisible frames are not updated and are
1750 usually not displayed at all, even in a window system's \"taskbar\".
1751
1752 If FRAME is a text terminal frame, this always returns t.
1753 Such frames are always considered visible, whether or not they are
1754 currently being displayed on the terminal. */)
1755 (Lisp_Object frame)
1756 {
1757 CHECK_LIVE_FRAME (frame);
1758
1759 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1760
1761 if (FRAME_VISIBLE_P (XFRAME (frame)))
1762 return Qt;
1763 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1764 return Qicon;
1765 return Qnil;
1766 }
1767
1768 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1769 0, 0, 0,
1770 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1771 (void)
1772 {
1773 Lisp_Object tail, frame, value = Qnil;
1774
1775 FOR_EACH_FRAME (tail, frame)
1776 if (FRAME_VISIBLE_P (XFRAME (frame)))
1777 value = Fcons (frame, value);
1778
1779 return value;
1780 }
1781
1782
1783 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1784 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
1785 If FRAME is invisible or iconified, make it visible.
1786 If you don't specify a frame, the selected frame is used.
1787 If Emacs is displaying on an ordinary terminal or some other device which
1788 doesn't support multiple overlapping frames, this function selects FRAME. */)
1789 (Lisp_Object frame)
1790 {
1791 struct frame *f = decode_live_frame (frame);
1792
1793 XSETFRAME (frame, f);
1794
1795 if (FRAME_TERMCAP_P (f))
1796 /* On a text terminal select FRAME. */
1797 Fselect_frame (frame, Qnil);
1798 else
1799 /* Do like the documentation says. */
1800 Fmake_frame_visible (frame);
1801
1802 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1803 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
1804
1805 return Qnil;
1806 }
1807
1808 /* Should we have a corresponding function called Flower_Power? */
1809 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1810 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
1811 If you don't specify a frame, the selected frame is used.
1812 If Emacs is displaying on an ordinary terminal or some other device which
1813 doesn't support multiple overlapping frames, this function does nothing. */)
1814 (Lisp_Object frame)
1815 {
1816 struct frame *f = decode_live_frame (frame);
1817
1818 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1819 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
1820
1821 return Qnil;
1822 }
1823
1824 \f
1825 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1826 1, 2, 0,
1827 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
1828 In other words, switch-frame events caused by events in FRAME will
1829 request a switch to FOCUS-FRAME, and `last-event-frame' will be
1830 FOCUS-FRAME after reading an event typed at FRAME.
1831
1832 If FOCUS-FRAME is nil, any existing redirection is canceled, and the
1833 frame again receives its own keystrokes.
1834
1835 Focus redirection is useful for temporarily redirecting keystrokes to
1836 a surrogate minibuffer frame when a frame doesn't have its own
1837 minibuffer window.
1838
1839 A frame's focus redirection can be changed by `select-frame'. If frame
1840 FOO is selected, and then a different frame BAR is selected, any
1841 frames redirecting their focus to FOO are shifted to redirect their
1842 focus to BAR. This allows focus redirection to work properly when the
1843 user switches from one frame to another using `select-window'.
1844
1845 This means that a frame whose focus is redirected to itself is treated
1846 differently from a frame whose focus is redirected to nil; the former
1847 is affected by `select-frame', while the latter is not.
1848
1849 The redirection lasts until `redirect-frame-focus' is called to change it. */)
1850 (Lisp_Object frame, Lisp_Object focus_frame)
1851 {
1852 /* Note that we don't check for a live frame here. It's reasonable
1853 to redirect the focus of a frame you're about to delete, if you
1854 know what other frame should receive those keystrokes. */
1855 struct frame *f = decode_any_frame (frame);
1856
1857 if (! NILP (focus_frame))
1858 CHECK_LIVE_FRAME (focus_frame);
1859
1860 fset_focus_frame (f, focus_frame);
1861
1862 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
1863 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
1864
1865 return Qnil;
1866 }
1867
1868
1869 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 0, 1, 0,
1870 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
1871 If FRAME is omitted or nil, the selected frame is used.
1872 Return nil if FRAME's focus is not redirected.
1873 See `redirect-frame-focus'. */)
1874 (Lisp_Object frame)
1875 {
1876 return FRAME_FOCUS_FRAME (decode_live_frame (frame));
1877 }
1878
1879
1880 \f
1881 /* Return the value of frame parameter PROP in frame FRAME. */
1882
1883 #ifdef HAVE_WINDOW_SYSTEM
1884 #if !HAVE_NS
1885 static
1886 #endif
1887 Lisp_Object
1888 get_frame_param (register struct frame *frame, Lisp_Object prop)
1889 {
1890 register Lisp_Object tem;
1891
1892 tem = Fassq (prop, frame->param_alist);
1893 if (EQ (tem, Qnil))
1894 return tem;
1895 return Fcdr (tem);
1896 }
1897 #endif
1898
1899 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
1900
1901 void
1902 frames_discard_buffer (Lisp_Object buffer)
1903 {
1904 Lisp_Object frame, tail;
1905
1906 FOR_EACH_FRAME (tail, frame)
1907 {
1908 fset_buffer_list
1909 (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buffer_list));
1910 fset_buried_buffer_list
1911 (XFRAME (frame), Fdelq (buffer, XFRAME (frame)->buried_buffer_list));
1912 }
1913 }
1914
1915 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1916 If the alist already has an element for PROP, we change it. */
1917
1918 void
1919 store_in_alist (Lisp_Object *alistptr, Lisp_Object prop, Lisp_Object val)
1920 {
1921 register Lisp_Object tem;
1922
1923 tem = Fassq (prop, *alistptr);
1924 if (EQ (tem, Qnil))
1925 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1926 else
1927 Fsetcdr (tem, val);
1928 }
1929
1930 static int
1931 frame_name_fnn_p (char *str, ptrdiff_t len)
1932 {
1933 if (len > 1 && str[0] == 'F' && '0' <= str[1] && str[1] <= '9')
1934 {
1935 char *p = str + 2;
1936 while ('0' <= *p && *p <= '9')
1937 p++;
1938 if (p == str + len)
1939 return 1;
1940 }
1941 return 0;
1942 }
1943
1944 /* Set the name of the terminal frame. Also used by MSDOS frames.
1945 Modeled after x_set_name which is used for WINDOW frames. */
1946
1947 static void
1948 set_term_frame_name (struct frame *f, Lisp_Object name)
1949 {
1950 f->explicit_name = ! NILP (name);
1951
1952 /* If NAME is nil, set the name to F<num>. */
1953 if (NILP (name))
1954 {
1955 char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
1956
1957 /* Check for no change needed in this very common case
1958 before we do any consing. */
1959 if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name)))
1960 return;
1961
1962 name = make_formatted_string (namebuf, "F%"pMd, ++tty_frame_count);
1963 }
1964 else
1965 {
1966 CHECK_STRING (name);
1967
1968 /* Don't change the name if it's already NAME. */
1969 if (! NILP (Fstring_equal (name, f->name)))
1970 return;
1971
1972 /* Don't allow the user to set the frame name to F<num>, so it
1973 doesn't clash with the names we generate for terminal frames. */
1974 if (frame_name_fnn_p (SSDATA (name), SBYTES (name)))
1975 error ("Frame names of the form F<num> are usurped by Emacs");
1976 }
1977
1978 fset_name (f, name);
1979 update_mode_lines = 1;
1980 }
1981
1982 void
1983 store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
1984 {
1985 register Lisp_Object old_alist_elt;
1986
1987 /* The buffer-list parameters are stored in a special place and not
1988 in the alist. All buffers must be live. */
1989 if (EQ (prop, Qbuffer_list))
1990 {
1991 Lisp_Object list = Qnil;
1992 for (; CONSP (val); val = XCDR (val))
1993 if (!NILP (Fbuffer_live_p (XCAR (val))))
1994 list = Fcons (XCAR (val), list);
1995 fset_buffer_list (f, Fnreverse (list));
1996 return;
1997 }
1998 if (EQ (prop, Qburied_buffer_list))
1999 {
2000 Lisp_Object list = Qnil;
2001 for (; CONSP (val); val = XCDR (val))
2002 if (!NILP (Fbuffer_live_p (XCAR (val))))
2003 list = Fcons (XCAR (val), list);
2004 fset_buried_buffer_list (f, Fnreverse (list));
2005 return;
2006 }
2007
2008 /* If PROP is a symbol which is supposed to have frame-local values,
2009 and it is set up based on this frame, switch to the global
2010 binding. That way, we can create or alter the frame-local binding
2011 without messing up the symbol's status. */
2012 if (SYMBOLP (prop))
2013 {
2014 struct Lisp_Symbol *sym = XSYMBOL (prop);
2015 start:
2016 switch (sym->redirect)
2017 {
2018 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2019 case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
2020 case SYMBOL_LOCALIZED:
2021 { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
2022 if (blv->frame_local && blv_found (blv) && XFRAME (blv->where) == f)
2023 swap_in_global_binding (sym);
2024 break;
2025 }
2026 default: emacs_abort ();
2027 }
2028 }
2029
2030 /* The tty color needed to be set before the frame's parameter
2031 alist was updated with the new value. This is not true any more,
2032 but we still do this test early on. */
2033 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2034 && f == FRAME_TTY (f)->previous_frame)
2035 /* Force redisplay of this tty. */
2036 FRAME_TTY (f)->previous_frame = NULL;
2037
2038 /* Update the frame parameter alist. */
2039 old_alist_elt = Fassq (prop, f->param_alist);
2040 if (EQ (old_alist_elt, Qnil))
2041 fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
2042 else
2043 Fsetcdr (old_alist_elt, val);
2044
2045 /* Update some other special parameters in their special places
2046 in addition to the alist. */
2047
2048 if (EQ (prop, Qbuffer_predicate))
2049 fset_buffer_predicate (f, val);
2050
2051 if (! FRAME_WINDOW_P (f))
2052 {
2053 if (EQ (prop, Qmenu_bar_lines))
2054 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2055 else if (EQ (prop, Qname))
2056 set_term_frame_name (f, val);
2057 }
2058
2059 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2060 {
2061 if (! MINI_WINDOW_P (XWINDOW (val)))
2062 error ("Surrogate minibuffer windows must be minibuffer windows");
2063
2064 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2065 && !EQ (val, f->minibuffer_window))
2066 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2067
2068 /* Install the chosen minibuffer window, with proper buffer. */
2069 fset_minibuffer_window (f, val);
2070 }
2071 }
2072
2073 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2074 doc: /* Return the parameters-alist of frame FRAME.
2075 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2076 The meaningful PARMs depend on the kind of frame.
2077 If FRAME is omitted or nil, return information on the currently selected frame. */)
2078 (Lisp_Object frame)
2079 {
2080 Lisp_Object alist;
2081 struct frame *f = decode_any_frame (frame);
2082 int height, width;
2083 struct gcpro gcpro1;
2084
2085 if (!FRAME_LIVE_P (f))
2086 return Qnil;
2087
2088 alist = Fcopy_alist (f->param_alist);
2089 GCPRO1 (alist);
2090
2091 if (!FRAME_WINDOW_P (f))
2092 {
2093 int fg = FRAME_FOREGROUND_PIXEL (f);
2094 int bg = FRAME_BACKGROUND_PIXEL (f);
2095 Lisp_Object elt;
2096
2097 /* If the frame's parameter alist says the colors are
2098 unspecified and reversed, take the frame's background pixel
2099 for foreground and vice versa. */
2100 elt = Fassq (Qforeground_color, alist);
2101 if (CONSP (elt) && STRINGP (XCDR (elt)))
2102 {
2103 if (strncmp (SSDATA (XCDR (elt)),
2104 unspecified_bg,
2105 SCHARS (XCDR (elt))) == 0)
2106 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2107 else if (strncmp (SSDATA (XCDR (elt)),
2108 unspecified_fg,
2109 SCHARS (XCDR (elt))) == 0)
2110 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2111 }
2112 else
2113 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2114 elt = Fassq (Qbackground_color, alist);
2115 if (CONSP (elt) && STRINGP (XCDR (elt)))
2116 {
2117 if (strncmp (SSDATA (XCDR (elt)),
2118 unspecified_fg,
2119 SCHARS (XCDR (elt))) == 0)
2120 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2121 else if (strncmp (SSDATA (XCDR (elt)),
2122 unspecified_bg,
2123 SCHARS (XCDR (elt))) == 0)
2124 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2125 }
2126 else
2127 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2128 store_in_alist (&alist, intern ("font"),
2129 build_string (FRAME_MSDOS_P (f)
2130 ? "ms-dos"
2131 : FRAME_W32_P (f) ? "w32term"
2132 :"tty"));
2133 }
2134 store_in_alist (&alist, Qname, f->name);
2135 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2136 store_in_alist (&alist, Qheight, make_number (height));
2137 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2138 store_in_alist (&alist, Qwidth, make_number (width));
2139 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2140 store_in_alist (&alist, Qminibuffer,
2141 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2142 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2143 : FRAME_MINIBUF_WINDOW (f)));
2144 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2145 store_in_alist (&alist, Qbuffer_list, f->buffer_list);
2146 store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
2147
2148 /* I think this should be done with a hook. */
2149 #ifdef HAVE_WINDOW_SYSTEM
2150 if (FRAME_WINDOW_P (f))
2151 x_report_frame_params (f, &alist);
2152 else
2153 #endif
2154 {
2155 /* This ought to be correct in f->param_alist for an X frame. */
2156 Lisp_Object lines;
2157 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2158 store_in_alist (&alist, Qmenu_bar_lines, lines);
2159 }
2160
2161 UNGCPRO;
2162 return alist;
2163 }
2164
2165
2166 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2167 doc: /* Return FRAME's value for parameter PARAMETER.
2168 If FRAME is nil, describe the currently selected frame. */)
2169 (Lisp_Object frame, Lisp_Object parameter)
2170 {
2171 struct frame *f = decode_any_frame (frame);
2172 Lisp_Object value = Qnil;
2173
2174 CHECK_SYMBOL (parameter);
2175
2176 XSETFRAME (frame, f);
2177
2178 if (FRAME_LIVE_P (f))
2179 {
2180 /* Avoid consing in frequent cases. */
2181 if (EQ (parameter, Qname))
2182 value = f->name;
2183 #ifdef HAVE_X_WINDOWS
2184 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2185 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2186 #endif /* HAVE_X_WINDOWS */
2187 else if (EQ (parameter, Qbackground_color)
2188 || EQ (parameter, Qforeground_color))
2189 {
2190 value = Fassq (parameter, f->param_alist);
2191 if (CONSP (value))
2192 {
2193 value = XCDR (value);
2194 /* Fframe_parameters puts the actual fg/bg color names,
2195 even if f->param_alist says otherwise. This is
2196 important when param_alist's notion of colors is
2197 "unspecified". We need to do the same here. */
2198 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2199 {
2200 const char *color_name;
2201 ptrdiff_t csz;
2202
2203 if (EQ (parameter, Qbackground_color))
2204 {
2205 color_name = SSDATA (value);
2206 csz = SCHARS (value);
2207 if (strncmp (color_name, unspecified_bg, csz) == 0)
2208 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2209 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2210 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2211 }
2212 else if (EQ (parameter, Qforeground_color))
2213 {
2214 color_name = SSDATA (value);
2215 csz = SCHARS (value);
2216 if (strncmp (color_name, unspecified_fg, csz) == 0)
2217 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2218 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2219 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2220 }
2221 }
2222 }
2223 else
2224 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2225 }
2226 else if (EQ (parameter, Qdisplay_type)
2227 || EQ (parameter, Qbackground_mode))
2228 value = Fcdr (Fassq (parameter, f->param_alist));
2229 else
2230 /* FIXME: Avoid this code path at all (as well as code duplication)
2231 by sharing more code with Fframe_parameters. */
2232 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2233 }
2234
2235 return value;
2236 }
2237
2238
2239 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2240 Smodify_frame_parameters, 2, 2, 0,
2241 doc: /* Modify the parameters of frame FRAME according to ALIST.
2242 If FRAME is nil, it defaults to the selected frame.
2243 ALIST is an alist of parameters to change and their new values.
2244 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2245 The meaningful PARMs depend on the kind of frame.
2246 Undefined PARMs are ignored, but stored in the frame's parameter list
2247 so that `frame-parameters' will return them.
2248
2249 The value of frame parameter FOO can also be accessed
2250 as a frame-local binding for the variable FOO, if you have
2251 enabled such bindings for that variable with `make-variable-frame-local'.
2252 Note that this functionality is obsolete as of Emacs 22.2, and its
2253 use is not recommended. Explicitly check for a frame-parameter instead. */)
2254 (Lisp_Object frame, Lisp_Object alist)
2255 {
2256 struct frame *f = decode_live_frame (frame);
2257 register Lisp_Object tail, prop, val;
2258
2259 /* I think this should be done with a hook. */
2260 #ifdef HAVE_WINDOW_SYSTEM
2261 if (FRAME_WINDOW_P (f))
2262 x_set_frame_parameters (f, alist);
2263 else
2264 #endif
2265 #ifdef MSDOS
2266 if (FRAME_MSDOS_P (f))
2267 IT_set_frame_parameters (f, alist);
2268 else
2269 #endif
2270
2271 {
2272 EMACS_INT length = XFASTINT (Flength (alist));
2273 ptrdiff_t i;
2274 Lisp_Object *parms;
2275 Lisp_Object *values;
2276 USE_SAFE_ALLOCA;
2277 SAFE_ALLOCA_LISP (parms, 2 * length);
2278 values = parms + length;
2279
2280 /* Extract parm names and values into those vectors. */
2281
2282 i = 0;
2283 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2284 {
2285 Lisp_Object elt;
2286
2287 elt = XCAR (tail);
2288 parms[i] = Fcar (elt);
2289 values[i] = Fcdr (elt);
2290 i++;
2291 }
2292
2293 /* Now process them in reverse of specified order. */
2294 while (--i >= 0)
2295 {
2296 prop = parms[i];
2297 val = values[i];
2298 store_frame_param (f, prop, val);
2299
2300 if (EQ (prop, Qforeground_color)
2301 || EQ (prop, Qbackground_color))
2302 update_face_from_frame_parameter (f, prop, val);
2303 }
2304
2305 SAFE_FREE ();
2306 }
2307 return Qnil;
2308 }
2309 \f
2310 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2311 0, 1, 0,
2312 doc: /* Height in pixels of a line in the font in frame FRAME.
2313 If FRAME is omitted or nil, the selected frame is used.
2314 For a terminal frame, the value is always 1. */)
2315 (Lisp_Object frame)
2316 {
2317 #ifdef HAVE_WINDOW_SYSTEM
2318 struct frame *f = decode_any_frame (frame);
2319
2320 if (FRAME_WINDOW_P (f))
2321 return make_number (x_char_height (f));
2322 else
2323 #endif
2324 return make_number (1);
2325 }
2326
2327
2328 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2329 0, 1, 0,
2330 doc: /* Width in pixels of characters in the font in frame FRAME.
2331 If FRAME is omitted or nil, the selected frame is used.
2332 On a graphical screen, the width is the standard width of the default font.
2333 For a terminal screen, the value is always 1. */)
2334 (Lisp_Object frame)
2335 {
2336 #ifdef HAVE_WINDOW_SYSTEM
2337 struct frame *f = decode_any_frame (frame);
2338
2339 if (FRAME_WINDOW_P (f))
2340 return make_number (x_char_width (f));
2341 else
2342 #endif
2343 return make_number (1);
2344 }
2345
2346 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2347 Sframe_pixel_height, 0, 1, 0,
2348 doc: /* Return a FRAME's height in pixels.
2349 If FRAME is omitted or nil, the selected frame is used. The exact value
2350 of the result depends on the window-system and toolkit in use:
2351
2352 In the Gtk+ version of Emacs, it includes only any window (including
2353 the minibuffer or echo area), mode line, and header line. It does not
2354 include the tool bar or menu bar.
2355
2356 With other graphical versions, it also includes the tool bar and the
2357 menu bar.
2358
2359 For a text terminal, it includes the menu bar. In this case, the
2360 result is really in characters rather than pixels (i.e., is identical
2361 to `frame-height'). */)
2362 (Lisp_Object frame)
2363 {
2364 struct frame *f = decode_any_frame (frame);
2365
2366 #ifdef HAVE_WINDOW_SYSTEM
2367 if (FRAME_WINDOW_P (f))
2368 return make_number (x_pixel_height (f));
2369 else
2370 #endif
2371 return make_number (FRAME_LINES (f));
2372 }
2373
2374 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2375 Sframe_pixel_width, 0, 1, 0,
2376 doc: /* Return FRAME's width in pixels.
2377 For a terminal frame, the result really gives the width in characters.
2378 If FRAME is omitted or nil, the selected frame is used. */)
2379 (Lisp_Object frame)
2380 {
2381 struct frame *f = decode_any_frame (frame);
2382
2383 #ifdef HAVE_WINDOW_SYSTEM
2384 if (FRAME_WINDOW_P (f))
2385 return make_number (x_pixel_width (f));
2386 else
2387 #endif
2388 return make_number (FRAME_COLS (f));
2389 }
2390
2391 DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
2392 Stool_bar_pixel_width, 0, 1, 0,
2393 doc: /* Return width in pixels of FRAME's tool bar.
2394 The result is greater than zero only when the tool bar is on the left
2395 or right side of FRAME. If FRAME is omitted or nil, the selected frame
2396 is used. */)
2397 (Lisp_Object frame)
2398 {
2399 #ifdef FRAME_TOOLBAR_WIDTH
2400 struct frame *f = decode_any_frame (frame);
2401
2402 if (FRAME_WINDOW_P (f))
2403 return make_number (FRAME_TOOLBAR_WIDTH (f));
2404 #endif
2405 return make_number (0);
2406 }
2407 \f
2408 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2409 doc: /* Specify that the frame FRAME has LINES lines.
2410 Optional third arg non-nil means that redisplay should use LINES lines
2411 but that the idea of the actual height of the frame should not be changed. */)
2412 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
2413 {
2414 register struct frame *f = decode_live_frame (frame);
2415
2416 CHECK_TYPE_RANGED_INTEGER (int, lines);
2417
2418 /* I think this should be done with a hook. */
2419 #ifdef HAVE_WINDOW_SYSTEM
2420 if (FRAME_WINDOW_P (f))
2421 {
2422 if (XINT (lines) != FRAME_LINES (f))
2423 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
2424 do_pending_window_change (0);
2425 }
2426 else
2427 #endif
2428 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2429 return Qnil;
2430 }
2431
2432 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2433 doc: /* Specify that the frame FRAME has COLS columns.
2434 Optional third arg non-nil means that redisplay should use COLS columns
2435 but that the idea of the actual width of the frame should not be changed. */)
2436 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
2437 {
2438 register struct frame *f = decode_live_frame (frame);
2439
2440 CHECK_TYPE_RANGED_INTEGER (int, cols);
2441
2442 /* I think this should be done with a hook. */
2443 #ifdef HAVE_WINDOW_SYSTEM
2444 if (FRAME_WINDOW_P (f))
2445 {
2446 if (XINT (cols) != FRAME_COLS (f))
2447 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
2448 do_pending_window_change (0);
2449 }
2450 else
2451 #endif
2452 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2453 return Qnil;
2454 }
2455
2456 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2457 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2458 (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows)
2459 {
2460 register struct frame *f;
2461
2462 CHECK_LIVE_FRAME (frame);
2463 CHECK_TYPE_RANGED_INTEGER (int, cols);
2464 CHECK_TYPE_RANGED_INTEGER (int, rows);
2465 f = XFRAME (frame);
2466
2467 /* I think this should be done with a hook. */
2468 #ifdef HAVE_WINDOW_SYSTEM
2469 if (FRAME_WINDOW_P (f))
2470 {
2471 if (XINT (rows) != FRAME_LINES (f)
2472 || XINT (cols) != FRAME_COLS (f)
2473 || f->new_text_lines || f->new_text_cols)
2474 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2475 do_pending_window_change (0);
2476 }
2477 else
2478 #endif
2479 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2480
2481 return Qnil;
2482 }
2483
2484 DEFUN ("set-frame-position", Fset_frame_position,
2485 Sset_frame_position, 3, 3, 0,
2486 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2487 This is actually the position of the upper left corner of the frame.
2488 Negative values for XOFFSET or YOFFSET are interpreted relative to
2489 the rightmost or bottommost possible position (that stays within the screen). */)
2490 (Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset)
2491 {
2492 register struct frame *f;
2493
2494 CHECK_LIVE_FRAME (frame);
2495 CHECK_TYPE_RANGED_INTEGER (int, xoffset);
2496 CHECK_TYPE_RANGED_INTEGER (int, yoffset);
2497 f = XFRAME (frame);
2498
2499 /* I think this should be done with a hook. */
2500 #ifdef HAVE_WINDOW_SYSTEM
2501 if (FRAME_WINDOW_P (f))
2502 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2503 #endif
2504
2505 return Qt;
2506 }
2507
2508 \f
2509 /***********************************************************************
2510 Frame Parameters
2511 ***********************************************************************/
2512
2513 /* Connect the frame-parameter names for X frames
2514 to the ways of passing the parameter values to the window system.
2515
2516 The name of a parameter, as a Lisp symbol,
2517 has an `x-frame-parameter' property which is an integer in Lisp
2518 that is an index in this table. */
2519
2520 struct frame_parm_table {
2521 const char *name;
2522 Lisp_Object *variable;
2523 };
2524
2525 static const struct frame_parm_table frame_parms[] =
2526 {
2527 {"auto-raise", &Qauto_raise},
2528 {"auto-lower", &Qauto_lower},
2529 {"background-color", 0},
2530 {"border-color", &Qborder_color},
2531 {"border-width", &Qborder_width},
2532 {"cursor-color", &Qcursor_color},
2533 {"cursor-type", &Qcursor_type},
2534 {"font", 0},
2535 {"foreground-color", 0},
2536 {"icon-name", &Qicon_name},
2537 {"icon-type", &Qicon_type},
2538 {"internal-border-width", &Qinternal_border_width},
2539 {"menu-bar-lines", &Qmenu_bar_lines},
2540 {"mouse-color", &Qmouse_color},
2541 {"name", &Qname},
2542 {"scroll-bar-width", &Qscroll_bar_width},
2543 {"title", &Qtitle},
2544 {"unsplittable", &Qunsplittable},
2545 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2546 {"visibility", &Qvisibility},
2547 {"tool-bar-lines", &Qtool_bar_lines},
2548 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2549 {"scroll-bar-background", &Qscroll_bar_background},
2550 {"screen-gamma", &Qscreen_gamma},
2551 {"line-spacing", &Qline_spacing},
2552 {"left-fringe", &Qleft_fringe},
2553 {"right-fringe", &Qright_fringe},
2554 {"wait-for-wm", &Qwait_for_wm},
2555 {"fullscreen", &Qfullscreen},
2556 {"font-backend", &Qfont_backend},
2557 {"alpha", &Qalpha},
2558 {"sticky", &Qsticky},
2559 {"tool-bar-position", &Qtool_bar_position},
2560 };
2561
2562 #ifdef HAVE_NTGUI
2563
2564 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2565 wanted positions of the WM window (not Emacs window).
2566 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2567 window (FRAME_X_WINDOW).
2568 */
2569
2570 void
2571 x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos)
2572 {
2573 int newwidth = FRAME_COLS (f);
2574 int newheight = FRAME_LINES (f);
2575 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2576
2577 *top_pos = f->top_pos;
2578 *left_pos = f->left_pos;
2579
2580 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
2581 {
2582 int ph;
2583
2584 ph = x_display_pixel_height (dpyinfo);
2585 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2586 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2587 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2588 *top_pos = 0;
2589 }
2590
2591 if (f->want_fullscreen & FULLSCREEN_WIDTH)
2592 {
2593 int pw;
2594
2595 pw = x_display_pixel_width (dpyinfo);
2596 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2597 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2598 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2599 *left_pos = 0;
2600 }
2601
2602 *width = newwidth;
2603 *height = newheight;
2604 }
2605
2606 #endif /* HAVE_NTGUI */
2607
2608 #ifdef HAVE_WINDOW_SYSTEM
2609
2610 /* Change the parameters of frame F as specified by ALIST.
2611 If a parameter is not specially recognized, do nothing special;
2612 otherwise call the `x_set_...' function for that parameter.
2613 Except for certain geometry properties, always call store_frame_param
2614 to store the new value in the parameter alist. */
2615
2616 void
2617 x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
2618 {
2619 Lisp_Object tail;
2620
2621 /* If both of these parameters are present, it's more efficient to
2622 set them both at once. So we wait until we've looked at the
2623 entire list before we set them. */
2624 int width, height;
2625
2626 /* Same here. */
2627 Lisp_Object left, top;
2628
2629 /* Same with these. */
2630 Lisp_Object icon_left, icon_top;
2631
2632 /* Record in these vectors all the parms specified. */
2633 Lisp_Object *parms;
2634 Lisp_Object *values;
2635 ptrdiff_t i, p;
2636 int left_no_change = 0, top_no_change = 0;
2637 int icon_left_no_change = 0, icon_top_no_change = 0;
2638 int size_changed = 0;
2639 struct gcpro gcpro1, gcpro2;
2640
2641 i = 0;
2642 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2643 i++;
2644
2645 parms = alloca (i * sizeof *parms);
2646 values = alloca (i * sizeof *values);
2647
2648 /* Extract parm names and values into those vectors. */
2649
2650 i = 0;
2651 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2652 {
2653 Lisp_Object elt;
2654
2655 elt = XCAR (tail);
2656 parms[i] = Fcar (elt);
2657 values[i] = Fcdr (elt);
2658 i++;
2659 }
2660 /* TAIL and ALIST are not used again below here. */
2661 alist = tail = Qnil;
2662
2663 GCPRO2 (*parms, *values);
2664 gcpro1.nvars = i;
2665 gcpro2.nvars = i;
2666
2667 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2668 because their values appear in VALUES and strings are not valid. */
2669 top = left = Qunbound;
2670 icon_left = icon_top = Qunbound;
2671
2672 /* Provide default values for HEIGHT and WIDTH. */
2673 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2674 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2675
2676 /* Process foreground_color and background_color before anything else.
2677 They are independent of other properties, but other properties (e.g.,
2678 cursor_color) are dependent upon them. */
2679 /* Process default font as well, since fringe widths depends on it. */
2680 for (p = 0; p < i; p++)
2681 {
2682 Lisp_Object prop, val;
2683
2684 prop = parms[p];
2685 val = values[p];
2686 if (EQ (prop, Qforeground_color)
2687 || EQ (prop, Qbackground_color)
2688 || EQ (prop, Qfont))
2689 {
2690 register Lisp_Object param_index, old_value;
2691
2692 old_value = get_frame_param (f, prop);
2693 if (NILP (Fequal (val, old_value)))
2694 {
2695 store_frame_param (f, prop, val);
2696
2697 param_index = Fget (prop, Qx_frame_parameter);
2698 if (NATNUMP (param_index)
2699 && (XFASTINT (param_index)
2700 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2701 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2702 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2703 }
2704 }
2705 }
2706
2707 /* Now process them in reverse of specified order. */
2708 while (i-- != 0)
2709 {
2710 Lisp_Object prop, val;
2711
2712 prop = parms[i];
2713 val = values[i];
2714
2715 if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX))
2716 {
2717 size_changed = 1;
2718 width = XFASTINT (val);
2719 }
2720 else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX))
2721 {
2722 size_changed = 1;
2723 height = XFASTINT (val);
2724 }
2725 else if (EQ (prop, Qtop))
2726 top = val;
2727 else if (EQ (prop, Qleft))
2728 left = val;
2729 else if (EQ (prop, Qicon_top))
2730 icon_top = val;
2731 else if (EQ (prop, Qicon_left))
2732 icon_left = val;
2733 else if (EQ (prop, Qforeground_color)
2734 || EQ (prop, Qbackground_color)
2735 || EQ (prop, Qfont))
2736 /* Processed above. */
2737 continue;
2738 else
2739 {
2740 register Lisp_Object param_index, old_value;
2741
2742 old_value = get_frame_param (f, prop);
2743
2744 store_frame_param (f, prop, val);
2745
2746 param_index = Fget (prop, Qx_frame_parameter);
2747 if (NATNUMP (param_index)
2748 && (XFASTINT (param_index)
2749 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2750 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
2751 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2752 }
2753 }
2754
2755 /* Don't die if just one of these was set. */
2756 if (EQ (left, Qunbound))
2757 {
2758 left_no_change = 1;
2759 if (f->left_pos < 0)
2760 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
2761 else
2762 XSETINT (left, f->left_pos);
2763 }
2764 if (EQ (top, Qunbound))
2765 {
2766 top_no_change = 1;
2767 if (f->top_pos < 0)
2768 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
2769 else
2770 XSETINT (top, f->top_pos);
2771 }
2772
2773 /* If one of the icon positions was not set, preserve or default it. */
2774 if (! TYPE_RANGED_INTEGERP (int, icon_left))
2775 {
2776 icon_left_no_change = 1;
2777 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
2778 if (NILP (icon_left))
2779 XSETINT (icon_left, 0);
2780 }
2781 if (! TYPE_RANGED_INTEGERP (int, icon_top))
2782 {
2783 icon_top_no_change = 1;
2784 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
2785 if (NILP (icon_top))
2786 XSETINT (icon_top, 0);
2787 }
2788
2789 /* Don't set these parameters unless they've been explicitly
2790 specified. The window might be mapped or resized while we're in
2791 this function, and we don't want to override that unless the lisp
2792 code has asked for it.
2793
2794 Don't set these parameters unless they actually differ from the
2795 window's current parameters; the window may not actually exist
2796 yet. */
2797 {
2798 Lisp_Object frame;
2799
2800 check_frame_size (f, &height, &width);
2801
2802 XSETFRAME (frame, f);
2803
2804 if (size_changed
2805 && (width != FRAME_COLS (f)
2806 || height != FRAME_LINES (f)
2807 || f->new_text_lines || f->new_text_cols))
2808 Fset_frame_size (frame, make_number (width), make_number (height));
2809
2810 if ((!NILP (left) || !NILP (top))
2811 && ! (left_no_change && top_no_change)
2812 && ! (NUMBERP (left) && XINT (left) == f->left_pos
2813 && NUMBERP (top) && XINT (top) == f->top_pos))
2814 {
2815 int leftpos = 0;
2816 int toppos = 0;
2817
2818 /* Record the signs. */
2819 f->size_hint_flags &= ~ (XNegative | YNegative);
2820 if (EQ (left, Qminus))
2821 f->size_hint_flags |= XNegative;
2822 else if (TYPE_RANGED_INTEGERP (int, left))
2823 {
2824 leftpos = XINT (left);
2825 if (leftpos < 0)
2826 f->size_hint_flags |= XNegative;
2827 }
2828 else if (CONSP (left) && EQ (XCAR (left), Qminus)
2829 && CONSP (XCDR (left))
2830 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
2831 {
2832 leftpos = - XINT (XCAR (XCDR (left)));
2833 f->size_hint_flags |= XNegative;
2834 }
2835 else if (CONSP (left) && EQ (XCAR (left), Qplus)
2836 && CONSP (XCDR (left))
2837 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
2838 {
2839 leftpos = XINT (XCAR (XCDR (left)));
2840 }
2841
2842 if (EQ (top, Qminus))
2843 f->size_hint_flags |= YNegative;
2844 else if (TYPE_RANGED_INTEGERP (int, top))
2845 {
2846 toppos = XINT (top);
2847 if (toppos < 0)
2848 f->size_hint_flags |= YNegative;
2849 }
2850 else if (CONSP (top) && EQ (XCAR (top), Qminus)
2851 && CONSP (XCDR (top))
2852 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
2853 {
2854 toppos = - XINT (XCAR (XCDR (top)));
2855 f->size_hint_flags |= YNegative;
2856 }
2857 else if (CONSP (top) && EQ (XCAR (top), Qplus)
2858 && CONSP (XCDR (top))
2859 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
2860 {
2861 toppos = XINT (XCAR (XCDR (top)));
2862 }
2863
2864
2865 /* Store the numeric value of the position. */
2866 f->top_pos = toppos;
2867 f->left_pos = leftpos;
2868
2869 f->win_gravity = NorthWestGravity;
2870
2871 /* Actually set that position, and convert to absolute. */
2872 x_set_offset (f, leftpos, toppos, -1);
2873 }
2874
2875 if ((!NILP (icon_left) || !NILP (icon_top))
2876 && ! (icon_left_no_change && icon_top_no_change))
2877 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
2878 }
2879
2880 UNGCPRO;
2881 }
2882
2883
2884 /* Insert a description of internally-recorded parameters of frame X
2885 into the parameter alist *ALISTPTR that is to be given to the user.
2886 Only parameters that are specific to the X window system
2887 and whose values are not correctly recorded in the frame's
2888 param_alist need to be considered here. */
2889
2890 void
2891 x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
2892 {
2893 Lisp_Object tem;
2894 uprintmax_t w;
2895 char buf[INT_BUFSIZE_BOUND (w)];
2896
2897 /* Represent negative positions (off the top or left screen edge)
2898 in a way that Fmodify_frame_parameters will understand correctly. */
2899 XSETINT (tem, f->left_pos);
2900 if (f->left_pos >= 0)
2901 store_in_alist (alistptr, Qleft, tem);
2902 else
2903 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
2904
2905 XSETINT (tem, f->top_pos);
2906 if (f->top_pos >= 0)
2907 store_in_alist (alistptr, Qtop, tem);
2908 else
2909 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
2910
2911 store_in_alist (alistptr, Qborder_width,
2912 make_number (f->border_width));
2913 store_in_alist (alistptr, Qinternal_border_width,
2914 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
2915 store_in_alist (alistptr, Qleft_fringe,
2916 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
2917 store_in_alist (alistptr, Qright_fringe,
2918 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
2919 store_in_alist (alistptr, Qscroll_bar_width,
2920 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
2921 ? make_number (0)
2922 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
2923 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
2924 /* nil means "use default width"
2925 for non-toolkit scroll bar.
2926 ruler-mode.el depends on this. */
2927 : Qnil));
2928 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
2929 MS-Windows it returns a value whose type is HANDLE, which is
2930 actually a pointer. Explicit casting avoids compiler
2931 warnings. */
2932 w = (uintptr_t) FRAME_X_WINDOW (f);
2933 store_in_alist (alistptr, Qwindow_id,
2934 make_formatted_string (buf, "%"pMu, w));
2935 #ifdef HAVE_X_WINDOWS
2936 #ifdef USE_X_TOOLKIT
2937 /* Tooltip frame may not have this widget. */
2938 if (FRAME_X_OUTPUT (f)->widget)
2939 #endif
2940 w = (uintptr_t) FRAME_OUTER_WINDOW (f);
2941 store_in_alist (alistptr, Qouter_window_id,
2942 make_formatted_string (buf, "%"pMu, w));
2943 #endif
2944 store_in_alist (alistptr, Qicon_name, f->icon_name);
2945 FRAME_SAMPLE_VISIBILITY (f);
2946 store_in_alist (alistptr, Qvisibility,
2947 (FRAME_VISIBLE_P (f) ? Qt
2948 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
2949 store_in_alist (alistptr, Qdisplay,
2950 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
2951
2952 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
2953 tem = Qnil;
2954 else
2955 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
2956 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
2957 store_in_alist (alistptr, Qparent_id, tem);
2958 store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position);
2959 }
2960
2961
2962 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
2963 the previous value of that parameter, NEW_VALUE is the new value. */
2964
2965 void
2966 x_set_fullscreen (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2967 {
2968 if (NILP (new_value))
2969 f->want_fullscreen = FULLSCREEN_NONE;
2970 else if (EQ (new_value, Qfullboth) || EQ (new_value, Qfullscreen))
2971 f->want_fullscreen = FULLSCREEN_BOTH;
2972 else if (EQ (new_value, Qfullwidth))
2973 f->want_fullscreen = FULLSCREEN_WIDTH;
2974 else if (EQ (new_value, Qfullheight))
2975 f->want_fullscreen = FULLSCREEN_HEIGHT;
2976 else if (EQ (new_value, Qmaximized))
2977 f->want_fullscreen = FULLSCREEN_MAXIMIZED;
2978
2979 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
2980 FRAME_TERMINAL (f)->fullscreen_hook (f);
2981 }
2982
2983
2984 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
2985 the previous value of that parameter, NEW_VALUE is the new value. */
2986
2987 void
2988 x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2989 {
2990 if (NILP (new_value))
2991 f->extra_line_spacing = 0;
2992 else if (RANGED_INTEGERP (0, new_value, INT_MAX))
2993 f->extra_line_spacing = XFASTINT (new_value);
2994 else
2995 signal_error ("Invalid line-spacing", new_value);
2996 if (FRAME_VISIBLE_P (f))
2997 redraw_frame (f);
2998 }
2999
3000
3001 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3002 the previous value of that parameter, NEW_VALUE is the new value. */
3003
3004 void
3005 x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3006 {
3007 Lisp_Object bgcolor;
3008
3009 if (NILP (new_value))
3010 f->gamma = 0;
3011 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3012 /* The value 0.4545 is the normal viewing gamma. */
3013 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3014 else
3015 signal_error ("Invalid screen-gamma", new_value);
3016
3017 /* Apply the new gamma value to the frame background. */
3018 bgcolor = Fassq (Qbackground_color, f->param_alist);
3019 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3020 {
3021 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
3022 if (NATNUMP (parm_index)
3023 && (XFASTINT (parm_index)
3024 < sizeof (frame_parms)/sizeof (frame_parms[0]))
3025 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3026 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)])
3027 (f, bgcolor, Qnil);
3028 }
3029
3030 Fclear_face_cache (Qnil);
3031 }
3032
3033
3034 void
3035 x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3036 {
3037 Lisp_Object font_object;
3038 int fontset = -1;
3039 #ifdef HAVE_X_WINDOWS
3040 Lisp_Object font_param = arg;
3041 #endif
3042
3043 /* Set the frame parameter back to the old value because we may
3044 fail to use ARG as the new parameter value. */
3045 store_frame_param (f, Qfont, oldval);
3046
3047 /* ARG is a fontset name, a font name, a cons of fontset name and a
3048 font object, or a font object. In the last case, this function
3049 never fail. */
3050 if (STRINGP (arg))
3051 {
3052 fontset = fs_query_fontset (arg, 0);
3053 if (fontset < 0)
3054 {
3055 font_object = font_open_by_name (f, arg);
3056 if (NILP (font_object))
3057 error ("Font `%s' is not defined", SSDATA (arg));
3058 arg = AREF (font_object, FONT_NAME_INDEX);
3059 }
3060 else if (fontset > 0)
3061 {
3062 font_object = font_open_by_name (f, fontset_ascii (fontset));
3063 if (NILP (font_object))
3064 error ("Font `%s' is not defined", SDATA (arg));
3065 arg = AREF (font_object, FONT_NAME_INDEX);
3066 }
3067 else
3068 error ("The default fontset can't be used for a frame font");
3069 }
3070 else if (CONSP (arg) && STRINGP (XCAR (arg)) && FONT_OBJECT_P (XCDR (arg)))
3071 {
3072 /* This is the case that the ASCII font of F's fontset XCAR
3073 (arg) is changed to the font XCDR (arg) by
3074 `set-fontset-font'. */
3075 fontset = fs_query_fontset (XCAR (arg), 0);
3076 if (fontset < 0)
3077 error ("Unknown fontset: %s", SDATA (XCAR (arg)));
3078 font_object = XCDR (arg);
3079 arg = AREF (font_object, FONT_NAME_INDEX);
3080 #ifdef HAVE_X_WINDOWS
3081 font_param = Ffont_get (font_object, QCname);
3082 #endif
3083 }
3084 else if (FONT_OBJECT_P (arg))
3085 {
3086 font_object = arg;
3087 #ifdef HAVE_X_WINDOWS
3088 font_param = Ffont_get (font_object, QCname);
3089 #endif
3090 /* This is to store the XLFD font name in the frame parameter for
3091 backward compatibility. We should store the font-object
3092 itself in the future. */
3093 arg = AREF (font_object, FONT_NAME_INDEX);
3094 fontset = FRAME_FONTSET (f);
3095 /* Check if we can use the current fontset. If not, set FONTSET
3096 to -1 to generate a new fontset from FONT-OBJECT. */
3097 if (fontset >= 0)
3098 {
3099 Lisp_Object ascii_font = fontset_ascii (fontset);
3100 Lisp_Object spec = font_spec_from_name (ascii_font);
3101
3102 if (NILP (spec))
3103 signal_error ("Invalid font name", ascii_font);
3104
3105 if (! font_match_p (spec, font_object))
3106 fontset = -1;
3107 }
3108 }
3109 else
3110 signal_error ("Invalid font", arg);
3111
3112 if (! NILP (Fequal (font_object, oldval)))
3113 return;
3114
3115 x_new_font (f, font_object, fontset);
3116 store_frame_param (f, Qfont, arg);
3117 #ifdef HAVE_X_WINDOWS
3118 store_frame_param (f, Qfont_param, font_param);
3119 #endif
3120 /* Recalculate toolbar height. */
3121 f->n_tool_bar_rows = 0;
3122 /* Ensure we redraw it. */
3123 clear_current_matrices (f);
3124
3125 recompute_basic_faces (f);
3126
3127 do_pending_window_change (0);
3128
3129 /* We used to call face-set-after-frame-default here, but it leads to
3130 recursive calls (since that function can set the `default' face's
3131 font which in turns changes the frame's `font' parameter).
3132 Also I don't know what this call is meant to do, but it seems the
3133 wrong way to do it anyway (it does a lot more work than what seems
3134 reasonable in response to a change to `font'). */
3135 }
3136
3137
3138 void
3139 x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3140 {
3141 if (! NILP (new_value)
3142 && !CONSP (new_value))
3143 {
3144 char *p0, *p1;
3145
3146 CHECK_STRING (new_value);
3147 p0 = p1 = SSDATA (new_value);
3148 new_value = Qnil;
3149 while (*p0)
3150 {
3151 while (*p1 && ! c_isspace (*p1) && *p1 != ',') p1++;
3152 if (p0 < p1)
3153 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3154 new_value);
3155 if (*p1)
3156 {
3157 int c;
3158
3159 while ((c = *++p1) && c_isspace (c));
3160 }
3161 p0 = p1;
3162 }
3163 new_value = Fnreverse (new_value);
3164 }
3165
3166 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3167 return;
3168
3169 if (FRAME_FONT (f))
3170 free_all_realized_faces (Qnil);
3171
3172 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
3173 if (NILP (new_value))
3174 {
3175 if (NILP (old_value))
3176 error ("No font backend available");
3177 font_update_drivers (f, old_value);
3178 error ("None of specified font backends are available");
3179 }
3180 store_frame_param (f, Qfont_backend, new_value);
3181
3182 if (FRAME_FONT (f))
3183 {
3184 Lisp_Object frame;
3185
3186 XSETFRAME (frame, f);
3187 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3188 ++face_change_count;
3189 ++windows_or_buffers_changed;
3190 }
3191 }
3192
3193
3194 void
3195 x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3196 {
3197 compute_fringe_widths (f, 1);
3198 #ifdef HAVE_X_WINDOWS
3199 /* Must adjust this so window managers report correct number of columns. */
3200 if (FRAME_X_WINDOW (f) != 0)
3201 x_wm_set_size_hint (f, 0, 0);
3202 #endif
3203 }
3204
3205 void
3206 x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3207 {
3208 CHECK_TYPE_RANGED_INTEGER (int, arg);
3209
3210 if (XINT (arg) == f->border_width)
3211 return;
3212
3213 if (FRAME_X_WINDOW (f) != 0)
3214 error ("Cannot change the border width of a frame");
3215
3216 f->border_width = XINT (arg);
3217 }
3218
3219 void
3220 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3221 {
3222 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
3223
3224 CHECK_TYPE_RANGED_INTEGER (int, arg);
3225 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3226 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3227 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
3228
3229 #ifdef USE_X_TOOLKIT
3230 if (FRAME_X_OUTPUT (f)->edit_widget)
3231 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3232 #endif
3233
3234 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
3235 return;
3236
3237 if (FRAME_X_WINDOW (f) != 0)
3238 {
3239 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3240 SET_FRAME_GARBAGED (f);
3241 do_pending_window_change (0);
3242 }
3243 else
3244 SET_FRAME_GARBAGED (f);
3245 }
3246
3247 void
3248 x_set_visibility (struct frame *f, Lisp_Object value, Lisp_Object oldval)
3249 {
3250 Lisp_Object frame;
3251 XSETFRAME (frame, f);
3252
3253 if (NILP (value))
3254 Fmake_frame_invisible (frame, Qt);
3255 else if (EQ (value, Qicon))
3256 Ficonify_frame (frame);
3257 else
3258 Fmake_frame_visible (frame);
3259 }
3260
3261 void
3262 x_set_autoraise (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3263 {
3264 f->auto_raise = !EQ (Qnil, arg);
3265 }
3266
3267 void
3268 x_set_autolower (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3269 {
3270 f->auto_lower = !EQ (Qnil, arg);
3271 }
3272
3273 void
3274 x_set_unsplittable (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3275 {
3276 f->no_split = !NILP (arg);
3277 }
3278
3279 void
3280 x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3281 {
3282 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3283 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3284 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3285 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3286 {
3287 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3288 = (NILP (arg)
3289 ? vertical_scroll_bar_none
3290 : EQ (Qleft, arg)
3291 ? vertical_scroll_bar_left
3292 : EQ (Qright, arg)
3293 ? vertical_scroll_bar_right
3294 : EQ (Qleft, Vdefault_frame_scroll_bars)
3295 ? vertical_scroll_bar_left
3296 : EQ (Qright, Vdefault_frame_scroll_bars)
3297 ? vertical_scroll_bar_right
3298 : vertical_scroll_bar_none);
3299
3300 /* We set this parameter before creating the X window for the
3301 frame, so we can get the geometry right from the start.
3302 However, if the window hasn't been created yet, we shouldn't
3303 call x_set_window_size. */
3304 if (FRAME_X_WINDOW (f))
3305 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3306 do_pending_window_change (0);
3307 }
3308 }
3309
3310 void
3311 x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3312 {
3313 int wid = FRAME_COLUMN_WIDTH (f);
3314
3315 if (NILP (arg))
3316 {
3317 x_set_scroll_bar_default_width (f);
3318
3319 if (FRAME_X_WINDOW (f))
3320 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3321 do_pending_window_change (0);
3322 }
3323 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3324 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3325 {
3326 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3327 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3328
3329 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3330 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3331 if (FRAME_X_WINDOW (f))
3332 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3333 do_pending_window_change (0);
3334 }
3335
3336 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
3337 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3338 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3339 }
3340
3341
3342
3343 /* Return non-nil if frame F wants a bitmap icon. */
3344
3345 Lisp_Object
3346 x_icon_type (FRAME_PTR f)
3347 {
3348 Lisp_Object tem;
3349
3350 tem = assq_no_quit (Qicon_type, f->param_alist);
3351 if (CONSP (tem))
3352 return XCDR (tem);
3353 else
3354 return Qnil;
3355 }
3356
3357 void
3358 x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3359 {
3360 double alpha = 1.0;
3361 double newval[2];
3362 int i;
3363 Lisp_Object item;
3364
3365 for (i = 0; i < 2; i++)
3366 {
3367 newval[i] = 1.0;
3368 if (CONSP (arg))
3369 {
3370 item = CAR (arg);
3371 arg = CDR (arg);
3372 }
3373 else
3374 item = arg;
3375
3376 if (NILP (item))
3377 alpha = - 1.0;
3378 else if (FLOATP (item))
3379 {
3380 alpha = XFLOAT_DATA (item);
3381 if (alpha < 0.0 || 1.0 < alpha)
3382 args_out_of_range (make_float (0.0), make_float (1.0));
3383 }
3384 else if (INTEGERP (item))
3385 {
3386 EMACS_INT ialpha = XINT (item);
3387 if (ialpha < 0 || 100 < ialpha)
3388 args_out_of_range (make_number (0), make_number (100));
3389 else
3390 alpha = ialpha / 100.0;
3391 }
3392 else
3393 wrong_type_argument (Qnumberp, item);
3394 newval[i] = alpha;
3395 }
3396
3397 for (i = 0; i < 2; i++)
3398 f->alpha[i] = newval[i];
3399
3400 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3401 block_input ();
3402 x_set_frame_alpha (f);
3403 unblock_input ();
3404 #endif
3405
3406 return;
3407 }
3408
3409 \f
3410 /* Subroutines of creating an X frame. */
3411
3412 /* Make sure that Vx_resource_name is set to a reasonable value.
3413 Fix it up, or set it to `emacs' if it is too hopeless. */
3414
3415 void
3416 validate_x_resource_name (void)
3417 {
3418 ptrdiff_t len = 0;
3419 /* Number of valid characters in the resource name. */
3420 ptrdiff_t good_count = 0;
3421 /* Number of invalid characters in the resource name. */
3422 ptrdiff_t bad_count = 0;
3423 Lisp_Object new;
3424 ptrdiff_t i;
3425
3426 if (!STRINGP (Vx_resource_class))
3427 Vx_resource_class = build_string (EMACS_CLASS);
3428
3429 if (STRINGP (Vx_resource_name))
3430 {
3431 unsigned char *p = SDATA (Vx_resource_name);
3432
3433 len = SBYTES (Vx_resource_name);
3434
3435 /* Only letters, digits, - and _ are valid in resource names.
3436 Count the valid characters and count the invalid ones. */
3437 for (i = 0; i < len; i++)
3438 {
3439 int c = p[i];
3440 if (! ((c >= 'a' && c <= 'z')
3441 || (c >= 'A' && c <= 'Z')
3442 || (c >= '0' && c <= '9')
3443 || c == '-' || c == '_'))
3444 bad_count++;
3445 else
3446 good_count++;
3447 }
3448 }
3449 else
3450 /* Not a string => completely invalid. */
3451 bad_count = 5, good_count = 0;
3452
3453 /* If name is valid already, return. */
3454 if (bad_count == 0)
3455 return;
3456
3457 /* If name is entirely invalid, or nearly so, or is so implausibly
3458 large that alloca might not work, use `emacs'. */
3459 if (good_count < 2 || MAX_ALLOCA - sizeof ".customization" < len)
3460 {
3461 Vx_resource_name = build_string ("emacs");
3462 return;
3463 }
3464
3465 /* Name is partly valid. Copy it and replace the invalid characters
3466 with underscores. */
3467
3468 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3469
3470 for (i = 0; i < len; i++)
3471 {
3472 int c = SREF (new, i);
3473 if (! ((c >= 'a' && c <= 'z')
3474 || (c >= 'A' && c <= 'Z')
3475 || (c >= '0' && c <= '9')
3476 || c == '-' || c == '_'))
3477 SSET (new, i, '_');
3478 }
3479 }
3480
3481
3482 extern char *x_get_string_resource (XrmDatabase, const char *, const char *);
3483 extern Display_Info *check_x_display_info (Lisp_Object);
3484
3485
3486 /* Get specified attribute from resource database RDB.
3487 See Fx_get_resource below for other parameters. */
3488
3489 static Lisp_Object
3490 xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3491 {
3492 register char *value;
3493 char *name_key;
3494 char *class_key;
3495
3496 CHECK_STRING (attribute);
3497 CHECK_STRING (class);
3498
3499 if (!NILP (component))
3500 CHECK_STRING (component);
3501 if (!NILP (subclass))
3502 CHECK_STRING (subclass);
3503 if (NILP (component) != NILP (subclass))
3504 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3505
3506 validate_x_resource_name ();
3507
3508 /* Allocate space for the components, the dots which separate them,
3509 and the final '\0'. Make them big enough for the worst case. */
3510 name_key = alloca (SBYTES (Vx_resource_name)
3511 + (STRINGP (component)
3512 ? SBYTES (component) : 0)
3513 + SBYTES (attribute)
3514 + 3);
3515
3516 class_key = alloca (SBYTES (Vx_resource_class)
3517 + SBYTES (class)
3518 + (STRINGP (subclass)
3519 ? SBYTES (subclass) : 0)
3520 + 3);
3521
3522 /* Start with emacs.FRAMENAME for the name (the specific one)
3523 and with `Emacs' for the class key (the general one). */
3524 strcpy (name_key, SSDATA (Vx_resource_name));
3525 strcpy (class_key, SSDATA (Vx_resource_class));
3526
3527 strcat (class_key, ".");
3528 strcat (class_key, SSDATA (class));
3529
3530 if (!NILP (component))
3531 {
3532 strcat (class_key, ".");
3533 strcat (class_key, SSDATA (subclass));
3534
3535 strcat (name_key, ".");
3536 strcat (name_key, SSDATA (component));
3537 }
3538
3539 strcat (name_key, ".");
3540 strcat (name_key, SSDATA (attribute));
3541
3542 value = x_get_string_resource (rdb, name_key, class_key);
3543
3544 if (value != (char *) 0 && *value)
3545 return build_string (value);
3546 else
3547 return Qnil;
3548 }
3549
3550
3551 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3552 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3553 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3554 class, where INSTANCE is the name under which Emacs was invoked, or
3555 the name specified by the `-name' or `-rn' command-line arguments.
3556
3557 The optional arguments COMPONENT and SUBCLASS add to the key and the
3558 class, respectively. You must specify both of them or neither.
3559 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3560 and the class is `Emacs.CLASS.SUBCLASS'. */)
3561 (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3562 {
3563 #ifdef HAVE_X_WINDOWS
3564 check_x ();
3565 #endif
3566
3567 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3568 attribute, class, component, subclass);
3569 }
3570
3571 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3572
3573 Lisp_Object
3574 display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
3575 {
3576 return xrdb_get_resource (dpyinfo->xrdb,
3577 attribute, class, component, subclass);
3578 }
3579
3580 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
3581 /* Used when C code wants a resource value. */
3582 /* Called from oldXMenu/Create.c. */
3583 char *
3584 x_get_resource_string (const char *attribute, const char *class)
3585 {
3586 char *result;
3587 struct frame *sf = SELECTED_FRAME ();
3588 ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
3589 USE_SAFE_ALLOCA;
3590
3591 /* Allocate space for the components, the dots which separate them,
3592 and the final '\0'. */
3593 char *name_key = SAFE_ALLOCA (invocation_namelen + strlen (attribute) + 2);
3594 char *class_key = alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2);
3595
3596 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
3597 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3598
3599 result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3600 name_key, class_key);
3601 SAFE_FREE ();
3602 return result;
3603 }
3604 #endif
3605
3606 /* Return the value of parameter PARAM.
3607
3608 First search ALIST, then Vdefault_frame_alist, then the X defaults
3609 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3610
3611 Convert the resource to the type specified by desired_type.
3612
3613 If no default is specified, return Qunbound. If you call
3614 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3615 and don't let it get stored in any Lisp-visible variables! */
3616
3617 Lisp_Object
3618 x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
3619 const char *attribute, const char *class, enum resource_types type)
3620 {
3621 register Lisp_Object tem;
3622
3623 tem = Fassq (param, alist);
3624
3625 if (!NILP (tem))
3626 {
3627 /* If we find this parm in ALIST, clear it out
3628 so that it won't be "left over" at the end. */
3629 Lisp_Object tail;
3630 XSETCAR (tem, Qnil);
3631 /* In case the parameter appears more than once in the alist,
3632 clear it out. */
3633 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3634 if (CONSP (XCAR (tail))
3635 && EQ (XCAR (XCAR (tail)), param))
3636 XSETCAR (XCAR (tail), Qnil);
3637 }
3638 else
3639 tem = Fassq (param, Vdefault_frame_alist);
3640
3641 /* If it wasn't specified in ALIST or the Lisp-level defaults,
3642 look in the X resources. */
3643 if (EQ (tem, Qnil))
3644 {
3645 if (attribute && dpyinfo)
3646 {
3647 tem = display_x_get_resource (dpyinfo,
3648 build_string (attribute),
3649 build_string (class),
3650 Qnil, Qnil);
3651
3652 if (NILP (tem))
3653 return Qunbound;
3654
3655 switch (type)
3656 {
3657 case RES_TYPE_NUMBER:
3658 return make_number (atoi (SSDATA (tem)));
3659
3660 case RES_TYPE_BOOLEAN_NUMBER:
3661 if (!strcmp (SSDATA (tem), "on")
3662 || !strcmp (SSDATA (tem), "true"))
3663 return make_number (1);
3664 return make_number (atoi (SSDATA (tem)));
3665 break;
3666
3667 case RES_TYPE_FLOAT:
3668 return make_float (atof (SSDATA (tem)));
3669
3670 case RES_TYPE_BOOLEAN:
3671 tem = Fdowncase (tem);
3672 if (!strcmp (SSDATA (tem), "on")
3673 #ifdef HAVE_NS
3674 || !strcmp (SSDATA (tem), "yes")
3675 #endif
3676 || !strcmp (SSDATA (tem), "true"))
3677 return Qt;
3678 else
3679 return Qnil;
3680
3681 case RES_TYPE_STRING:
3682 return tem;
3683
3684 case RES_TYPE_SYMBOL:
3685 /* As a special case, we map the values `true' and `on'
3686 to Qt, and `false' and `off' to Qnil. */
3687 {
3688 Lisp_Object lower;
3689 lower = Fdowncase (tem);
3690 if (!strcmp (SSDATA (lower), "on")
3691 #ifdef HAVE_NS
3692 || !strcmp (SSDATA (lower), "yes")
3693 #endif
3694 || !strcmp (SSDATA (lower), "true"))
3695 return Qt;
3696 else if (!strcmp (SSDATA (lower), "off")
3697 #ifdef HAVE_NS
3698 || !strcmp (SSDATA (lower), "no")
3699 #endif
3700 || !strcmp (SSDATA (lower), "false"))
3701 return Qnil;
3702 else
3703 return Fintern (tem, Qnil);
3704 }
3705
3706 default:
3707 emacs_abort ();
3708 }
3709 }
3710 else
3711 return Qunbound;
3712 }
3713 return Fcdr (tem);
3714 }
3715
3716 static Lisp_Object
3717 x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param,
3718 const char *attribute, const char *class,
3719 enum resource_types type)
3720 {
3721 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3722 alist, param, attribute, class, type);
3723 }
3724
3725 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
3726
3727 Lisp_Object
3728 x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist,
3729 Lisp_Object param,
3730 const char *attribute, const char *class,
3731 enum resource_types type)
3732 {
3733 Lisp_Object value;
3734
3735 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3736 attribute, class, type);
3737 if (! NILP (value) && ! EQ (value, Qunbound))
3738 store_frame_param (f, param, value);
3739
3740 return value;
3741 }
3742
3743
3744 /* Record in frame F the specified or default value according to ALIST
3745 of the parameter named PROP (a Lisp symbol).
3746 If no value is specified for PROP, look for an X default for XPROP
3747 on the frame named NAME.
3748 If that is not found either, use the value DEFLT. */
3749
3750 Lisp_Object
3751 x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
3752 Lisp_Object deflt, const char *xprop, const char *xclass,
3753 enum resource_types type)
3754 {
3755 Lisp_Object tem;
3756
3757 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3758 if (EQ (tem, Qunbound))
3759 tem = deflt;
3760 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
3761 return tem;
3762 }
3763
3764
3765 #if !defined (HAVE_X_WINDOWS) && defined (NoValue)
3766
3767 /*
3768 * XParseGeometry parses strings of the form
3769 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
3770 * width, height, xoffset, and yoffset are unsigned integers.
3771 * Example: "=80x24+300-49"
3772 * The equal sign is optional.
3773 * It returns a bitmask that indicates which of the four values
3774 * were actually found in the string. For each value found,
3775 * the corresponding argument is updated; for each value
3776 * not found, the corresponding argument is left unchanged.
3777 */
3778
3779 static int
3780 XParseGeometry (char *string,
3781 int *x, int *y,
3782 unsigned int *width, unsigned int *height)
3783 {
3784 int mask = NoValue;
3785 char *strind;
3786 unsigned long int tempWidth, tempHeight;
3787 long int tempX, tempY;
3788 char *nextCharacter;
3789
3790 if (string == NULL || *string == '\0')
3791 return mask;
3792 if (*string == '=')
3793 string++; /* ignore possible '=' at beg of geometry spec */
3794
3795 strind = string;
3796 if (*strind != '+' && *strind != '-' && *strind != 'x')
3797 {
3798 tempWidth = strtoul (strind, &nextCharacter, 10);
3799 if (strind == nextCharacter)
3800 return 0;
3801 strind = nextCharacter;
3802 mask |= WidthValue;
3803 }
3804
3805 if (*strind == 'x' || *strind == 'X')
3806 {
3807 strind++;
3808 tempHeight = strtoul (strind, &nextCharacter, 10);
3809 if (strind == nextCharacter)
3810 return 0;
3811 strind = nextCharacter;
3812 mask |= HeightValue;
3813 }
3814
3815 if (*strind == '+' || *strind == '-')
3816 {
3817 if (*strind == '-')
3818 mask |= XNegative;
3819 tempX = strtol (strind, &nextCharacter, 10);
3820 if (strind == nextCharacter)
3821 return 0;
3822 strind = nextCharacter;
3823 mask |= XValue;
3824 if (*strind == '+' || *strind == '-')
3825 {
3826 if (*strind == '-')
3827 mask |= YNegative;
3828 tempY = strtol (strind, &nextCharacter, 10);
3829 if (strind == nextCharacter)
3830 return 0;
3831 strind = nextCharacter;
3832 mask |= YValue;
3833 }
3834 }
3835
3836 /* If strind isn't at the end of the string then it's an invalid
3837 geometry specification. */
3838
3839 if (*strind != '\0')
3840 return 0;
3841
3842 if (mask & XValue)
3843 *x = clip_to_bounds (INT_MIN, tempX, INT_MAX);
3844 if (mask & YValue)
3845 *y = clip_to_bounds (INT_MIN, tempY, INT_MAX);
3846 if (mask & WidthValue)
3847 *width = min (tempWidth, UINT_MAX);
3848 if (mask & HeightValue)
3849 *height = min (tempHeight, UINT_MAX);
3850 return mask;
3851 }
3852
3853 #endif /* !defined (HAVE_X_WINDOWS) && defined (NoValue) */
3854
3855 \f
3856 /* NS used to define x-parse-geometry in ns-win.el, but that confused
3857 make-docfile: the documentation string in ns-win.el was used for
3858 x-parse-geometry even in non-NS builds.
3859
3860 With two definitions of x-parse-geometry in this file, various
3861 things still get confused (eg M-x apropos documentation), so that
3862 it is best if the two definitions just share the same doc-string.
3863 */
3864 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
3865 doc: /* Parse a display geometry string STRING.
3866 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3867 The properties returned may include `top', `left', `height', and `width'.
3868 For X, the value of `left' or `top' may be an integer,
3869 or a list (+ N) meaning N pixels relative to top/left corner,
3870 or a list (- N) meaning -N pixels relative to bottom/right corner.
3871 On Nextstep, this just calls `ns-parse-geometry'. */)
3872 (Lisp_Object string)
3873 {
3874 int geometry, x, y;
3875 unsigned int width, height;
3876 Lisp_Object result;
3877
3878 CHECK_STRING (string);
3879
3880 #ifdef HAVE_NS
3881 if (strchr (SSDATA (string), ' ') != NULL)
3882 return call1 (Qns_parse_geometry, string);
3883 #endif
3884 geometry = XParseGeometry (SSDATA (string),
3885 &x, &y, &width, &height);
3886 result = Qnil;
3887 if (geometry & XValue)
3888 {
3889 Lisp_Object element;
3890
3891 if (x >= 0 && (geometry & XNegative))
3892 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
3893 else if (x < 0 && ! (geometry & XNegative))
3894 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
3895 else
3896 element = Fcons (Qleft, make_number (x));
3897 result = Fcons (element, result);
3898 }
3899
3900 if (geometry & YValue)
3901 {
3902 Lisp_Object element;
3903
3904 if (y >= 0 && (geometry & YNegative))
3905 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
3906 else if (y < 0 && ! (geometry & YNegative))
3907 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
3908 else
3909 element = Fcons (Qtop, make_number (y));
3910 result = Fcons (element, result);
3911 }
3912
3913 if (geometry & WidthValue)
3914 result = Fcons (Fcons (Qwidth, make_number (width)), result);
3915 if (geometry & HeightValue)
3916 result = Fcons (Fcons (Qheight, make_number (height)), result);
3917
3918 return result;
3919 }
3920
3921
3922 /* Calculate the desired size and position of frame F.
3923 Return the flags saying which aspects were specified.
3924
3925 Also set the win_gravity and size_hint_flags of F.
3926
3927 Adjust height for toolbar if TOOLBAR_P is 1.
3928
3929 This function does not make the coordinates positive. */
3930
3931 #define DEFAULT_ROWS 35
3932 #define DEFAULT_COLS 80
3933
3934 int
3935 x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
3936 {
3937 register Lisp_Object tem0, tem1, tem2;
3938 long window_prompting = 0;
3939 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3940
3941 /* Default values if we fall through.
3942 Actually, if that happens we should get
3943 window manager prompting. */
3944 SET_FRAME_COLS (f, DEFAULT_COLS);
3945 FRAME_LINES (f) = DEFAULT_ROWS;
3946 /* Window managers expect that if program-specified
3947 positions are not (0,0), they're intentional, not defaults. */
3948 f->top_pos = 0;
3949 f->left_pos = 0;
3950
3951 /* Ensure that old new_text_cols and new_text_lines will not override the
3952 values set here. */
3953 /* ++KFS: This was specific to W32, but seems ok for all platforms */
3954 f->new_text_cols = f->new_text_lines = 0;
3955
3956 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
3957 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
3958 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
3959 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3960 {
3961 if (!EQ (tem0, Qunbound))
3962 {
3963 CHECK_NUMBER (tem0);
3964 if (! (0 <= XINT (tem0) && XINT (tem0) <= INT_MAX))
3965 xsignal1 (Qargs_out_of_range, tem0);
3966 FRAME_LINES (f) = XINT (tem0);
3967 }
3968 if (!EQ (tem1, Qunbound))
3969 {
3970 CHECK_NUMBER (tem1);
3971 if (! (0 <= XINT (tem1) && XINT (tem1) <= INT_MAX))
3972 xsignal1 (Qargs_out_of_range, tem1);
3973 SET_FRAME_COLS (f, XINT (tem1));
3974 }
3975 if (!NILP (tem2) && !EQ (tem2, Qunbound))
3976 window_prompting |= USSize;
3977 else
3978 window_prompting |= PSize;
3979 }
3980
3981 f->scroll_bar_actual_width
3982 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
3983
3984 /* This used to be done _before_ calling x_figure_window_size, but
3985 since the height is reset here, this was really a no-op. I
3986 assume that moving it here does what Gerd intended (although he
3987 no longer can remember what that was... ++KFS, 2003-03-25. */
3988
3989 /* Add the tool-bar height to the initial frame height so that the
3990 user gets a text display area of the size he specified with -g or
3991 via .Xdefaults. Later changes of the tool-bar height don't
3992 change the frame size. This is done so that users can create
3993 tall Emacs frames without having to guess how tall the tool-bar
3994 will get. */
3995 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
3996 {
3997 int margin, relief, bar_height;
3998
3999 relief = (tool_bar_button_relief >= 0
4000 ? tool_bar_button_relief
4001 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4002
4003 if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX))
4004 margin = XFASTINT (Vtool_bar_button_margin);
4005 else if (CONSP (Vtool_bar_button_margin)
4006 && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX))
4007 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4008 else
4009 margin = 0;
4010
4011 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4012 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
4013 }
4014
4015 compute_fringe_widths (f, 0);
4016
4017 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
4018 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
4019
4020 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4021 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4022 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4023 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4024 {
4025 if (EQ (tem0, Qminus))
4026 {
4027 f->top_pos = 0;
4028 window_prompting |= YNegative;
4029 }
4030 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
4031 && CONSP (XCDR (tem0))
4032 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem0)), INT_MAX))
4033 {
4034 f->top_pos = - XINT (XCAR (XCDR (tem0)));
4035 window_prompting |= YNegative;
4036 }
4037 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
4038 && CONSP (XCDR (tem0))
4039 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem0))))
4040 {
4041 f->top_pos = XINT (XCAR (XCDR (tem0)));
4042 }
4043 else if (EQ (tem0, Qunbound))
4044 f->top_pos = 0;
4045 else
4046 {
4047 CHECK_TYPE_RANGED_INTEGER (int, tem0);
4048 f->top_pos = XINT (tem0);
4049 if (f->top_pos < 0)
4050 window_prompting |= YNegative;
4051 }
4052
4053 if (EQ (tem1, Qminus))
4054 {
4055 f->left_pos = 0;
4056 window_prompting |= XNegative;
4057 }
4058 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
4059 && CONSP (XCDR (tem1))
4060 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem1)), INT_MAX))
4061 {
4062 f->left_pos = - XINT (XCAR (XCDR (tem1)));
4063 window_prompting |= XNegative;
4064 }
4065 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
4066 && CONSP (XCDR (tem1))
4067 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem1))))
4068 {
4069 f->left_pos = XINT (XCAR (XCDR (tem1)));
4070 }
4071 else if (EQ (tem1, Qunbound))
4072 f->left_pos = 0;
4073 else
4074 {
4075 CHECK_TYPE_RANGED_INTEGER (int, tem1);
4076 f->left_pos = XINT (tem1);
4077 if (f->left_pos < 0)
4078 window_prompting |= XNegative;
4079 }
4080
4081 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
4082 window_prompting |= USPosition;
4083 else
4084 window_prompting |= PPosition;
4085 }
4086
4087 if (window_prompting & XNegative)
4088 {
4089 if (window_prompting & YNegative)
4090 f->win_gravity = SouthEastGravity;
4091 else
4092 f->win_gravity = NorthEastGravity;
4093 }
4094 else
4095 {
4096 if (window_prompting & YNegative)
4097 f->win_gravity = SouthWestGravity;
4098 else
4099 f->win_gravity = NorthWestGravity;
4100 }
4101
4102 f->size_hint_flags = window_prompting;
4103
4104 return window_prompting;
4105 }
4106
4107
4108
4109 #endif /* HAVE_WINDOW_SYSTEM */
4110
4111 void
4112 frame_make_pointer_invisible (void)
4113 {
4114 if (! NILP (Vmake_pointer_invisible))
4115 {
4116 struct frame *f;
4117 if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
4118 return;
4119
4120 f = SELECTED_FRAME ();
4121 if (f && !f->pointer_invisible
4122 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4123 {
4124 f->mouse_moved = 0;
4125 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 1);
4126 f->pointer_invisible = 1;
4127 }
4128 }
4129 }
4130
4131 void
4132 frame_make_pointer_visible (void)
4133 {
4134 /* We don't check Vmake_pointer_invisible here in case the
4135 pointer was invisible when Vmake_pointer_invisible was set to nil. */
4136 struct frame *f;
4137
4138 if (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
4139 return;
4140
4141 f = SELECTED_FRAME ();
4142 if (f && f->pointer_invisible && f->mouse_moved
4143 && FRAME_TERMINAL (f)->toggle_invisible_pointer_hook)
4144 {
4145 FRAME_TERMINAL (f)->toggle_invisible_pointer_hook (f, 0);
4146 f->pointer_invisible = 0;
4147 }
4148 }
4149
4150 DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p,
4151 Sframe_pointer_visible_p, 0, 1, 0,
4152 doc: /* Return t if the mouse pointer displayed on FRAME is visible.
4153 Otherwise it returns nil. FRAME omitted or nil means the
4154 selected frame. This is useful when `make-pointer-invisible' is set. */)
4155 (Lisp_Object frame)
4156 {
4157 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
4158 }
4159
4160 \f
4161 /***********************************************************************
4162 Initialization
4163 ***********************************************************************/
4164
4165 void
4166 syms_of_frame (void)
4167 {
4168 DEFSYM (Qframep, "framep");
4169 DEFSYM (Qframe_live_p, "frame-live-p");
4170 DEFSYM (Qexplicit_name, "explicit-name");
4171 DEFSYM (Qheight, "height");
4172 DEFSYM (Qicon, "icon");
4173 DEFSYM (Qminibuffer, "minibuffer");
4174 DEFSYM (Qmodeline, "modeline");
4175 DEFSYM (Qonly, "only");
4176 DEFSYM (Qnone, "none");
4177 DEFSYM (Qwidth, "width");
4178 DEFSYM (Qgeometry, "geometry");
4179 DEFSYM (Qicon_left, "icon-left");
4180 DEFSYM (Qicon_top, "icon-top");
4181 DEFSYM (Qtooltip, "tooltip");
4182 DEFSYM (Qleft, "left");
4183 DEFSYM (Qright, "right");
4184 DEFSYM (Quser_position, "user-position");
4185 DEFSYM (Quser_size, "user-size");
4186 DEFSYM (Qwindow_id, "window-id");
4187 #ifdef HAVE_X_WINDOWS
4188 DEFSYM (Qouter_window_id, "outer-window-id");
4189 #endif
4190 DEFSYM (Qparent_id, "parent-id");
4191 DEFSYM (Qx, "x");
4192 DEFSYM (Qw32, "w32");
4193 DEFSYM (Qpc, "pc");
4194 DEFSYM (Qns, "ns");
4195 DEFSYM (Qvisible, "visible");
4196 DEFSYM (Qbuffer_predicate, "buffer-predicate");
4197 DEFSYM (Qbuffer_list, "buffer-list");
4198 DEFSYM (Qburied_buffer_list, "buried-buffer-list");
4199 DEFSYM (Qdisplay_type, "display-type");
4200 DEFSYM (Qbackground_mode, "background-mode");
4201 DEFSYM (Qnoelisp, "noelisp");
4202 DEFSYM (Qtty_color_mode, "tty-color-mode");
4203 DEFSYM (Qtty, "tty");
4204 DEFSYM (Qtty_type, "tty-type");
4205
4206 DEFSYM (Qface_set_after_frame_default, "face-set-after-frame-default");
4207
4208 DEFSYM (Qfullwidth, "fullwidth");
4209 DEFSYM (Qfullheight, "fullheight");
4210 DEFSYM (Qfullboth, "fullboth");
4211 DEFSYM (Qmaximized, "maximized");
4212 DEFSYM (Qx_resource_name, "x-resource-name");
4213 DEFSYM (Qx_frame_parameter, "x-frame-parameter");
4214
4215 DEFSYM (Qterminal, "terminal");
4216 DEFSYM (Qterminal_live_p, "terminal-live-p");
4217
4218 #ifdef HAVE_NS
4219 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
4220 #endif
4221
4222 {
4223 int i;
4224
4225 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4226 {
4227 Lisp_Object v = intern_c_string (frame_parms[i].name);
4228 if (frame_parms[i].variable)
4229 {
4230 *frame_parms[i].variable = v;
4231 staticpro (frame_parms[i].variable);
4232 }
4233 Fput (v, Qx_frame_parameter, make_number (i));
4234 }
4235 }
4236
4237 #ifdef HAVE_WINDOW_SYSTEM
4238 DEFVAR_LISP ("x-resource-name", Vx_resource_name,
4239 doc: /* The name Emacs uses to look up X resources.
4240 `x-get-resource' uses this as the first component of the instance name
4241 when requesting resource values.
4242 Emacs initially sets `x-resource-name' to the name under which Emacs
4243 was invoked, or to the value specified with the `-name' or `-rn'
4244 switches, if present.
4245
4246 It may be useful to bind this variable locally around a call
4247 to `x-get-resource'. See also the variable `x-resource-class'. */);
4248 Vx_resource_name = Qnil;
4249
4250 DEFVAR_LISP ("x-resource-class", Vx_resource_class,
4251 doc: /* The class Emacs uses to look up X resources.
4252 `x-get-resource' uses this as the first component of the instance class
4253 when requesting resource values.
4254
4255 Emacs initially sets `x-resource-class' to "Emacs".
4256
4257 Setting this variable permanently is not a reasonable thing to do,
4258 but binding this variable locally around a call to `x-get-resource'
4259 is a reasonable practice. See also the variable `x-resource-name'. */);
4260 Vx_resource_class = build_string (EMACS_CLASS);
4261
4262 DEFVAR_LISP ("frame-alpha-lower-limit", Vframe_alpha_lower_limit,
4263 doc: /* The lower limit of the frame opacity (alpha transparency).
4264 The value should range from 0 (invisible) to 100 (completely opaque).
4265 You can also use a floating number between 0.0 and 1.0.
4266 The default is 20. */);
4267 Vframe_alpha_lower_limit = make_number (20);
4268 #endif
4269
4270 DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist,
4271 doc: /* Alist of default values for frame creation.
4272 These may be set in your init file, like this:
4273 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4274 These override values given in window system configuration data,
4275 including X Windows' defaults database.
4276 For values specific to the first Emacs frame, see `initial-frame-alist'.
4277 For window-system specific values, see `window-system-default-frame-alist'.
4278 For values specific to the separate minibuffer frame, see
4279 `minibuffer-frame-alist'.
4280 The `menu-bar-lines' element of the list controls whether new frames
4281 have menu bars; `menu-bar-mode' works by altering this element.
4282 Setting this variable does not affect existing frames, only new ones. */);
4283 Vdefault_frame_alist = Qnil;
4284
4285 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars,
4286 doc: /* Default position of scroll bars on this window-system. */);
4287 #ifdef HAVE_WINDOW_SYSTEM
4288 #if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
4289 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
4290 default. */
4291 Vdefault_frame_scroll_bars = Qright;
4292 #else
4293 Vdefault_frame_scroll_bars = Qleft;
4294 #endif
4295 #else
4296 Vdefault_frame_scroll_bars = Qnil;
4297 #endif
4298
4299 DEFVAR_LISP ("terminal-frame", Vterminal_frame,
4300 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4301
4302 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function,
4303 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4304 `mouse-position' calls this function, passing its usual return value as
4305 argument, and returns whatever this function returns.
4306 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4307 which need to do mouse handling at the Lisp level. */);
4308 Vmouse_position_function = Qnil;
4309
4310 DEFVAR_LISP ("mouse-highlight", Vmouse_highlight,
4311 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4312 If the value is an integer, highlighting is only shown after moving the
4313 mouse, while keyboard input turns off the highlight even when the mouse
4314 is over the clickable text. However, the mouse shape still indicates
4315 when the mouse is over clickable text. */);
4316 Vmouse_highlight = Qt;
4317
4318 DEFVAR_LISP ("make-pointer-invisible", Vmake_pointer_invisible,
4319 doc: /* If non-nil, make pointer invisible while typing.
4320 The pointer becomes visible again when the mouse is moved. */);
4321 Vmake_pointer_invisible = Qt;
4322
4323 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
4324 doc: /* Functions run before deleting a frame.
4325 The functions are run with one arg, the frame to be deleted.
4326 See `delete-frame'.
4327
4328 Note that functions in this list may be called just before the frame is
4329 actually deleted, or some time later (or even both when an earlier function
4330 in `delete-frame-functions' (indirectly) calls `delete-frame'
4331 recursively). */);
4332 Vdelete_frame_functions = Qnil;
4333 DEFSYM (Qdelete_frame_functions, "delete-frame-functions");
4334
4335 DEFVAR_LISP ("menu-bar-mode", Vmenu_bar_mode,
4336 doc: /* Non-nil if Menu-Bar mode is enabled.
4337 See the command `menu-bar-mode' for a description of this minor mode.
4338 Setting this variable directly does not take effect;
4339 either customize it (see the info node `Easy Customization')
4340 or call the function `menu-bar-mode'. */);
4341 Vmenu_bar_mode = Qt;
4342
4343 DEFVAR_LISP ("tool-bar-mode", Vtool_bar_mode,
4344 doc: /* Non-nil if Tool-Bar mode is enabled.
4345 See the command `tool-bar-mode' for a description of this minor mode.
4346 Setting this variable directly does not take effect;
4347 either customize it (see the info node `Easy Customization')
4348 or call the function `tool-bar-mode'. */);
4349 #ifdef HAVE_WINDOW_SYSTEM
4350 Vtool_bar_mode = Qt;
4351 #else
4352 Vtool_bar_mode = Qnil;
4353 #endif
4354
4355 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4356 doc: /* Minibufferless frames use this frame's minibuffer.
4357
4358 Emacs cannot create minibufferless frames unless this is set to an
4359 appropriate surrogate.
4360
4361 Emacs consults this variable only when creating minibufferless
4362 frames; once the frame is created, it sticks with its assigned
4363 minibuffer, no matter what this variable is set to. This means that
4364 this variable doesn't necessarily say anything meaningful about the
4365 current set of frames, or where the minibuffer is currently being
4366 displayed.
4367
4368 This variable is local to the current terminal and cannot be buffer-local. */);
4369
4370 DEFVAR_BOOL ("focus-follows-mouse", focus_follows_mouse,
4371 doc: /* Non-nil if window system changes focus when you move the mouse.
4372 You should set this variable to tell Emacs how your window manager
4373 handles focus, since there is no way in general for Emacs to find out
4374 automatically. See also `mouse-autoselect-window'. */);
4375 focus_follows_mouse = 0;
4376
4377 staticpro (&Vframe_list);
4378
4379 defsubr (&Sframep);
4380 defsubr (&Sframe_live_p);
4381 defsubr (&Swindow_system);
4382 defsubr (&Smake_terminal_frame);
4383 defsubr (&Shandle_switch_frame);
4384 defsubr (&Sselect_frame);
4385 defsubr (&Sselected_frame);
4386 defsubr (&Sframe_list);
4387 defsubr (&Snext_frame);
4388 defsubr (&Sprevious_frame);
4389 defsubr (&Sdelete_frame);
4390 defsubr (&Smouse_position);
4391 defsubr (&Smouse_pixel_position);
4392 defsubr (&Sset_mouse_position);
4393 defsubr (&Sset_mouse_pixel_position);
4394 #if 0
4395 defsubr (&Sframe_configuration);
4396 defsubr (&Srestore_frame_configuration);
4397 #endif
4398 defsubr (&Smake_frame_visible);
4399 defsubr (&Smake_frame_invisible);
4400 defsubr (&Siconify_frame);
4401 defsubr (&Sframe_visible_p);
4402 defsubr (&Svisible_frame_list);
4403 defsubr (&Sraise_frame);
4404 defsubr (&Slower_frame);
4405 defsubr (&Sredirect_frame_focus);
4406 defsubr (&Sframe_focus);
4407 defsubr (&Sframe_parameters);
4408 defsubr (&Sframe_parameter);
4409 defsubr (&Smodify_frame_parameters);
4410 defsubr (&Sframe_char_height);
4411 defsubr (&Sframe_char_width);
4412 defsubr (&Sframe_pixel_height);
4413 defsubr (&Sframe_pixel_width);
4414 defsubr (&Stool_bar_pixel_width);
4415 defsubr (&Sset_frame_height);
4416 defsubr (&Sset_frame_width);
4417 defsubr (&Sset_frame_size);
4418 defsubr (&Sset_frame_position);
4419 defsubr (&Sframe_pointer_visible_p);
4420
4421 #ifdef HAVE_WINDOW_SYSTEM
4422 defsubr (&Sx_get_resource);
4423 defsubr (&Sx_parse_geometry);
4424 #endif
4425
4426 }