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