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