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