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