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