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