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