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